I'm back to work on my next title (Outside Parties, a horror game) and I'm wondering... what's the highest-framerate way to fade (nearly) the entire screen from one image to another? (Not one image to/from black—two images.)
My early experiments using image:blendWithImage have been super slow and choppy on-device, regardless of dither choice. Maybe it can't be done? (At least not in Lua?)
Luckily, there's NOTHING else going on on the screen, so I have lots of flexibility to use any approach!
15 fps would be good... 20+ would be awesome! I'm getting more like 6 to 8.
I was going to suggest looking at the "fast_fade" example in Single File Examples, but it looks like that could use an update. So, I would suggest using stencils, something like this:
import "CoreLibs/graphics"
import "CoreLibs/animator"
local gfx <const> = playdate.graphics
playdate.display.setRefreshRate(50)
local image1 = gfx.image.new("one")
local image2 = gfx.image.new("two")
local alpha = 0
local duration = 1000
local animator = playdate.graphics.animator.new(duration, 0, 1)
function playdate.AButtonDown()
if alpha == 1 then
animator = playdate.graphics.animator.new(duration, alpha, 0)
end
end
function playdate.BButtonDown()
if alpha == 0 then
animator = playdate.graphics.animator.new(duration, alpha, 1)
end
end
function playdate.update()
image1:draw(0, 0)
alpha = animator:currentValue()
gfx.setStencilPattern(alpha, gfx.image.kDitherTypeBayer8x8)
image2:draw(0, 0)
gfx.clearStencil()
playdate.drawFPS(1, 1)
end
I was trying to do this fade, but with using sprites, and I was banging my head against the wall, because I could only get it to fade in (increasing the alpha level to 1), but couldn't get it to fade down again! Well several hours later I finally found out why!
I had to set the sprite not to be opaque!!! I think that should be added to the documentation to sprite:setStencilPattern(level) - at least it could have saved me some hours!
For anyone interested here is Dave's code, but using sprites:
import "CoreLibs/graphics"
import "CoreLibs/animator"
import "CoreLibs/sprites"
local gfx <const> = playdate.graphics
playdate.display.setRefreshRate(50)
local image1 = gfx.image.new("one")
local image2 = gfx.image.new("two")
local sprite1 = gfx.sprite.new(image1)
sprite1:setCenter(0, 0)
sprite1:setZIndex(1)
sprite1:add()
local sprite2 = gfx.sprite.new(image2)
sprite2:setCenter(0, 0)
sprite2:setZIndex(2)
sprite2:add()
sprite2:setOpaque(false)
local alpha = 0
local duration = 1000
local animator = playdate.graphics.animator.new(duration, 0, 1)
function playdate.AButtonDown()
if alpha == 1 then
animator = playdate.graphics.animator.new(duration, alpha, 0)
end
end
function playdate.BButtonDown()
if alpha == 0 then
animator = playdate.graphics.animator.new(duration, alpha, 1)
end
end
sprite2.update = function(self)
self:setStencilPattern(alpha, gfx.image.kDitherTypeBayer8x8)
end
function playdate.update()
alpha = animator:currentValue()
gfx.sprite.update()
end