- grid rework (the simplest solution)

- checkerboard tile testing
- character centering
This commit is contained in:
PeaAshMeter 2025-08-10 05:18:41 +03:00
parent 9fdeb7326c
commit 324856b26c
10 changed files with 74 additions and 126 deletions

View File

@ -34,7 +34,6 @@ local function spawn(name, template, spriteDir, position, size, level)
char = setmetatable(char, character)
Tree.level.characters[char.id] = char
Tree.level.characterGrid:add(char)
return char
end

View File

@ -23,9 +23,12 @@ function graphics:draw()
local position = Tree.level.characters[self.id].logic.mapLogic.position
local state = Tree.level.characters[self.id].logic.state
if Tree.level.selector.id == self.id then love.graphics.setColor(0.5, 1, 0.5) end
self.animation.animationTable[state]:draw(Tree.assets.files.sprites.character[state],
position.x,
position.y, nil, 1 / ppm, 1 / ppm, 38, 47)
position.x + 0.5,
position.y + 0.5, nil, 1 / ppm, 1 / ppm, 38, 47)
love.graphics.setColor(1, 1, 1)
end
return { new = new }

View File

@ -30,16 +30,12 @@ function logic:update(dt)
self.mapLogic.runTarget = nil
else -- мы не добежали до цели
local vel = (self.mapLogic.runTarget:subtract(self.mapLogic.position):normalize() --[[@as Vec3]]
):scale(2 * dt) -- бежим 2 условных метра в секунду
):scale(1 * dt) -- бежим 2 условных метра в секунду
self.mapLogic.position = self.mapLogic.position:add(vel)
end
end
if self.mapLogic.position ~= self.mapLogic.latestPosition then
-- типа уведомление о том, что положение (на уровне клеток) изменилось
Tree.level.characterGrid:remove(Tree.level.characters[self.id])
Tree.level.characterGrid:add(Tree.level.characters[self.id])
end
Tree.level.characterGrid:add(self.id)
end
return { new = new }

48
lib/grid.lua Normal file
View File

@ -0,0 +1,48 @@
local utils = require "lib/utils"
--- @class CharacterGrid
--- @field __grid {string: Id|nil}
local grid = {}
grid.__index = grid
local function encode(x, y)
return tostring(x) .. ";" .. tostring(y)
end
--- Adds a character id to the grid
--- @param id Id
function grid:add(id)
local character = Tree.level.characters[id]
if not character then return end
local centerX, centerY = math.floor(character.logic.mapLogic.position.x + 0.5),
math.floor(character.logic.mapLogic.position.y + 0.5)
local sizeX, sizeY = character.logic.mapLogic.size.x, character.logic.mapLogic.size.y
for y = centerY, centerY + sizeY - 1 do
for x = centerX, centerX + sizeX - 1 do
self.__grid[encode(x, y)] = character.id
end
end
end
--- @param x integer
--- @param y integer
function grid:get(x, y)
return self.__grid[encode(x, y)]
end
--- clears the grid
function grid:reset()
self.__grid = {}
end
--- Generates an empty grid
--- @return CharacterGrid
local function new()
return setmetatable({
__grid = {}
}, grid)
end
return { new = new }

View File

@ -1,27 +0,0 @@
local Grid = require "lib.grid.grid"
--- @class CharacterGrid: Grid
local CharacterGrid = setmetatable({}, { __index = Grid })
CharacterGrid.__index = CharacterGrid
function CharacterGrid.new(width, height)
return setmetatable(Grid.new(width, height, nil), CharacterGrid)
end
--- Adds a character id to the grid
--- @param character Character
function CharacterGrid:add(character)
local cx, cy = math.floor(character.logic.mapLogic.position.x), math.floor(character.logic.mapLogic.position.y)
local sx, sy = character.logic.mapLogic.size.x, character.logic.mapLogic.size.y
self:fillRect(cx, cy, sx, sy, character.id)
end
--- Removes a character id from the grid
--- @param character Character
function CharacterGrid:remove(character)
local cx, cy = math.floor(character.logic.mapLogic.position.x), math.floor(character.logic.mapLogic.position.y)
local sx, sy = character.logic.mapLogic.size.x, character.logic.mapLogic.size.y
self:fillRect(cx, cy, sx, sy, nil)
end
return { new = CharacterGrid.new }

