Here's something I put together after finding myself repeatedly reaching for animated patterns. I'll acknowledge up front that this isn't the best approach when it comes to performance (an imageable
would be faster; also, I haven't done any optimization work here yet). That said, it's quick and fun to prototype with. (I'll also plug the Roto utility I made which could be used to export the animated output from this to a sprite sheet as needed.)
Usage
Initialize with a table containing the pattern and animation properties (see the full implementation below for a complete list), and then all it takes is one line to apply it when drawing…
-- initialize
local checkerboard = {0xF0F0, 0xF0F0, 0xF0F0, 0xF0F0, 0x0F0F, 0x0F0F, 0x0F0F, 0x0F0F}
self.easyp = EasyPattern {
pattern = checkerboard,
phaseDuration = 1.0,
phaseFunction = playdate.easingFunctions.inOutCubic,
-- <list any additional animation params here>
}
-- in draw function
playdate.graphics.setPattern(self.easyp:apply())
Examples
Here's an example of a simple horizontal conveyor belt effect:
self.easyp = EasyPattern {
ditherType = gfx.image.kDitherTypeVerticalLine,
xPhaseDuration = 0.5
}
One for a downward stair bounce effect:
self.easyp = EasyPattern {
pattern = checkerboard,
yPhaseDuration = 1.0,
yPhaseFunction = playdate.easingFunctions.outBounce,
yReversed = true,
scale = 2
}
One that pans in a circular motion:
self.easyp = EasyPattern {
pattern = checkerboard,
phaseDuration = 0.5,
phaseFunction = playdate.easingFunctions.inOutSine,
xPhaseOffset = 0.25,
reverses = true,
scale = 2
}
And finally one that demonstrates a custom easing function. Here I'm generating a "random" Perlin noise movement, which could be used for e.g. simulating leaves rustling.
self.easyp = EasyPattern {
pattern = checkerboard,
xPhaseDuration = 3.5,
yPhaseDuration = 2.5,
xPhaseFunction = function(t, b, c, d) return playdate.graphics.perlin(t / d, 1, 2, 3, 3, 0.5) end,
yPhaseFunction = function(t, b, c, d) return playdate.graphics.perlin(t / d, 4, 5, 6, 3, 0.5) end,
scale = 50
}
Implementation
The code isn't doing anything especially complicated, but I did get a bit carried away with the parameterization so file length grew quickly. To make it easier to view the code and docs, I threw it up on GitHub:
Any thoughts on optimization are welcome!