tile grid implementation
This commit is contained in:
parent
bc0537a649
commit
7000f0fb4d
32
lib/level/grid/base.lua
Normal file
32
lib/level/grid/base.lua
Normal file
@ -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
|
||||||
@ -1,14 +1,8 @@
|
|||||||
local utils = require "lib.utils.utils"
|
--- @class CharacterGrid : Grid
|
||||||
|
|
||||||
--- @class CharacterGrid
|
|
||||||
--- @field __grid {string: Id|nil}
|
--- @field __grid {string: Id|nil}
|
||||||
local grid = {}
|
local grid = setmetatable({}, require "lib.level.grid.base")
|
||||||
grid.__index = grid
|
grid.__index = grid
|
||||||
|
|
||||||
local function encode(x, y)
|
|
||||||
return tostring(x) .. ";" .. tostring(y)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Adds a character id to the grid
|
--- Adds a character id to the grid
|
||||||
--- @param id Id
|
--- @param id Id
|
||||||
function grid:add(id)
|
function grid:add(id)
|
||||||
@ -21,22 +15,11 @@ function grid:add(id)
|
|||||||
|
|
||||||
for y = centerY, centerY + sizeY - 1 do
|
for y = centerY, centerY + sizeY - 1 do
|
||||||
for x = centerX, centerX + sizeX - 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
|
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
|
--- Generates an empty grid
|
||||||
--- @return CharacterGrid
|
--- @return CharacterGrid
|
||||||
local function new()
|
local function new()
|
||||||
21
lib/level/grid/tile_grid.lua
Normal file
21
lib/level/grid/tile_grid.lua
Normal file
@ -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 }
|
||||||
@ -6,7 +6,7 @@ local utils = require "lib.utils.utils"
|
|||||||
--- @field characterGrid CharacterGrid
|
--- @field characterGrid CharacterGrid
|
||||||
--- @field selector Selector
|
--- @field selector Selector
|
||||||
--- @field camera Camera
|
--- @field camera Camera
|
||||||
--- @field map Map
|
--- @field tileGrid TileGrid
|
||||||
local level = {}
|
local level = {}
|
||||||
level.__index = level
|
level.__index = level
|
||||||
|
|
||||||
@ -20,10 +20,10 @@ local function new(type, template)
|
|||||||
return setmetatable({
|
return setmetatable({
|
||||||
size = size,
|
size = size,
|
||||||
characters = {},
|
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(),
|
selector = (require "lib.level.selector").new(),
|
||||||
camera = (require "lib.level.camera").new(),
|
camera = (require "lib.level.camera").new(),
|
||||||
map = (require "lib.level.map").new(type, template, size)
|
|
||||||
}, level)
|
}, level)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ function level:update(dt)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function level:draw()
|
function level:draw()
|
||||||
self.map:draw()
|
self.tileGrid:draw()
|
||||||
|
|
||||||
--- Это отрисовка пути персонажа к мышке
|
--- Это отрисовка пути персонажа к мышке
|
||||||
if self.selector.id and path then
|
if self.selector.id and path then
|
||||||
|
|||||||
@ -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 }
|
|
||||||
@ -6,12 +6,12 @@ local function new(template, size)
|
|||||||
-- паттерн-матчинг для самых маленьких
|
-- паттерн-матчинг для самых маленьких
|
||||||
if template == "flower_plains" then
|
if template == "flower_plains" then
|
||||||
local tileMap = require("lib.level.tileMap").load(Tree.assets.files.tiles.grass)
|
local tileMap = require("lib.level.tileMap").load(Tree.assets.files.tiles.grass)
|
||||||
map.atlas = tileMap.atlas
|
|
||||||
for y = 0, size.y - 1 do
|
for y = 0, size.y - 1 do
|
||||||
map[y] = {}
|
|
||||||
for x = 0, size.x - 1 do
|
for x = 0, size.x - 1 do
|
||||||
local type = tileMap.map["flower_grass"]
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -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
|
if mousePosition.x >= Tree.level.size.x or mousePosition.y >= Tree.level.size.y or mousePosition.y < 0 or mousePosition.x < 0 then
|
||||||
return
|
return
|
||||||
end
|
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 -- временная обработка события "побежать к точке"
|
if not characterId and self.id then -- временная обработка события "побежать к точке"
|
||||||
local char = Tree.level.characters[self.id]
|
local char = Tree.level.characters[self.id]
|
||||||
|
|||||||
@ -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 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 = {}
|
local tile = {}
|
||||||
tile.__index = tile
|
tile.__index = tile
|
||||||
|
|
||||||
--- TODO: сделать как love.graphics.draw несколько сигнатур у функции
|
--- TODO: сделать как love.graphics.draw несколько сигнатур у функции
|
||||||
--- @param x number
|
--- @param atlasData TileAtlasData
|
||||||
--- @param y number
|
local function new(atlasData)
|
||||||
--- @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)
|
|
||||||
return setmetatable({
|
return setmetatable({
|
||||||
isClip = isClip,
|
atlasData = setmetatable(atlasData, tileAtlasData)
|
||||||
quad = quad
|
|
||||||
}, tile)
|
}, tile)
|
||||||
end
|
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 quad love.Quad
|
||||||
--- @param isClip boolean
|
--- @param isClip boolean
|
||||||
local function fromQuad(quad, isClip)
|
local function fromQuad(quad, isClip)
|
||||||
|
|||||||
@ -29,14 +29,14 @@ local function load(path)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- Как пропатчить KDE2 под любое устройство, используя любые технологии, например, через модульные тесты или инструменты автоматизации?
|
|
||||||
local cnt = 0
|
local cnt = 0
|
||||||
for y = 0, atlas:getHeight() - 1, tiles.tileSize do
|
for y = 0, atlas:getHeight() - 1, tiles.tileSize do
|
||||||
for x = 0, atlas:getWidth() - 1, tiles.tileSize do
|
for x = 0, atlas:getWidth() - 1, tiles.tileSize do
|
||||||
if layout[cnt] then
|
if layout[cnt] then
|
||||||
for _, group in ipairs(layout[cnt]) do
|
for _, group in ipairs(layout[cnt]) do
|
||||||
print(x, y, tiles.tileSize, atlas, false)
|
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
|
if tiles.map[group] then
|
||||||
table.insert(tiles.map[group], tile)
|
table.insert(tiles.map[group], tile)
|
||||||
else
|
else
|
||||||
|
|||||||
@ -28,7 +28,7 @@ end
|
|||||||
--- @param table {[any] : T}
|
--- @param table {[any] : T}
|
||||||
--- @param fn fun(el: T): nil
|
--- @param fn fun(el: T): nil
|
||||||
function P.each(table, fn)
|
function P.each(table, fn)
|
||||||
for _, value in ipairs(table) do
|
for _, value in pairs(table) do
|
||||||
fn(value)
|
fn(value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user