diff --git a/lib/level/grid/base.lua b/lib/level/grid/base.lua new file mode 100644 index 0000000..cac376d --- /dev/null +++ b/lib/level/grid/base.lua @@ -0,0 +1,32 @@ +local utils = require "lib.utils.utils" + +--- @class Grid +--- @field __grid {string: any} +local grid = {} +grid.__index = grid + +--- adds a value to the grid +--- @param value any +function grid:add(value) + grid[tostring(value.position)] = value +end + +--- @param position Vec3 +function grid:get(position) + return self.__grid[tostring(position)] +end + +--- clears the grid +function grid:reset() + self.__grid = {} +end + +--- Generates an empty grid +--- @return Grid +function grid.new() + return setmetatable({ + __grid = {} + }, grid) +end + +return grid diff --git a/lib/level/grid.lua b/lib/level/grid/character_grid.lua similarity index 65% rename from lib/level/grid.lua rename to lib/level/grid/character_grid.lua index 5a484b7..e217982 100644 --- a/lib/level/grid.lua +++ b/lib/level/grid/character_grid.lua @@ -1,14 +1,8 @@ -local utils = require "lib.utils.utils" - ---- @class CharacterGrid +--- @class CharacterGrid : Grid --- @field __grid {string: Id|nil} -local grid = {} +local grid = setmetatable({}, require "lib.level.grid.base") 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) @@ -21,22 +15,11 @@ function grid:add(id) for y = centerY, centerY + sizeY - 1 do for x = centerX, centerX + sizeX - 1 do - self.__grid[encode(x, y)] = character.id + self.__grid[tostring(Vec3 { 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() diff --git a/lib/level/grid/tile_grid.lua b/lib/level/grid/tile_grid.lua new file mode 100644 index 0000000..776b2e0 --- /dev/null +++ b/lib/level/grid/tile_grid.lua @@ -0,0 +1,21 @@ +local utils = require "lib.utils.utils" +--- @class TileGrid : Grid +local map = setmetatable({}, require "lib.level.grid.base") +map.__index = map + +--- create new map +--- @param type "procedural"|"handmaded" +--- @param template Procedural|Handmaded +--- @param size? Vec3 +local function new(type, template, size) + local tMap = require('lib.level.' .. type).new(template, size) + return setmetatable({ __grid = tMap }, map) +end + +function map:draw() + utils.each(self.__grid, function(el) + el:draw() + end) +end + +return { new = new } diff --git a/lib/level/level.lua b/lib/level/level.lua index 2918cf0..5d743fd 100644 --- a/lib/level/level.lua +++ b/lib/level/level.lua @@ -6,7 +6,7 @@ local utils = require "lib.utils.utils" --- @field characterGrid CharacterGrid --- @field selector Selector --- @field camera Camera ---- @field map Map +--- @field tileGrid TileGrid local level = {} level.__index = level @@ -20,10 +20,10 @@ local function new(type, template) return setmetatable({ size = size, characters = {}, - characterGrid = (require "lib.level.grid").new(), + characterGrid = (require "lib.level.grid.character_grid").new(), + tileGrid = (require "lib.level.grid.tile_grid").new(type, template, size), selector = (require "lib.level.selector").new(), camera = (require "lib.level.camera").new(), - map = (require "lib.level.map").new(type, template, size) }, level) end @@ -54,7 +54,7 @@ function level:update(dt) end function level:draw() - self.map:draw() + self.tileGrid:draw() --- Это отрисовка пути персонажа к мышке if self.selector.id and path then diff --git a/lib/level/map.lua b/lib/level/map.lua deleted file mode 100644 index f8b72cd..0000000 --- a/lib/level/map.lua +++ /dev/null @@ -1,30 +0,0 @@ ---- @class Map ---- @field atlas love.Image ---- @field size Vec3|nil -local map = {} -map.__index = map - ---- create new map ---- @param type "procedural"|"handmaded" ---- @param template Procedural|Handmaded ---- @param size? Vec3 -local function new(type, template, size) - map.size = size - local tMap = require('lib.level.' .. type).new(template, size) - return setmetatable(tMap, map) -end - -function map:draw() - for y = 0, self.size.y - 1 do - for x = 0, self.size.x - 1 do - love.graphics.draw(self.atlas, self[x][y].quad, x, y, - nil, 1 / 32, 1 / 32) - end - end -end - -function map:get(x, y) - return self[x][y] -end - -return { new = new } diff --git a/lib/level/procedural.lua b/lib/level/procedural.lua index 88574de..f62ae03 100644 --- a/lib/level/procedural.lua +++ b/lib/level/procedural.lua @@ -6,12 +6,12 @@ local function new(template, size) -- паттерн-матчинг для самых маленьких if template == "flower_plains" then local tileMap = require("lib.level.tileMap").load(Tree.assets.files.tiles.grass) - map.atlas = tileMap.atlas for y = 0, size.y - 1 do - map[y] = {} for x = 0, size.x - 1 do local type = tileMap.map["flower_grass"] - map[y][x] = type[math.random(1, #type)] + --- @type Tile + local tile = type[math.random(1, #type)]:copyWith({ position = Vec3 { x, y } }) + map[tostring(tile.position)] = tile end end end diff --git a/lib/level/selector.lua b/lib/level/selector.lua index 8784b25..ba7829f 100644 --- a/lib/level/selector.lua +++ b/lib/level/selector.lua @@ -25,7 +25,7 @@ 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:get(mousePosition.x, mousePosition.y) + local characterId = Tree.level.characterGrid:get(Vec3 { mousePosition.x, mousePosition.y }) if not characterId and self.id then -- временная обработка события "побежать к точке" local char = Tree.level.characters[self.id] diff --git a/lib/level/tile.lua b/lib/level/tile.lua index 7d132d1..74afba4 100644 --- a/lib/level/tile.lua +++ b/lib/level/tile.lua @@ -1,23 +1,50 @@ ---- @class Tile +--- @class TileAtlasData +--- @field x number +--- @field y number +--- @field tileSize number +--- @field atlas love.Image --- @field isClip boolean ---- @field quad love.Quad +--- @field quad love.Quad | nil +local tileAtlasData = {} +tileAtlasData.__index = tileAtlasData + +function tileAtlasData:getQuad() + if self.quad then return self.quad end + self.quad = love.graphics.newQuad(self.x, self.y, self.tileSize, self.tileSize, self.atlas) + return self.quad +end + +----------------------------------------------------------------- + +--- @class Tile +--- @field atlasData TileAtlasData +--- @field position Vec3 local tile = {} tile.__index = tile --- TODO: сделать как love.graphics.draw несколько сигнатур у функции ---- @param x number ---- @param y number ---- @param tileSize number ---- @param atlas love.Image ---- @param isClip boolean -local function new(x, y, tileSize, atlas, isClip) - local quad = love.graphics.newQuad(x, y, tileSize, tileSize, atlas) +--- @param atlasData TileAtlasData +local function new(atlasData) return setmetatable({ - isClip = isClip, - quad = quad + atlasData = setmetatable(atlasData, tileAtlasData) }, tile) end +function tile:draw() + love.graphics.draw(self.atlasData.atlas, self.atlasData:getQuad(), self.position.x, + self.position.y, + nil, 1 / 32, 1 / 32) +end + +--- @param values table +--- @return Tile +function tile:copyWith(values) + for k, v in pairs(self) do + values[k] = v + end + return setmetatable(values, tile) +end + --- @param quad love.Quad --- @param isClip boolean local function fromQuad(quad, isClip) diff --git a/lib/level/tileMap.lua b/lib/level/tileMap.lua index 3fff93a..749937f 100644 --- a/lib/level/tileMap.lua +++ b/lib/level/tileMap.lua @@ -29,14 +29,14 @@ local function load(path) end end end - -- Как пропатчить KDE2 под любое устройство, используя любые технологии, например, через модульные тесты или инструменты автоматизации? + local cnt = 0 for y = 0, atlas:getHeight() - 1, tiles.tileSize do for x = 0, atlas:getWidth() - 1, tiles.tileSize do if layout[cnt] then for _, group in ipairs(layout[cnt]) do print(x, y, tiles.tileSize, atlas, false) - local tile = require('lib.level.tile').new(x, y, tiles.tileSize, atlas, false) + local tile = require('lib.level.tile').new { x = x, y = y, tileSize = tiles.tileSize, atlas = atlas, isClip = false } if tiles.map[group] then table.insert(tiles.map[group], tile) else diff --git a/lib/utils/utils.lua b/lib/utils/utils.lua index e39d03e..b5c0362 100644 --- a/lib/utils/utils.lua +++ b/lib/utils/utils.lua @@ -28,7 +28,7 @@ end --- @param table {[any] : T} --- @param fn fun(el: T): nil function P.each(table, fn) - for _, value in ipairs(table) do + for _, value in pairs(table) do fn(value) end end