72 lines
2.2 KiB
Lua

local anim8 = require "lib.utils.anim8"
--- @class SpriteBehavior : Behavior
--- @field animationTable table<string, table>
--- @field animationGrid table
--- @field state "idle"|"run"|"hurt"|"attack"
--- @field side 1|-1
local sprite = {}
sprite.__index = sprite
sprite.id = "sprite"
sprite.LEFT = -1
sprite.RIGHT = 1
--- Скорость между кадрами в анимации
sprite.ANIMATION_SPEED = 0.1
function sprite.new(spriteDir)
local anim = setmetatable({}, sprite)
anim.animationTable = {}
anim.animationGrid = {}
-- n: name; i: image
for n, i in pairs(spriteDir) do
local aGrid = anim8.newGrid(96, 64, i:getWidth(), i:getHeight())
local tiles = '1-' .. math.ceil(i:getWidth() / 96)
anim.animationGrid[n] = aGrid(tiles, 1)
end
anim.state = "idle"
anim.side = sprite.RIGHT
anim:play("idle")
return anim
end
function sprite:update(dt)
local anim = self.animationTable[self.state] or self.animationTable["idle"] or nil
if not anim then return end
anim:update(dt)
end
function sprite:draw()
if not self.animationTable[self.state] or not Tree.assets.files.sprites.character[self.state] then return end
self.owner:try(Tree.behaviors.map,
function(map)
local ppm = Tree.level.camera.pixelsPerMeter
local position = map.displayedPosition
if Tree.level.selector.id == self.owner.id then love.graphics.setColor(0.5, 1, 0.5) end
self.animationTable[self.state]:draw(Tree.assets.files.sprites.character[self.state],
position.x + 0.5,
position.y + 0.5, nil, 1 / ppm * self.side, 1 / ppm, 38, 47)
love.graphics.setColor(1, 1, 1)
end
)
end
--- @param state string
--- @param loop nil | boolean | fun(): nil
function sprite:play(state, loop)
if not self.animationGrid[state] then
return print("[SpriteBehavior]: no animation for '" .. state .. "'")
end
self.animationTable[state] = anim8.newAnimation(self.animationGrid[state], self.ANIMATION_SPEED,
type(loop) == "function" and loop or
function()
if not loop then self:play("idle", true) end
end)
self.state = state
end
return sprite