I just came up with this snippet after pondering an SDK feature request I made myself. Use it to draw images with phase offsets, such as continuously scrolling backgrounds, etc.:
function playdate.graphics.image:drawPhased(x, y, xPhase, yPhase)
local w = self.width -- shorthand width
local h = self.height -- shorthand height
local _x = xPhase % w -- constrained phase in x axis
local _y = yPhase % h -- constrained phase in y axis
local w_ = w - _x -- width of left half
local _w = _x -- width of right half
local h_ = h - _y -- height of top half
local _h = _y -- height of bottom half
self:draw(x, y, nil, _x, _y, w_, h_) -- TL
self:draw(x + w_, y, nil, 0, _y, _w, h_) -- TR
self:draw(x, y + h_, nil, _x, 0, w_, _h) -- BL
self:draw(x + w_, y + h_, nil, 0, 0, _w, _h) -- BR
end
Result:
For good measure, I added an option to tile a phased image as well, which provides a way to animate patterns larger than the standard 8x8. You could use this with a stencil to use large animated patterns for drawn shapes.
function playdate.graphics.image:drawTiledWithPhase(x, y, w, h, flip, xPhase, yPhase)
-- create a phased version of ourselves to tile
local tile = playdate.graphics.image.new(self.width, self.height)
playdate.graphics.pushContext(tile)
self:drawPhased(0, 0, xPhase, yPhase)
playdate.graphics.popContext()
-- draw the phased tile
tile:drawTiled(x, y, w, h, flip)
end
Tile:
Result:
Update: Added support for flip
to drawPhased
.
function playdate.graphics.image:drawPhased(x, y, xPhase, yPhase, flip)
local w = self.width -- shorthand width
local h = self.height -- shorthand height
local xp = xPhase % w -- constrained phase in x axis
local yp = yPhase % h -- constrained phase in y axis
local w_ = w - xp -- width of left half
local _w = xp -- width of right half
local h_ = h - yp -- height of top half
local _h = yp -- height of bottom half
local x_ = x -- x coord of left half
local _x = x + w_ -- x coord of right half
local y_ = y -- y coord of top half
local _y = y + h_ -- y coord of bottom half
local gfx = playdate.graphics
if flip == gfx.kImageFlippedX or flip == gfx.kImageFlippedXY then
x_, _x = _x, x_
w_, _w = _w, w_
xp = w - xp
end
if flip == gfx.kImageFlippedY or flip == gfx.kImageFlippedXY then
y_, _y = _y, y_
h_, _h = _h, h_
yp = h - yp
end
-- (when unflipped)
self:draw(x_, y_, flip, xp, yp, w_, h_) -- TL
self:draw(_x, y_, flip, 0, yp, _w, h_) -- TR
self:draw(x_, _y, flip, xp, 0, w_, _h) -- BL
self:draw(_x, _y, flip, 0, 0, _w, _h) -- BR
end