84 lines
3.3 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

local utils = require "lib.utils.utils"
--- Отвечает за перемещение по тайлам
--- @class TiledBehavior : Behavior
--- @field private runSource? Vec3 точка, из которой бежит персонаж
--- @field private runTarget? Vec3 точка, в которую в данный момент бежит персонаж
--- @field private path? Deque путь, по которому сейчас бежит персонаж
--- @field private animationNode? AnimationNode AnimationNode, с которым связана анимация перемещения
--- @field private t0 number время начала движения
--- @field size Vec3
local behavior = {}
behavior.__index = behavior
behavior.id = "tiled"
--- @param size? Vec3
function behavior.new(size)
return setmetatable({
size = size or Vec3({ 1, 1 }),
}, behavior)
end
--- @param path Deque
--- @param animationNode AnimationNode
function behavior:followPath(path, animationNode)
if path:is_empty() then return animationNode:finish() end
self.animationNode = animationNode
self.owner:try(Tree.behaviors.sprite, function(sprite)
sprite:loop("run")
end)
self.path = path;
---@type Vec3
local nextCell = path:peek_front()
self:runTo(nextCell)
path:pop_front()
end
--- @param target Vec3
function behavior:runTo(target)
local positioned = self.owner:has(Tree.behaviors.positioned)
if not positioned then return end
self.t0 = love.timer.getTime()
self.runTarget = target
self.runSource = positioned.position
self.owner:try(Tree.behaviors.sprite,
function(sprite)
if target.x < positioned.position.x then
sprite.side = Tree.behaviors.sprite.LEFT
elseif target.x > positioned.position.x then
sprite.side = Tree.behaviors.sprite.RIGHT
end
end
)
end
function behavior:update(dt)
if self.runTarget then
local positioned = self.owner:has(Tree.behaviors.positioned)
if not positioned then return end
local delta = love.timer.getTime() - self.t0 or love.timer.getTime()
local fraction = delta /
(0.5 * self.runTarget:subtract(self.runSource):length()) -- бежим одну клетку за 500 мс, по диагонали больше
if fraction >= 1 then -- анимация перемещена завершена
positioned.position = self.runTarget
if not self.path:is_empty() then -- еще есть, куда бежать
self:runTo(self.path:pop_front())
else -- мы добежали до финальной цели
self.owner:try(Tree.behaviors.sprite, function(sprite)
sprite:loop("idle")
end)
self.runTarget = nil
if self.animationNode then self.animationNode:finish() end
end
else -- анимация перемещения не завершена
positioned.position = utils.lerp(self.runSource, self.runTarget, fraction) -- линейный интерполятор
end
end
end
return behavior