Use the animation.loop class from the SDK, implement mid-animation reversal.

This commit is contained in:
Anna Rose 2023-10-05 16:10:18 -04:00
parent 952bd63d73
commit 678207fd6d
2 changed files with 26 additions and 25 deletions

View File

@ -2,6 +2,7 @@
import "CoreLibs/object" import "CoreLibs/object"
import "CoreLibs/graphics" import "CoreLibs/graphics"
import "CoreLibs/sprites" import "CoreLibs/sprites"
import "CoreLibs/animation"
import "statemachine" import "statemachine"
local gfx <const> = playdate.graphics local gfx <const> = playdate.graphics
@ -16,9 +17,8 @@ function Entity:init(img, health, armor)
self.armor = armor or 0 self.armor = armor or 0
self.introAnimator = nil self.introAnimator = nil
-- For imagetable-based animation -- For imagetable-based animation. see :animate()
self.animationIndex = nil self.animation = nil
self.animationTimer = nil
-- movement direction, every update() the entity will move along this vector and return -- movement direction, every update() the entity will move along this vector and return
-- collision data to the subclass -- collision data to the subclass
@ -73,27 +73,29 @@ function Entity:update()
-- update state machine -- update state machine
self.fsm:execute() self.fsm:execute()
if self.animationTimer then if self.animation and self.animation:isValid() then
local targetIndex = math.floor(self.animationTimer.value) -- TODO: consider efficiency of this vs implementing loop:draw() in a custom draw function
if self.animationIndex ~= targetIndex then self:setImage(self.animation:image())
self:setImage(self.animationTable:getImage(targetIndex))
end
end end
end end
-- animate the entity based on the passed in imageTable. If reverse is true, play the -- animate the entity based on the passed in imageTable.
-- animation backwards. duration is how long the animation should be in total -- duration is the length of *each* frame
-- TODO: it would be nice to be able to reverse the *current* animation without -- If loop is true the animation will start over at the beginning
-- starting all the way over at the beginning... -- If reverse is true the animation will re-use the position in the *existing*
function Entity:animate(imgTable, duration, reverse) -- animation, but inverted. This assumes the new imgTable is the same number of
self.animationTable = imgTable -- frames *and* is a valid reversal of the current animation
local startValue = 1 function Entity:animate(imgTable, duration, loop, reverse)
local endValue = #imgTable local frame = 1
if reverse then
startValue = #imgTable -- reverse has no effect if there is not an active animation
endValue = 1 if reverse and self.animation and self.animation:isValid() then
frame = #imgTable - self.animation.frame + 1
end end
self.animationTimer = playdate.timer.new(duration, startValue, endValue)
loop = loop or false
self.animation = gfx.animation.loop.new(duration, imgTable, loop)
self.animation.frame = frame
end end
-- State machine-controlled functions -- State machine-controlled functions

View File

@ -46,11 +46,10 @@ local SPEED_SIZE_LOOKUP <const> = {
-- animations table -- animations table
local animations <const> = { local animations <const> = {
defend=gfx.imagetable.new("images/kani/defend") defend=gfx.imagetable.new("images/kani/defend"),
defend_reverse=gfx.imagetable.new("images/kani/defend_reverse"),
} }
class("Kani").extends(Entity) class("Kani").extends(Entity)
function Kani:init(ui) function Kani:init(ui)
@ -187,12 +186,12 @@ end
function Kani:onDefend() function Kani:onDefend()
self.armor = 5 self.armor = 5
self:animate(animations.defend, 500) self:animate(animations.defend, 50)
end end
function Kani:onDefendExit() function Kani:onDefendExit()
self.armor = 0 self.armor = 0
self:animate(animations.defend, 500, true) self:animate(animations.defend_reverse, 50, false, true)
end end
function Kani:runDefend() function Kani:runDefend()