72 lines
2.3 KiB
Lua
72 lines
2.3 KiB
Lua
-- selene: allow(shadowing)
|
|
local gfx = playdate.graphics
|
|
|
|
local AnnouncementFont <const> = playdate.graphics.font.new("fonts/Roobert-20-Medium.pft")
|
|
local AnnouncementTransitionMs <const> = 300
|
|
local AnnouncerMarginX <const> = 26
|
|
|
|
local AnnouncerAnimatorInY <const> =
|
|
playdate.graphics.animator.new(AnnouncementTransitionMs, -70, 0, playdate.easingFunctions.outBounce)
|
|
local AnnouncerAnimatorOutY <const> =
|
|
playdate.graphics.animator.new(AnnouncementTransitionMs, 0, -70, playdate.easingFunctions.outQuint)
|
|
|
|
-- selene: allow(unscoped_variables)
|
|
---@class Announcer
|
|
---@field textQueue string[]
|
|
---@field animatorY pd_animator
|
|
Announcer = {}
|
|
|
|
function Announcer.new()
|
|
return setmetatable({
|
|
textQueue = {},
|
|
animatorY = AnnouncerAnimatorInY,
|
|
}, { __index = Announcer })
|
|
end
|
|
|
|
local DurationMs <const> = 2000
|
|
|
|
function Announcer:popIn()
|
|
self.animatorY = AnnouncerAnimatorInY
|
|
self.animatorY:reset()
|
|
|
|
playdate.timer.new(DurationMs, function()
|
|
self.animatorY = AnnouncerAnimatorOutY
|
|
self.animatorY:reset()
|
|
-- If this popIn() call was inside a timer, successive messages would be
|
|
-- allowed to transition out. However, the Out animation, shortly followed by
|
|
-- a new message popping in, is actually *more* jarring than the interrupt.
|
|
if #self.textQueue ~= 1 then
|
|
self:popIn()
|
|
table.remove(self.textQueue, 1)
|
|
else
|
|
playdate.timer.new(AnnouncementTransitionMs, function()
|
|
table.remove(self.textQueue, 1)
|
|
end)
|
|
end
|
|
end)
|
|
end
|
|
|
|
function Announcer:say(text)
|
|
self.textQueue[#self.textQueue + 1] = text
|
|
if #self.textQueue == 1 then
|
|
self:popIn()
|
|
end
|
|
end
|
|
|
|
function Announcer:draw(x, y)
|
|
if #self.textQueue == 0 then
|
|
return
|
|
end
|
|
x = x - 5 -- Infield center is slightly offset from screen center
|
|
|
|
local originalDrawMode = gfx.getImageDrawMode()
|
|
local width = math.max(150, (AnnouncerMarginX * 2) + AnnouncementFont:getTextWidth(self.textQueue[1]))
|
|
local animY = self.animatorY:currentValue()
|
|
|
|
gfx.setColor(gfx.kColorBlack)
|
|
gfx.fillRect(x - (width / 2), y + animY, width, 50)
|
|
gfx.setImageDrawMode(gfx.kDrawModeInverted)
|
|
AnnouncementFont:drawTextAligned(self.textQueue[1], x, y + 10 + animY, kTextAlignment.center)
|
|
gfx.setImageDrawMode(originalDrawMode)
|
|
end
|