Compare commits
No commits in common. "5cead3c28291a1785797ec0741342437535a0013" and "dd1d64506d4f1060672e1bcfeaf8c5a7aa067fa0" have entirely different histories.
5cead3c282
...
dd1d64506d
@ -1,8 +1,6 @@
|
|||||||
local utils = require "lib.utils.utils"
|
local utils = require "lib.utils.utils"
|
||||||
local pQueue = require "lib.utils.priority_queue"
|
|
||||||
--- @class CharacterGrid : Grid
|
--- @class CharacterGrid : Grid
|
||||||
--- @field __grid {string: Id|nil}
|
--- @field __grid {string: Id|nil}
|
||||||
--- @field yOrderQueue PriorityQueue<Character> очередь отрисовки сверху вниз
|
|
||||||
local grid = setmetatable({}, require "lib.level.grid.base")
|
local grid = setmetatable({}, require "lib.level.grid.base")
|
||||||
grid.__index = grid
|
grid.__index = grid
|
||||||
|
|
||||||
@ -23,21 +21,13 @@ function grid:add(id)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param a Character
|
|
||||||
--- @param b Character
|
|
||||||
local function drawCmp(a, b)
|
|
||||||
return a.logic.mapLogic.displayedPosition.y < b.logic.mapLogic.displayedPosition.y
|
|
||||||
end
|
|
||||||
|
|
||||||
--- fills the grid with the actual data
|
--- fills the grid with the actual data
|
||||||
---
|
---
|
||||||
--- should be called as early as possible during every tick
|
--- should be called as early as possible during every tick
|
||||||
function grid:reload()
|
function grid:reload()
|
||||||
self:reset()
|
self:reset()
|
||||||
self.yOrderQueue = pQueue.new(drawCmp)
|
|
||||||
utils.each(Tree.level.characters, function(c)
|
utils.each(Tree.level.characters, function(c)
|
||||||
self:add(c.id)
|
self:add(c.id)
|
||||||
self.yOrderQueue:insert(c)
|
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -39,9 +39,9 @@ end
|
|||||||
|
|
||||||
function level:draw()
|
function level:draw()
|
||||||
self.tileGrid:draw()
|
self.tileGrid:draw()
|
||||||
while not self.characterGrid.yOrderQueue:is_empty() do -- по сути это сортировка кучей за n log n, но линейное
|
utils.each(self.characters, function(el)
|
||||||
self.characterGrid.yOrderQueue:pop():draw()
|
el:draw()
|
||||||
end
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -1,106 +0,0 @@
|
|||||||
---@class PriorityQueue
|
|
||||||
---@field private data any[] # внутренний массив-куча (индексация с 1)
|
|
||||||
---@field private cmp fun(a:any, b:any):boolean # компаратор: true, если a выше по приоритету, чем b
|
|
||||||
local PriorityQueue = {}
|
|
||||||
PriorityQueue.__index = PriorityQueue
|
|
||||||
|
|
||||||
---Создать очередь с приоритетом.
|
|
||||||
---@param cmp fun(a:any, b:any):boolean|nil # если nil, используется a < b (мин-куча)
|
|
||||||
---@return PriorityQueue
|
|
||||||
function PriorityQueue.new(cmp)
|
|
||||||
local self = setmetatable({}, PriorityQueue)
|
|
||||||
self.data = {}
|
|
||||||
self.cmp = cmp or function(a, b) return a < b end
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ===== Внутренние утилиты =====
|
|
||||||
|
|
||||||
---@param i integer @индекс узла
|
|
||||||
---@param j integer @индекс узла
|
|
||||||
function PriorityQueue:_swap(i, j)
|
|
||||||
self.data[i], self.data[j] = self.data[j], self.data[i]
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param i integer
|
|
||||||
function PriorityQueue:_sift_up(i)
|
|
||||||
while i > 1 do
|
|
||||||
local p = math.floor(i / 2)
|
|
||||||
if self.cmp(self.data[i], self.data[p]) then
|
|
||||||
self:_swap(i, p)
|
|
||||||
i = p
|
|
||||||
else
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param i integer
|
|
||||||
function PriorityQueue:_sift_down(i)
|
|
||||||
local n = #self.data
|
|
||||||
while true do
|
|
||||||
local l, r = i * 2, i * 2 + 1
|
|
||||||
local best = i
|
|
||||||
|
|
||||||
if l <= n and self.cmp(self.data[l], self.data[best]) then
|
|
||||||
best = l
|
|
||||||
end
|
|
||||||
if r <= n and self.cmp(self.data[r], self.data[best]) then
|
|
||||||
best = r
|
|
||||||
end
|
|
||||||
|
|
||||||
if best ~= i then
|
|
||||||
self:_swap(i, best)
|
|
||||||
i = best
|
|
||||||
else
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ===== Публичный API =====
|
|
||||||
|
|
||||||
---Вставка элемента.
|
|
||||||
---@param x any
|
|
||||||
function PriorityQueue:insert(x)
|
|
||||||
table.insert(self.data, x)
|
|
||||||
self:_sift_up(#self.data)
|
|
||||||
end
|
|
||||||
|
|
||||||
---Посмотреть первый элемент без удаления.
|
|
||||||
---@return any|nil
|
|
||||||
function PriorityQueue:peek()
|
|
||||||
return self.data[1]
|
|
||||||
end
|
|
||||||
|
|
||||||
---Извлечь первый элемент (корень кучи).
|
|
||||||
---@return any|nil
|
|
||||||
function PriorityQueue:pop()
|
|
||||||
local n = #self.data
|
|
||||||
if n == 0 then return nil end
|
|
||||||
|
|
||||||
local top = self.data[1]
|
|
||||||
local last = self.data[n]
|
|
||||||
self.data[n] = nil
|
|
||||||
|
|
||||||
if n > 1 then
|
|
||||||
self.data[1] = last
|
|
||||||
self:_sift_down(1)
|
|
||||||
end
|
|
||||||
|
|
||||||
return top
|
|
||||||
end
|
|
||||||
|
|
||||||
---Текущее количество элементов.
|
|
||||||
---@return integer
|
|
||||||
function PriorityQueue:size()
|
|
||||||
return #self.data
|
|
||||||
end
|
|
||||||
|
|
||||||
---Пуста ли очередь.
|
|
||||||
---@return boolean
|
|
||||||
function PriorityQueue:is_empty()
|
|
||||||
return #self.data == 0
|
|
||||||
end
|
|
||||||
|
|
||||||
return PriorityQueue
|
|
||||||
Loading…
x
Reference in New Issue
Block a user