rewrite sprite:animate, residentsleeper:sleep, attack:cast to use
callback trees
This commit is contained in:
parent
86a599723e
commit
59cc0fba0b
@ -1,6 +1,5 @@
|
|||||||
local easing = require "lib.utils.easing"
|
local easing = require "lib.utils.easing"
|
||||||
|
|
||||||
--- @alias voidCallback fun(): nil
|
|
||||||
--- @alias animationRunner fun(node: AnimationNode)
|
--- @alias animationRunner fun(node: AnimationNode)
|
||||||
|
|
||||||
--- Узел дерева анимаций.
|
--- Узел дерева анимаций.
|
||||||
|
|||||||
@ -9,3 +9,5 @@ Tree.behaviors.positioned = require "character.behaviors.positioned"
|
|||||||
Tree.behaviors.tiled = require "character.behaviors.tiled"
|
Tree.behaviors.tiled = require "character.behaviors.tiled"
|
||||||
Tree.behaviors.cursor = require "character.behaviors.cursor"
|
Tree.behaviors.cursor = require "character.behaviors.cursor"
|
||||||
Tree.behaviors.ai = require "lib.character.behaviors.ai"
|
Tree.behaviors.ai = require "lib.character.behaviors.ai"
|
||||||
|
|
||||||
|
--- @alias voidCallback fun(): nil
|
||||||
|
|||||||
@ -1,21 +1,37 @@
|
|||||||
--- Умеет асинхронно ждать какое-то время (для анимаций)
|
--- Умеет асинхронно ждать какое-то время (для анимаций)
|
||||||
--- @class ResidentSleeperBehavior : Behavior
|
--- @class ResidentSleeperBehavior : Behavior
|
||||||
--- @field animationNode? AnimationNode
|
--- @field private t0 number?
|
||||||
|
--- @field private sleepTime number?
|
||||||
|
--- @field private callback voidCallback?
|
||||||
|
--- @field private state 'running' | 'finished'
|
||||||
local behavior = {}
|
local behavior = {}
|
||||||
behavior.__index = behavior
|
behavior.__index = behavior
|
||||||
behavior.id = "residentsleeper"
|
behavior.id = "residentsleeper"
|
||||||
|
|
||||||
function behavior.new() return setmetatable({}, behavior) end
|
function behavior.new() return setmetatable({}, behavior) end
|
||||||
|
|
||||||
function behavior:update(dt)
|
function behavior:update(_)
|
||||||
if not self.animationNode then return end
|
if self.state ~= 'running' then return end
|
||||||
self.animationNode:update(dt)
|
|
||||||
|
local t = love.timer.getTime()
|
||||||
|
if t >= self.t0 + self.sleepTime then
|
||||||
|
self.state = 'finished'
|
||||||
|
self.callback()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param node AnimationNode
|
--- @return Task<nil>
|
||||||
function behavior:sleep(node)
|
function behavior:sleep(ms)
|
||||||
if self.animationNode then self.animationNode:finish() end
|
self.sleepTime = ms / 1000
|
||||||
self.animationNode = node
|
return function(callback)
|
||||||
|
if self.state == 'running' then
|
||||||
|
self.callback()
|
||||||
|
end
|
||||||
|
|
||||||
|
self.t0 = love.timer.getTime()
|
||||||
|
self.callback = callback
|
||||||
|
self.state = 'running'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return behavior
|
return behavior
|
||||||
|
|||||||
@ -69,17 +69,20 @@ function sprite:draw()
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param node AnimationNode
|
--- @return Task<nil>
|
||||||
function sprite:animate(state, node)
|
function sprite:animate(state, node)
|
||||||
|
return function(callback)
|
||||||
if not self.animationGrid[state] then
|
if not self.animationGrid[state] then
|
||||||
return print("[SpriteBehavior]: no animation for '" .. state .. "'")
|
print("[SpriteBehavior]: no animation for '" .. state .. "'")
|
||||||
|
callback()
|
||||||
end
|
end
|
||||||
self.animationTable[state] = anim8.newAnimation(self.animationGrid[state], self.ANIMATION_SPEED,
|
self.animationTable[state] = anim8.newAnimation(self.animationGrid[state], self.ANIMATION_SPEED,
|
||||||
function()
|
function()
|
||||||
self:loop("idle")
|
self:loop("idle")
|
||||||
node:finish()
|
callback()
|
||||||
end)
|
end)
|
||||||
self.state = state
|
self.state = state
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function sprite:loop(state)
|
function sprite:loop(state)
|
||||||
|
|||||||
@ -7,8 +7,7 @@
|
|||||||
--- --TODO: каждый каст должен возвращать объект, который позволит отследить момент завершения анимации спелла
|
--- --TODO: каждый каст должен возвращать объект, который позволит отследить момент завершения анимации спелла
|
||||||
--- Да, это Future/Promise/await/async
|
--- Да, это Future/Promise/await/async
|
||||||
|
|
||||||
local AnimationNode = require "lib.animation_node"
|
local Counter = require 'lib.utils.counter'
|
||||||
local easing = require "lib.utils.easing"
|
|
||||||
|
|
||||||
--- @class Spell Здесь будет много бойлерплейта, поэтому тоже понадобится спеллмейкерский фреймворк, который просто вернет готовый Spell
|
--- @class Spell Здесь будет много бойлерплейта, поэтому тоже понадобится спеллмейкерский фреймворк, который просто вернет готовый Spell
|
||||||
--- @field tag string
|
--- @field tag string
|
||||||
@ -59,9 +58,6 @@ function walk:cast(caster, target)
|
|||||||
local testChar = Tree.level.characters[1];
|
local testChar = Tree.level.characters[1];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return function(callback) -- <- вызовется после всех анимаций
|
return function(callback) -- <- вызовется после всех анимаций
|
||||||
local counter = require 'lib.utils.counter' (callback)
|
local counter = require 'lib.utils.counter' (callback)
|
||||||
counter.push()
|
counter.push()
|
||||||
@ -147,7 +143,7 @@ function attack:cast(caster, target)
|
|||||||
print("dist:", dist)
|
print("dist:", dist)
|
||||||
return dist > 2
|
return dist > 2
|
||||||
end) then
|
end) then
|
||||||
return false
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
caster:try(Tree.behaviors.stats, function(stats)
|
caster:try(Tree.behaviors.stats, function(stats)
|
||||||
@ -156,7 +152,7 @@ function attack:cast(caster, target)
|
|||||||
|
|
||||||
--- @type Character
|
--- @type Character
|
||||||
local targetCharacterId = Tree.level.characterGrid:get(target)
|
local targetCharacterId = Tree.level.characterGrid:get(target)
|
||||||
if not targetCharacterId or targetCharacterId == caster.id then return false end
|
if not targetCharacterId or targetCharacterId == caster.id then return end
|
||||||
local targetCharacter = Tree.level.characters[targetCharacterId]
|
local targetCharacter = Tree.level.characters[targetCharacterId]
|
||||||
targetCharacter:try(Tree.behaviors.stats, function(stats)
|
targetCharacter:try(Tree.behaviors.stats, function(stats)
|
||||||
stats.hp = stats.hp - 4
|
stats.hp = stats.hp - 4
|
||||||
@ -164,43 +160,24 @@ function attack:cast(caster, target)
|
|||||||
|
|
||||||
local sprite = caster:has(Tree.behaviors.sprite)
|
local sprite = caster:has(Tree.behaviors.sprite)
|
||||||
local targetSprite = targetCharacter:has(Tree.behaviors.sprite)
|
local targetSprite = targetCharacter:has(Tree.behaviors.sprite)
|
||||||
if not sprite or not targetSprite then return true end
|
if not sprite or not targetSprite then return end
|
||||||
|
|
||||||
caster:try(Tree.behaviors.positioned, function(b) b:lookAt(target) end)
|
caster:try(Tree.behaviors.positioned, function(b) b:lookAt(target) end)
|
||||||
|
|
||||||
AnimationNode {
|
return function(callback)
|
||||||
onEnd = function() caster:has(Tree.behaviors.spellcaster):endCast() end,
|
local c = Counter(callback)
|
||||||
children = {
|
|
||||||
AnimationNode {
|
|
||||||
function(node)
|
|
||||||
sprite:animate("attack", node)
|
|
||||||
end
|
|
||||||
},
|
|
||||||
AnimationNode {
|
|
||||||
function(node)
|
|
||||||
targetCharacter:has(Tree.behaviors.residentsleeper):sleep(node)
|
|
||||||
end,
|
|
||||||
duration = 200,
|
|
||||||
children = {
|
|
||||||
AnimationNode {
|
|
||||||
function(node)
|
|
||||||
local audioPath = Tree.assets.files.audio
|
|
||||||
targetSprite:animate("hurt", node)
|
|
||||||
--- @type SourceFilter
|
|
||||||
local settings = {
|
|
||||||
type = "highpass",
|
|
||||||
volume = 1,
|
|
||||||
lowgain = 0.1
|
|
||||||
}
|
|
||||||
Tree.audio:play(audioPath.sounds.hurt)
|
|
||||||
end
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}:run()
|
|
||||||
|
|
||||||
return true
|
c.push()
|
||||||
|
sprite:animate("attack")(c.pop)
|
||||||
|
|
||||||
|
c.push()
|
||||||
|
targetCharacter:has(Tree.behaviors.residentsleeper):sleep(200)(
|
||||||
|
function()
|
||||||
|
targetSprite:animate("hurt")(c.pop)
|
||||||
|
Tree.audio:play(Tree.assets.files.audio.sounds.hurt)
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user