Room = class("Room") require "player" require "box" require "wall" function Room:initialize(t) self.exits = t.exits self.name = t.name self.player = {} self.collideables = { red = {}, green = {}, blue = {} } self.activeColors = { red = false, green = false, blue = false } for color, coords in pairs(t.player) do self.player[color] = Player:new(coords.x, coords.y, color) self.activeColors[color] = true end for i=0, 20 do local c = randomColor() local x, y = math.random(1, gridWidth), math.random(1, gridHeight) self.collideables[c]["b: " .. x .. ", " .. y] = Box:new(x, y, c) end for i=0, 20 do local c = randomColor() local x, y = math.random(1, gridWidth), math.random(1, gridHeight) self.collideables[c]["w: " .. x .. ", " .. y] = Wall:new(x, y, c) end end function Room:update(dt) for color, player in pairs(self.player) do player:update(dt) end end function Room:draw() for color, player in pairs(self.player) do player:draw() end for color, entityArray in pairs(self.collideables) do for _, entity in pairs(entityArray) do entity:draw() end end end function Room:movePlayer(key) local moveAxis local direction if key == "up" then moveAxis, direction = "y", -1 elseif key == "down" then moveAxis, direction = "y", 1 elseif key == "left" then moveAxis, direction = "x", -1 elseif key == "right" then moveAxis, direction = "x", 1 else error("wtf did u do") end for color, active in pairs(self.activeColors) do if active then local playerPos = self.player[color]:getGridPos() local entities = self:getAdjacentEntities(self.collideables[color], playerPos, moveAxis, direction) local canMove = self:tryPlayerMove(entities, playerPos, moveAxis, direction) if canMove then self:checkAndPull(self.collideables[color], playerPos, moveAxis, direction) self.player[color]:move(moveAxis, direction) self:tick() end end end end function Room:switchPlayer(colorToActivate) for color, active in pairs(self.activeColors) do if color == colorToActivate then self:setActiveColor(color, true) else self:setActiveColor(color, false) end end end function Room:setActiveColor(color, bool) self.activeColors[color] = bool end function Room:getAdjacentEntities(entities, pos, axis, direction) local t = {} --first we gather all entities in direction of movement for _, entity in pairs(entities) do if axis == "x" then if entity:isAlignedWithPlayerMovement("y", pos.y) then if direction > 0 and entity:getGridPos()[axis] > pos[axis] then table.insert(t, entity) elseif direction < 0 and entity:getGridPos()[axis] < pos[axis] then table.insert(t, entity) end end elseif axis == "y" then if entity:isAlignedWithPlayerMovement("x", pos.x) then if direction > 0 and entity:getGridPos()[axis] > pos[axis] then table.insert(t, entity) elseif direction < 0 and entity:getGridPos()[axis] < pos[axis] then table.insert(t, entity) end end end end --then we put them in order table.sort(t, function(a, b) if direction > 0 then return a:getGridPos()[axis] < b:getGridPos()[axis] else return a:getGridPos()[axis] > b:getGridPos()[axis] end end) return t end function Room:checkAndPull(entities, pos, axis, direction) for _, entity in pairs(entities) do local entPos = entity:getGridPos() print(pos.x, pos.y, entPos.x, entPos.y) if axis == "x" and entPos.x == pos.x - direction and entPos.y == pos.y then if entity:canMove() then entity:move(axis, direction) return end elseif axis == "y" and entPos.x == pos.x and entPos.y == pos.y - direction then if entity:canMove() then entity:move(axis, direction) return end end end end function Room:tryPlayerMove(entities, pos, axis, direction) local counter = direction local entitiesToMove = {} for _, entity in ipairs(entities) do if entity:getGridPos()[axis] == pos[axis] + counter then if entity:canMove() then table.insert(entitiesToMove, entity) else return false end else break end counter = counter + direction end for _, entity in ipairs(entitiesToMove) do entity:move(axis, direction) end return true end function Room:tick() for color, entityArray in pairs(self.collideables) do for _, entity in pairs(entityArray) do entity:tick() end end self:nextRoomCheck() end function Room:nextRoomCheck() end function nextRoom() end