View File

@ -1,58 +0,0 @@
local utils = require "lib/utils"
--- @class Grid
local Grid = {}
Grid.__index = Grid
--- Создать пустую сетку width x height, заполненную initial (по умолчанию nil)
function Grid.new(width, height, initial)
local g = utils.generateList(width, function()
return utils.generateList(height, function()
return initial
end)
end)
return setmetatable(g, Grid)
end
--- @param x integer
--- @param y integer
function Grid:get(x, y)
local col = self[x]
return col and col[y] or nil
end
--- @param x integer
--- @param y integer
function Grid:set(x, y, value)
self[x][y] = value
end
--- @param x integer
--- @param y integer
function Grid:clear(x, y)
self[x][y] = nil
end
-- нормализуем прямоугольник (поддержка отрицательных размеров)
local function normalizeRect(x, y, w, h)
if w < 0 then
x = x + w + 1; w = -w
end
if h < 0 then
y = y + h + 1; h = -h
end
return x, y, w, h
end
--- Заполнить прямоугольник значением value
function Grid:fillRect(x, y, w, h, value)
x, y, w, h = normalizeRect(x, y, w, h)
local x2, y2 = x + w - 1, y + h - 1
for yy = y, y2 do
for xx = x, x2 do
self[xx][yy] = value
end
end
end
return Grid

View File

@ -1,18 +0,0 @@
local Grid = require "lib.grid.grid"
--- @class TileGrid: Grid
local TileGrid = setmetatable({}, { __index = Grid })
TileGrid.__index = TileGrid
function TileGrid.new(width, height)
return setmetatable(Grid.new(width, height, nil), TileGrid)
end
--- @param x integer
--- @param y integer
--- @param tile Tile | nil
function TileGrid:set(x, y, tile)
Grid.set(self, x, y, tile)
end
return { new = TileGrid.new }

View File

@ -14,14 +14,14 @@ local function new()
return setmetatable({
size = size,
characters = {},
characterGrid = (require "lib/grid/character").new(size.x, size.y),
tileGrid = (require "lib/grid/tile").new(size.x, size.y),
characterGrid = (require "lib/grid").new(),
selector = (require "lib/selector").new(),
camera = (require "lib/camera").new()
}, level)
end
function level:update(dt)
self.characterGrid:reset()
utils.each(self.characters, function(el)
el:update(dt)
end)

View File

@ -1,5 +1,5 @@
--- @class Selector
--- @field id Id
--- @field id Id | nil
local selector = {}
selector.__index = selector
@ -7,7 +7,7 @@ local function new()
return setmetatable({}, selector)
end
--- @param characterId integer
--- @param characterId integer | nil
function selector:select(characterId)
self.id = characterId
end
@ -25,10 +25,10 @@ function selector:update(dt)
if mousePosition.x >= Tree.level.size.x or mousePosition.y >= Tree.level.size.y or mousePosition.y < 0 or mousePosition.x < 0 then
return
end
local characterId = Tree.level.characterGrid[mousePosition.x][mousePosition.y]
local characterId = Tree.level.characterGrid:get(mousePosition.x, mousePosition.y)
self:select(characterId)
print("я ЖОСКО заселектил ", characterId)
print("[Selector]:", mousePosition, characterId and "selected " .. characterId or "deselected")
end
return {

View File

@ -25,15 +25,20 @@ end
function love.draw()
Tree.level.camera:attach()
local width = 20
local height = 12
local width = 30
local height = 30
love.graphics.setColor(139 / 255, 195 / 255, 74 / 255, 1)
love.graphics.rectangle('fill', 0, 0, width, height)
love.graphics.setColor(244 / 255, 67 / 255, 54 / 255, 1)
love.graphics.rectangle('fill', 0, 0, 1, 1)
love.graphics.setColor(1, 1, 1, 1)
for y = 0, height - 1 do
for x = 0, width - 1 do
if (x + y) % 2 == 0 then
love.graphics.setColor(0, 0, 0)
else
love.graphics.setColor(1, 1, 1)
end
love.graphics.rectangle("fill", x, y, 1, 1)
end
end
love.graphics.setColor(1, 1, 1)
Tree.level:draw()
Tree.level.camera:detach()
end