spells framework API & walk implementation
This commit is contained in:
parent
bab4b006ca
commit
dd1d64506d
@ -1,4 +1,3 @@
|
|||||||
local anim8 = require "lib.utils.anim8"
|
|
||||||
require 'lib.utils.vec3'
|
require 'lib.utils.vec3'
|
||||||
|
|
||||||
|
|
||||||
@ -12,7 +11,8 @@ local characterId = 1
|
|||||||
--- @field info Info
|
--- @field info Info
|
||||||
--- @field graphics Graphics
|
--- @field graphics Graphics
|
||||||
--- @field logic Logic
|
--- @field logic Logic
|
||||||
--- @field cast boolean @todo тестовое поле, которое отвечает за то, кастуется ли перемещение в данный момент
|
--- @field spellbook Spell[] собственный набор спеллов персонажа
|
||||||
|
--- @field cast Spell | nil ссылка на активный спелл из спеллбука
|
||||||
local character = {}
|
local character = {}
|
||||||
character.__index = character
|
character.__index = character
|
||||||
|
|
||||||
@ -45,11 +45,13 @@ end
|
|||||||
|
|
||||||
function character:update(dt)
|
function character:update(dt)
|
||||||
self.logic:update(dt)
|
self.logic:update(dt)
|
||||||
|
if self.cast then self.cast:update(self, dt) end
|
||||||
self.graphics:update(dt)
|
self.graphics:update(dt)
|
||||||
end
|
end
|
||||||
|
|
||||||
function character:draw()
|
function character:draw()
|
||||||
self.graphics:draw()
|
self.graphics:draw()
|
||||||
|
if self.cast then self.cast:draw() end
|
||||||
end
|
end
|
||||||
|
|
||||||
return { spawn = spawn }
|
return { spawn = spawn }
|
||||||
|
|||||||
@ -61,8 +61,6 @@ function logic:update(dt)
|
|||||||
self.mapLogic.displayedPosition = utils.lerp(self.mapLogic.position, self.mapLogic.runTarget, fraction) -- линейный интерполятор
|
self.mapLogic.displayedPosition = utils.lerp(self.mapLogic.position, self.mapLogic.runTarget, fraction) -- линейный интерполятор
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Tree.level.characterGrid:add(self.id)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return { new = new }
|
return { new = new }
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
local utils = require "lib.utils.utils"
|
||||||
--- @class CharacterGrid : Grid
|
--- @class CharacterGrid : Grid
|
||||||
--- @field __grid {string: Id|nil}
|
--- @field __grid {string: Id|nil}
|
||||||
local grid = setmetatable({}, require "lib.level.grid.base")
|
local grid = setmetatable({}, require "lib.level.grid.base")
|
||||||
@ -20,6 +21,16 @@ function grid:add(id)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- fills the grid with the actual data
|
||||||
|
---
|
||||||
|
--- should be called as early as possible during every tick
|
||||||
|
function grid:reload()
|
||||||
|
self:reset()
|
||||||
|
utils.each(Tree.level.characters, function(c)
|
||||||
|
self:add(c.id)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
--- Generates an empty grid
|
--- Generates an empty grid
|
||||||
--- @return CharacterGrid
|
--- @return CharacterGrid
|
||||||
local function new()
|
local function new()
|
||||||
|
|||||||
@ -27,27 +27,11 @@ local function new(type, template)
|
|||||||
}, level)
|
}, level)
|
||||||
end
|
end
|
||||||
|
|
||||||
local mposCache = nil
|
|
||||||
|
|
||||||
function level:update(dt)
|
function level:update(dt)
|
||||||
self.characterGrid:reset()
|
self.characterGrid:reload()
|
||||||
utils.each(self.characters, function(el)
|
utils.each(self.characters, function(el)
|
||||||
el:update(dt)
|
el:update(dt)
|
||||||
end)
|
end)
|
||||||
if self.characters[self.selector.id] then
|
|
||||||
local charPos = self.characters[self.selector.id].logic.mapLogic.position:floor()
|
|
||||||
--- @type Vec3
|
|
||||||
local mpos = self.camera:toWorldPosition(Vec3 { love.mouse.getX(), love.mouse.getY() }):floor()
|
|
||||||
|
|
||||||
-- ДУШИ здесь больше нет, приводите рыжих обратно
|
|
||||||
if not path or tostring(mpos) ~= mposCache then
|
|
||||||
path = require "lib.pathfinder" (charPos, mpos) -- ?????
|
|
||||||
end
|
|
||||||
mposCache = tostring(mpos)
|
|
||||||
-- path = (require "lib.pathfinder")(charPos, mpos)
|
|
||||||
else
|
|
||||||
mposCache = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
self.camera:update(dt)
|
self.camera:update(dt)
|
||||||
self.selector:update(dt)
|
self.selector:update(dt)
|
||||||
@ -55,16 +39,6 @@ end
|
|||||||
|
|
||||||
function level:draw()
|
function level:draw()
|
||||||
self.tileGrid:draw()
|
self.tileGrid:draw()
|
||||||
|
|
||||||
--- Это отрисовка пути персонажа к мышке
|
|
||||||
if self.selector.id and self.characters[self.selector.id].cast and path then
|
|
||||||
love.graphics.setColor(0.6, 0.75, 0.5)
|
|
||||||
for p in path:values() do
|
|
||||||
love.graphics.circle("fill", p.x + 0.45, p.y + 0.45, 0.1)
|
|
||||||
end
|
|
||||||
love.graphics.setColor(1, 1, 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
utils.each(self.characters, function(el)
|
utils.each(self.characters, function(el)
|
||||||
el:draw()
|
el:draw()
|
||||||
end)
|
end)
|
||||||
|
|||||||
@ -12,10 +12,6 @@ function selector:select(characterId)
|
|||||||
self.id = characterId
|
self.id = characterId
|
||||||
end
|
end
|
||||||
|
|
||||||
-- function selector:deselect()
|
|
||||||
-- self.id = nil
|
|
||||||
-- end
|
|
||||||
|
|
||||||
--- TODO: сделать обработчик селектора
|
--- TODO: сделать обработчик селектора
|
||||||
function selector:update(dt)
|
function selector:update(dt)
|
||||||
if not Tree.controls:isJustPressed("select") then return end
|
if not Tree.controls:isJustPressed("select") then return end
|
||||||
@ -27,16 +23,11 @@ function selector:update(dt)
|
|||||||
end
|
end
|
||||||
local characterId = Tree.level.characterGrid:get(Vec3 { 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]
|
||||||
if char.cast then
|
if char.cast then
|
||||||
char.cast = false
|
char.cast:cast(char, mousePosition)
|
||||||
local charPos = char.logic.mapLogic.position
|
char.cast = nil
|
||||||
local path = (require "lib.pathfinder")(charPos, mousePosition)
|
|
||||||
path:pop_front()
|
|
||||||
print("Following path: ")
|
|
||||||
for p in path:values() do print(p) end
|
|
||||||
char:followPath(path)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self:select(characterId)
|
self:select(characterId)
|
||||||
|
|||||||
54
lib/spellbook.lua
Normal file
54
lib/spellbook.lua
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
--- @class Spell
|
||||||
|
--- @field update fun(self: Spell, caster: Character, dt: number): nil Изменяет состояние спелла
|
||||||
|
--- @field draw fun(self: Spell): nil Рисует превью каста, ничего не должна изменять в идеальном мире
|
||||||
|
--- @field cast fun(self: Spell, caster: Character, target: Vec3): nil Вызывается в момент каста, изменяет мир
|
||||||
|
local spell = {}
|
||||||
|
spell.__index = spell
|
||||||
|
|
||||||
|
local walk = setmetatable({
|
||||||
|
--- @type Deque
|
||||||
|
path = nil
|
||||||
|
}, spell)
|
||||||
|
|
||||||
|
function walk:cast(caster, target)
|
||||||
|
caster.cast = nil
|
||||||
|
local path = self.path
|
||||||
|
path:pop_front()
|
||||||
|
print("Following path: ")
|
||||||
|
for p in path:values() do print(p) end
|
||||||
|
caster:followPath(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
function walk:update(caster, dt)
|
||||||
|
local charPos = caster.logic.mapLogic.position:floor()
|
||||||
|
--- @type Vec3
|
||||||
|
local mpos = Tree.level.camera:toWorldPosition(Vec3 { love.mouse.getX(), love.mouse.getY() }):floor()
|
||||||
|
self.path = require "lib.pathfinder" (charPos, mpos)
|
||||||
|
end
|
||||||
|
|
||||||
|
function walk:draw()
|
||||||
|
if not self.path then return end
|
||||||
|
--- Это отрисовка пути персонажа к мышке
|
||||||
|
love.graphics.setColor(0.6, 0.75, 0.5)
|
||||||
|
for p in self.path:values() do
|
||||||
|
love.graphics.circle("fill", p.x + 0.45, p.y + 0.45, 0.1)
|
||||||
|
end
|
||||||
|
love.graphics.setColor(1, 1, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
----------------------------------------
|
||||||
|
local spellbook = {
|
||||||
|
walk = walk
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Создает новый спеллбук с уникальными спеллами (а не ссылками на шаблоны)
|
||||||
|
--- @param list Spell[]
|
||||||
|
function spellbook.of(list)
|
||||||
|
local spb = {}
|
||||||
|
for i, sp in ipairs(list) do
|
||||||
|
spb[i] = setmetatable({}, { __index = sp })
|
||||||
|
end
|
||||||
|
return spb
|
||||||
|
end
|
||||||
|
|
||||||
|
return spellbook
|
||||||
@ -4,16 +4,16 @@ local ui = require "lib.ui.core"
|
|||||||
|
|
||||||
--- @class SkillButton : Rectangle
|
--- @class SkillButton : Rectangle
|
||||||
--- @field owner Character
|
--- @field owner Character
|
||||||
|
--- @field spellId number
|
||||||
local SkillButton = ui.Rectangle {
|
local SkillButton = ui.Rectangle {
|
||||||
size = Vec3 { 100, 100 },
|
size = Vec3 { 100, 100 },
|
||||||
color = { 1, 0, 0 },
|
color = { 1, 0, 0 },
|
||||||
owner = nil
|
|
||||||
}
|
}
|
||||||
function SkillButton:update(dt)
|
function SkillButton:update(dt)
|
||||||
ui.Rectangle.update(self, dt)
|
ui.Rectangle.update(self, dt)
|
||||||
self.color = self.owner.cast and { 0, 1, 0 } or { 1, 0, 0 }
|
self.color = self.owner.cast and { 0, 1, 0 } or { 1, 0, 0 }
|
||||||
self:onTap(function()
|
self:onTap(function()
|
||||||
self.owner.cast = not self.owner.cast
|
self.owner.cast = self.owner.cast and nil or self.owner.spellbook[self.spellId]
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ function layout:build()
|
|||||||
local r =
|
local r =
|
||||||
ui.Row {
|
ui.Row {
|
||||||
children = {
|
children = {
|
||||||
setmetatable({ owner = Tree.level.characters[id] }, { __index = SkillButton })
|
setmetatable({ owner = Tree.level.characters[id], spellId = 1 }, { __index = SkillButton })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
skillRows[id] = r
|
skillRows[id] = r
|
||||||
|
|||||||
2
main.lua
2
main.lua
@ -3,6 +3,7 @@
|
|||||||
local character = require "lib/character/character"
|
local character = require "lib/character/character"
|
||||||
require "lib/tree"
|
require "lib/tree"
|
||||||
local layout = require "lib.ui.layout"
|
local layout = require "lib.ui.layout"
|
||||||
|
local spellbook = require "lib.spellbook"
|
||||||
|
|
||||||
function love.conf(t)
|
function love.conf(t)
|
||||||
t.console = true
|
t.console = true
|
||||||
@ -15,6 +16,7 @@ function love.load()
|
|||||||
local c = character.spawn("Hero", "warrior", Tree.assets.files.sprites.character)
|
local c = character.spawn("Hero", "warrior", Tree.assets.files.sprites.character)
|
||||||
c.logic.mapLogic.position = Vec3 { x, y }
|
c.logic.mapLogic.position = Vec3 { x, y }
|
||||||
c.logic.mapLogic.displayedPosition = Vec3 { x, y }
|
c.logic.mapLogic.displayedPosition = Vec3 { x, y }
|
||||||
|
c.spellbook = spellbook.of { spellbook.walk }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user