Hello Playdate team!
I've been enjoying the Playdate SDK very much. It's a fun development playground, and the crank is intriguing. The features and documentation have helped me get some projects started. Although the 1-bit display sounds restrictive, it has actually sparked some creativity. They say that constraints boost creativity.
In particular, the SDK's image features afford a lot of flexibility when drawing things to the screen. One of my projects requires rotating and scaling sprites. When rotating a sprite that has a negative scale, the sprite disappears. Also, the scale has to be set after setting the rotation, otherwise the scale appears to be reset for sprites that have a negative y scale and a positive x scale.
I can work around this problem by creating a blank image; pushing that image onto the graphics context; drawing a scaled, unrotated version of the desired image; popping the context; and rotating the drawn image.
Example code and Playdate Simulator recordings follow.
I am using a 2020 Mac M1 mini.
I look forward to hearing back from you.
Thanks!
REPLICATION
local rotation = 0
function makeSprite(offsetX, offsetY, scaleX, scaleY)
local sprite <const> = playdate.graphics.sprite.new(playdate.graphics.image.new("Sprites/robot"))
sprite:setScale(scaleX, scaleY)
sprite:add()
sprite:moveTo((playdate.display.getWidth() / 2) + offsetX, (playdate.display.getHeight() / 2) + offsetY)
return sprite
end
local sprites <const> = {
makeSprite(-150, -50, 1, 1), -- unscaled
makeSprite(-50, -50, -1, 1), -- negative x scale
makeSprite(50, -50, 1, -1), -- negative y scale
makeSprite(150, -50, -1, -1), -- negative x and y scale
makeSprite(-150, 50, 2, 2), -- upscaled
makeSprite(-50, 50, -2, 2), -- upscaled, negative x scale
makeSprite(50, 50, 2, -2), -- upscaled, negative y scale
makeSprite(150, 50, -2, -2) -- upscaled, negative x and y scale
}
function playdate.update()
rotation += 1
for i = 1, #sprites do
local sprite <const> = sprites[i]
local scaleX <const>, scaleY <const> = sprite:getScale()
sprite:setRotation(rotation)
sprite:setCollideRect(0, 0, sprite:getSize())
sprite:setScale(scaleX, scaleY)
end
playdate.graphics.sprite.update()
end
WORKAROUND
local rotation = 0
function makeSprite(offsetX, offsetY, scaleX, scaleY)
local image <const> = playdate.graphics.image.new("Sprites/robot")
local imageSizeX <const>, imageSizeY <const> = image:getSize()
local spriteImage = playdate.graphics.image.new(math.abs(imageSizeX * scaleX), math.abs(imageSizeY * scaleY))
local sprite <const> = playdate.graphics.sprite.new(spriteImage)
playdate.graphics.pushContext(sprite:getImage())
image:scaledImage(scaleX, scaleY):draw(0, 0)
playdate.graphics.popContext()
sprite:add()
sprite:moveTo((playdate.display.getWidth() / 2) + offsetX, (playdate.display.getHeight() / 2) + offsetY)
return sprite
end
local sprites <const> = {
makeSprite(-150, -50, 1, 1), -- unscaled
makeSprite(-50, -50, -1, 1), -- negative x scale
makeSprite(50, -50, 1, -1), -- negative y scale
makeSprite(150, -50, -1, -1), -- negative x and y scale
makeSprite(-150, 50, 2, 2), -- upscaled
makeSprite(-50, 50, -2, 2), -- upscaled, negative x scale
makeSprite(50, 50, 2, -2), -- upscaled, negative y scale
makeSprite(150, 50, -2, -2) -- upscaled, negative x and y scale
}
function playdate.update()
rotation += 1
for i = 1, #sprites do
local sprite <const> = sprites[i]
sprite:setRotation(rotation)
sprite:setCollideRect(0, 0, sprite:getSize())
end
playdate.graphics.sprite.update()
end