This is on:
- macOS 12.3.1
- SDK 1.10.0
I'm making a game that plays on a grid with a cursor you can move around. When the player taps on the d-pad, the cursor animates between positions. Not only that, but the "color" of the cursor changes based on what square the cursor's on, like on a checkerboard. I want to animate both the cursor's position and its color.
The bug occurs when the color animation outlasts the position animation.
When the user taps a direction, I create animators for both the position and the color. I use
sprite:setAnimator for the position, but have to use my own property for the color animator. (Math omitted for brevity)
function Cursor:movePosition(newX, newY) // ... local anim = gfx.animator.new(positionTransitionDuration, oldPos, newPos, playdate.easingFunctions.linear) self:setAnimator(anim) // ... self.colorAnimator = gfx.animator.new(colorTransitionDuration, fromColor, toColor, playdate.easingFunctions.linear) end
sprite:draw I use the
colorAnimator I set to change the dithering pattern I draw with. When that animator ends, I save it to the sprite's image to avoid re-drawing. In
sprite:update, I see if the sprite's been moved -- if it has, I remove the image and mark it as dirty so the color can animate again.
-- Compute x/y based on position, re-draw if it's moved. function Cursor:update() local x = self.gameRect.x + self.position.x * self.xStep local y = self.gameRect.y + self.position.y * self.yStep if x ~= self.x or y ~= self.y then self:setImage(nil) self:markDirty() end end -- Draw a black border with dithering function Cursor:draw(x, y, width, height) local image = gfx.image.new(width, height) gfx.pushContext(image) gfx.drawRect(x, y, width, height) local ditherValue = self.colorAnimator:currentValue() gfx.setDitherPattern(ditherValue) gfx.fillRect(x, y, width, height) gfx.popContext() -- Always draw. Without it, it flickers in the last frame. print("Drawing " .. ditherValue) image:draw(x, y) -- If we're done animating, then save the image. if self.colorAnimator:ended() then print("Preserving " .. ditherValue) self:setImage(image) end end
If both the position and color animations take the same amount of time, it works great.
positionTransitionDuration = 500.0 colorTransitionDuration = 500.0
However, if I want the color animation to occur more slowly -- to continue changing color after the cursor as finished moving, it just... stops changing color as soon as the position animation ends
positionTransitionDuration = 500.0 colorTransitionDuration = 2000.0
It looks like
sprite:updatejust stops being called once the animator set in
You can try it for yourself with the attached code. Thanks!
test-custom-drawing-sprite.zip (101.1 KB)