diff --git a/_debug_helpers.lua b/_debug_helpers.lua new file mode 100644 index 0000000..6aa47f8 --- /dev/null +++ b/_debug_helpers.lua @@ -0,0 +1,14 @@ +function shallowTablePrint(t) + for i, v in pairs(t) do + print(i, v) + end +end + +function printMatrix(matrix) + for i, v in ipairs(matrix) do + for j, w in ipairs(v) do + if not w then io.write("o ") else io.write("x ") end + end + io.write("\n") + end +end \ No newline at end of file diff --git a/color.lua b/color.lua index 0ff3136..1e2d713 100644 --- a/color.lua +++ b/color.lua @@ -6,7 +6,8 @@ Color = class("Color") Color.static.list = { red = {r = 255, g = 0, b = 0, a = 255}, green = {r = 0, g = 255, b = 0, a = 255}, - blue = {r = 0, g = 0, b = 255, a = 255} + blue = {r = 0, g = 0, b = 255, a = 255}, + white = {r = 255, g = 255, b = 255, a = 255} } function Color:initialize(inColor) diff --git a/debug_helpers.lua b/debug_helpers.lua deleted file mode 100644 index da170e2..0000000 --- a/debug_helpers.lua +++ /dev/null @@ -1,5 +0,0 @@ -function shallowTablePrint(t) - for i, v in pairs(t) do - print(i, v) - end -end \ No newline at end of file diff --git a/entity.lua b/entity.lua index 92d8c48..bf35d22 100644 --- a/entity.lua +++ b/entity.lua @@ -10,8 +10,12 @@ function Entity:initialize(t) self.shaAmount = t.sha or 1 end +function Entity:getCollision() + return self.collision +end + function Entity:atGridPos(x, y) - -- print(x, y, self.x, self.y, self.x + self.size.x, self.y + self.size.y) + -- we probably don't need this anymore local size = self:getGridSize() if x >= self.x and y >= self.y and x < self.x + size.x and y < self.y + size.y then return true @@ -19,6 +23,21 @@ function Entity:atGridPos(x, y) return false end +function Entity:getOccupiedCells(coords) + --we have this offset so we can project what a movement would do + local offset = coords or {x = 0, y = 0} + local box = self:getGridBox() + local cells = {} + + for i = box.x + offset.x, box.x + box.w - 1 + offset.x do + for j = box.y + offset.y, box.y + box.h - 1 + offset.y do + table.insert(cells, {x = i, y = j}) + end + end + + return cells +end + function Entity:getDrawBox() local drawPos = self:getDrawPos() return {x = drawPos.x, y = drawPos.y, w = self.spriteSize.w * drawScale, h = self.spriteSize.h * drawScale} diff --git a/main.lua b/main.lua index 32e4f81..077d9c1 100644 --- a/main.lua +++ b/main.lua @@ -7,7 +7,7 @@ require "input" require "color" require "room" require "shaders" -require "debug_helpers" +require "_debug_helpers" function love.load() _initDefaults() @@ -22,9 +22,7 @@ function love.load() currentRoom = Room:new{ player = { - red = {x = 5, y = 5}, - green = {x = 5, y = 5}, - blue = {x = 5, y = 5} + x = 5, y = 5, activeColors = {"red", "green", "blue"} } } end diff --git a/player.lua b/player.lua index e9591b4..b5d8c12 100644 --- a/player.lua +++ b/player.lua @@ -2,18 +2,38 @@ require "entity" Player = class("Player", Entity) -function Player:initialize(x, y, color) +function Player:initialize(x, y, activeColors) Entity.initialize(self, { x = x, y = y, sizeX = 1, sizeY = 1, - color = color, + color = "white", collision = "none", --player can't push other player sprite = playerSprite }) + + self.red, self.green, self.blue = Color:new("red"), Color:new("green"), Color:new("blue") + + self.activeColors = activeColors or {"red", "green", "blue"} +end + +function Player:setActiveColors(colorArray) + self.activeColors = colorArray +end + +function Player:getActiveColors() + return self.activeColors end function Player:update() +end + +function Player:draw() + for _, color in ipairs(self.activeColors) do + love.graphics.setColor(self[color]:set()) + local p = self:getDrawPos() + love.graphics.draw(self.sprite, p.x, p.y, 0, drawScale, drawScale) + end end \ No newline at end of file diff --git a/room.lua b/room.lua index 9cec648..3bff1b1 100644 --- a/room.lua +++ b/room.lua @@ -11,26 +11,29 @@ require "assorted" function Room:initialize(t) self.exits = t.exits self.name = t.name - self.player = {} + self.player = Player:new(t.player.x, t.player.y, t.player.activeColors) self.collideables = { red = {}, green = {}, blue = {} } + self.collidableMatrices = {} --{red = {{...}{...}{...}}, ...} self.activeColors = { - red = false, green = false, blue = false + red = true, green = true, blue = true } - 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, 5 do + -- 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, 2 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) + self.collideables[c]["b: " .. x .. ", " .. y]:getOccupiedCells() end @@ -41,35 +44,34 @@ function Room:initialize(t) end end - -- for color, active in pairs(self.activeColors) do - -- local x, y = 6, 3 - -- if active then self.collideables[color]["n: " .. x .. ", " .. y] = Ass:new(x, y, color, "animals/processed/", "me_rach") end + for color, active in pairs(self.activeColors) do + local x, y = 6, 3 + -- if active then self.collideables[color]["n: " .. x .. ", " .. y] = Ass:new(x, y, color, "animals/processed/", "me_rach") end - -- local x, y = 1, 1 - -- if active then self.collideables[color]["n: " .. x .. ", " .. y] = Ass:new(x, y, color, "tech/processed/", "mac_smaller") end + local x, y = 1, 1 + if active then self.collideables[color]["n: " .. x .. ", " .. y] = Ass:new(x, y, color, "tech/processed/", "mac_smaller") end + self.collideables[color]["n: " .. x .. ", " .. y]:getOccupiedCells() - -- local x, y = 7, 7 - -- if active then self.collideables[color]["n: " .. x .. ", " .. y] = Ass:new(x, y, color, "tech/processed/", "cd") end + local x, y = 7, 7 + if active then self.collideables[color]["n: " .. x .. ", " .. y] = Ass:new(x, y, color, "tech/processed/", "cd") end - -- end + end -- self.collideables["green"]["fpp"] = Artifact:new(6, 6, "green") + for color, entities in pairs(self.collideables) do + self.collidableMatrices[color] = self:createEntityMatrix(entities) + end end function Room:update(dt) - for color, player in pairs(self.player) do - player:update(dt) - end + self.player:update(dt) end function Room:draw() - for color, player in pairs(self.player) do - if self.activeColors[color] then - player:draw() - end - end + self.player:draw() + for color, entityArray in pairs(self.collideables) do for _, entity in pairs(entityArray) do entity:draw() @@ -77,20 +79,210 @@ function Room:draw() end end -function Room:movePlayer(key) +function Room:createCollideablesMatrix(collideables) + for color, entities in pairs(self.collideables) do + self.collidableMatrices[color] = self:createEntityMatrix(entities) + end +end +function Room:createEntityMatrix(entities) + local matrix = {} + --lets populate it w/ empty stuff first + for i = 1, gridWidth do + local row = {} + for i = 1, gridHeight do + table.insert(row, false) + end + table.insert(matrix, row) + end + + --assumes that entities table is set up li_e {index = ent1, anotherIndex = ent2, ...} + for _, entity in pairs(entities) do + for _, occupiedCells in pairs(entity:getOccupiedCells()) do + --we store a table reference so we can call a method on it during a chec_ + matrix[occupiedCells.y][occupiedCells.x] = entity + end + end + -- printMatrix(matrix) + return matrix end -function Room:switchPlayerColor(color) - print(color) - for c, active in pairs(self.activeColors) do - if color == "white" then - self:setActiveColor(c, true) - elseif c == color then - self:setActiveColor(c, true) - else - self:setActiveColor(c, false) +function Room:getCellInMatrix(matrix, cell) + return matrix[cell.y][cell.x] +end + +function Room:movePlayer(key) + local activeColors = self.player:getActiveColors() + local pos = self.player:getGridPos() + local x, y = pos.x, pos.y + local dir = {x = 0, y = 0} + local axis + + if key == "up" then + dir.y, axis = -1, "y" + elseif key == "down" then + dir.y, axis = 1, "y" + elseif key == "left" then + dir.x, axis = -1, "x" + elseif key == "right" then + dir.x, axis = 1, "x" + end + + local move + local entitiesToPush = { + red = {}, + green = {}, + blue = {} + } + local entitiesToPull = { + red = {}, + green = {}, + blue = {} + } + + -- PUSHHHHHHHHHHHHHHHHHHHHHH--------------------- + + local initialTargetCell = { + x = pos.x + dir.x, y = pos.y + dir.y + } -- this is for reference for each color as we change the targetCells table + + local move = true + local targetCells + + --so the way this worx is.... + for _, color in pairs(activeColors) do + --for each color... + targetCells = {initialTargetCell} -- ...we start with our attempted movement... + local doneSearching + while not doneSearching do + nextTargetCells = {} -- ...then we create this array to save our next group of cells + local emptyCells = {} + for _, cell in pairs(targetCells) do + if self:isInBounds(cell) then + local entity = self:getCellInMatrix(self.collidableMatrices[color], cell) + if entity then + --something is here!! + if not entitiesToPush[color][entity] then --if the entity hasnt been found already + if entity:canMove() then + local projectedCells = entity:getOccupiedCells(dir) -- we project the movement here + entitiesToPush[color][entity] = entity + for _, projectedCell in ipairs(projectedCells) do + table.insert(nextTargetCells, projectedCell) + end + else + move = false + doneSearching = true + end + end + else + --there's nothin there!! + table.insert(emptyCells, cell) + end + else + --we are out of bounds now + move = false + doneSearching = true + end + end + + --if every projected cell is empty then we can do the move + if #emptyCells == #targetCells then + move = true + doneSearching = true + end + + targetCells = nextTargetCells end + --let's get out of this loop b/c if we can't move one color we can't move at all + if move == false then break end + end + + + ---PULL CHEC + + local initialTargetCell = {x = pos.x - dir.x, y = pos.y - dir.y} + + local targetCells + + local pull = {} + --so the way this worx is.... + for _, color in pairs(activeColors) do + --for each color... + targetCells = {initialTargetCell} -- ...we start with our attempted movement... + local doneSearching + while not doneSearching do + nextTargetCells = {} -- ...then we create this array to save our next group of cells + local emptyCells = {} + for _, cell in pairs(targetCells) do + if self:isInBounds(cell) then + local entity = self:getCellInMatrix(self.collidableMatrices[color], cell) + if entity then + --something is here!! + if not entitiesToPull[color][entity] then --if the entity hasnt been found already + if entity:canMove() then + local projectedCells = entity:getOccupiedCells(dir) -- we project the movement here + entitiesToPull[color][entity] = entity + for _, projectedCell in ipairs(projectedCells) do + table.insert(nextTargetCells, projectedCell) + end + else + pull[color] = false + doneSearching = true + end + end + else + --there's nothin there!! + table.insert(emptyCells, cell) + end + else + pull[color] = true + --we are out of bounds now + doneSearching = true + end + end + + --if every projected cell is empty then we can do the move + if #emptyCells == #targetCells then + pull[color] = true + doneSearching = true + end + + targetCells = nextTargetCells + end + --let's get out of this loop b/c if we can't move one color we can't move at all + if move == false then break end + end + + + + if move then + for color, entities in pairs(entitiesToPush) do + for _, entity in pairs(entities) do + entity:move(axis, dir[axis]) + end + end + for color, entities in pairs(entitiesToPull) do + if pull[color] then + for _, entity in pairs(entities) do + entity:move(axis, dir[axis]) + end + end + end + self.player:move(axis, dir[axis]) + self:tick() + end +end + +function Room:attemptPush(dirVector) + -- should return array of things to push or nil/falsey value +end + + +function Room:switchPlayerColor(color) + if color == "white" then + self.player:setActiveColors({"red", "green", "blue"}) + else + self.player:setActiveColors({color}) end end @@ -98,27 +290,24 @@ function Room:setActiveColor(color, bool) self.activeColors[color] = bool end -function Room:getAdjacentEntities(entities, pos, axis, direction) - -end - -function Room:checkAndPull(entities, pos, axis, direction) - -end - -function Room:tryPlayerMove(entities, pos, axis, direction) - -end - function Room:tick() for color, entityArray in pairs(self.collideables) do for _, entity in pairs(entityArray) do entity:tick() end end + self:createCollideablesMatrix() self:nextRoomCheck() end +function Room:isInBounds(cell) + if cell.x > 0 and cell.x <= gridWidth and + cell.y > 0 and cell.y <= gridHeight then + return true + end + return false +end + function Room:nextRoomCheck() end