Here's a simple class I made to make a scrolling parallax background simple
local pd <const> = playdate
local gfx <const> = pd.graphics
class("Parallax").extends(gfx.sprite)
function Parallax:init()
Parallax.super.init(self)
self.layers = {}
end
function Parallax:draw(...)
gfx.setClipRect(...)
for _, layer in ipairs(self.layers) do
local img = layer.image
-- lock offset to steps of 2 to reduce flashing
local offset = layer.offset - (layer.offset % 2)
local w = layer.width
img:draw(self.x+offset, self.y)
if offset < 0 or offset > w - self.width then
if offset > 0 then
img:draw(self.x+offset-w, self.y)
else
img:draw(self.x+offset+w, self.y)
end
end
end
gfx.clearClipRect()
end
function Parallax:addLayer(img, depth)
local w, _ = img:getSize()
local layer = {}
layer.image = img
layer.depth = depth
layer.offset = 0
layer.width = w
table.push(self.layers, layer)
end
function Parallax:scroll(delta)
for _, layer in ipairs(self.layers) do
layer.offset = math.ring(
layer.offset + (delta * layer.depth),
-layer.width, 0
)
end
self:markDirty()
end
it also uses the math.ring
function that was posted is this thread somewhere (I can't find it atm)
function math.ring(a, min, max)
if min > max then
min, max = max, min
end
return min + (a-min)%(max-min)
end
It's simple to use:
img_1 = gfx.image.new("images/parallax-1")
img_2 = gfx.image.new("images/parallax-2")
-- create
local parallax = Parallax()
parallax:setSize(400,240)
parallax:addLayer(img_1, 0.2)
parallax:addLayer(img_2, 0.6)
parallax:add()
-- scroll
parallax:scroll(10)