BatterUp/src/draw/overlay.lua

169 lines
5.7 KiB
Lua

-- selene: allow(shadowing)
local gfx = playdate.graphics
local ScoreFont <const> = FontFullCircle
local MinimapSizeX, MinimapSizeY <const> = Minimap:getSize()
local MinimapPosX, MinimapPosY = C.Screen.W - MinimapSizeX, C.Screen.H - MinimapSizeY
local MinimapBoundX, MinimapBoundY = (MinimapSizeX + MinimapPosX), (MinimapSizeY + MinimapPosY)
local MinimapMultX <const> = 0.75 * MinimapSizeX / C.Screen.W
local MinimapOffsetX <const> = MinimapPosX + 5
local MinimapMultY <const> = 0.70 * MinimapSizeY / C.FieldHeight
local MinimapOffsetY <const> = MinimapPosY - 15
local RunnerSquareWidth = 8
local FielderCircleRadius = 4
local FielderCircleStrokeWidth = 2
function drawMinimap(runners, fielders)
Minimap:draw(MinimapPosX, MinimapPosY)
gfx.setColor(gfx.kColorBlack)
for _, runner in pairs(runners) do
local x = (MinimapMultX * runner.x) + MinimapOffsetX
local y = (MinimapMultY * runner.y) + MinimapOffsetY
gfx.fillRect(x, y, RunnerSquareWidth, RunnerSquareWidth)
end
gfx.setLineWidth(FielderCircleStrokeWidth)
for _, fielder in pairs(fielders) do
local x = (MinimapMultX * fielder.x) + MinimapOffsetX
local y = (MinimapMultY * fielder.y) + MinimapOffsetY
if x > MinimapPosX and x < MinimapBoundX and y > MinimapPosY and y < MinimapBoundY then
gfx.drawCircleAtPoint(x, y, FielderCircleRadius)
end
end
end
local BallStrikeMarginY <const> = 4
local BallStrikeWidth <const> = 60
local BallStrikeHeight <const> = (BallStrikeMarginY * 2) + ScoreFont:getHeight()
local BallStrikeAnimatorIn <const> =
playdate.graphics.animator.new(500, BallStrikeHeight, 0, playdate.easingFunctions.outBounce)
local BallStrikeAnimatorOut <const> =
playdate.graphics.animator.new(500, 0, BallStrikeHeight, playdate.easingFunctions.linear)
-- Start out of frame.
local currentBallStrikeAnimator = utils.staticAnimator(20)
function drawBallsAndStrikes(x, y, balls, strikes)
if balls == 0 and strikes == 0 then
if currentBallStrikeAnimator == BallStrikeAnimatorIn then
currentBallStrikeAnimator = BallStrikeAnimatorOut
currentBallStrikeAnimator:reset()
end
if currentBallStrikeAnimator:ended() then
return
end
end
if balls + strikes == 1 and currentBallStrikeAnimator ~= BallStrikeAnimatorIn then
-- First pitch - should pop in now.
currentBallStrikeAnimator = BallStrikeAnimatorIn
currentBallStrikeAnimator:reset()
end
y = y + currentBallStrikeAnimator:currentValue()
gfx.setColor(gfx.kColorBlack)
gfx.fillRect(x, y, BallStrikeWidth, BallStrikeHeight)
local originalDrawMode = gfx.getImageDrawMode()
gfx.setImageDrawMode(gfx.kDrawModeInverted)
local text = tostring(balls) .. " - " .. tostring(strikes)
local textWidth = ScoreFont:getTextWidth(text)
local widthDiff = BallStrikeWidth - textWidth
ScoreFont:drawText(text, x + (widthDiff / 2), y + BallStrikeMarginY)
gfx.setImageDrawMode(originalDrawMode)
end
local OutBubbleRadius <const> = 5
local ScoreboardMarginX <const> = 6
local ScoreboardMarginRight <const> = 4
local ScoreboardHeight <const> = 55
local Indicator = "> "
local IndicatorWidth <const> = ScoreFont:getTextWidth(Indicator)
---@param battingTeam any
---@return string, number, string, number
function getIndicators(battingTeam)
if battingTeam == "home" then
return Indicator, 0, "", IndicatorWidth
end
return "", IndicatorWidth, Indicator, 0
end
local stats = {
homeScore = 0,
awayScore = 0,
outs = 0,
inning = 1,
battingTeam = nil,
}
function drawScoreboardImpl(x, y)
local homeScore = stats.homeScore
local awayScore = stats.awayScore
local homeIndicator, homeOffset, awayIndicator, awayOffset = getIndicators(stats.battingTeam)
local homeScoreText = homeIndicator .. "HOME " .. (homeScore > 9 and homeScore or " " .. homeScore)
local awayScoreText = awayIndicator .. "AWAY " .. (awayScore > 9 and awayScore or " " .. awayScore)
local rectWidth = (ScoreboardMarginX * 2)
+ ScoreboardMarginRight
+ ScoreFont:getTextWidth(homeScoreText)
+ homeOffset
gfx.setLineWidth(1)
gfx.setColor(gfx.kColorBlack)
gfx.fillRect(x, y, rectWidth, ScoreboardHeight)
local originalDrawMode = gfx.getImageDrawMode()
gfx.setImageDrawMode(gfx.kDrawModeInverted)
ScoreFont:drawText(homeScoreText, x + ScoreboardMarginX + homeOffset, y + 6)
ScoreFont:drawText(awayScoreText, x + ScoreboardMarginX + awayOffset, y + 22)
local inningOffsetX = (x + ScoreboardMarginX + IndicatorWidth) + (4 * 2.5 * OutBubbleRadius)
ScoreFont:drawText(tostring(stats.inning), inningOffsetX, y + 39)
gfx.setImageDrawMode(originalDrawMode)
gfx.setColor(gfx.kColorWhite)
function circleParams(i)
local circleOffset = i * 2.5 * OutBubbleRadius
return (x + ScoreboardMarginX + OutBubbleRadius + IndicatorWidth) + circleOffset, y + 46, OutBubbleRadius
end
for i = stats.outs, 2 do
gfx.drawCircleAtPoint(circleParams(i))
end
for i = 0, (stats.outs - 1) do
gfx.fillCircleAtPoint(circleParams(i))
end
end
local newStats = stats
function drawScoreboard(x, y, homeScore, awayScore, outs, battingTeam, inning)
if
newStats.homeScore ~= homeScore
or newStats.awayScore ~= awayScore
or newStats.outs ~= outs
or newStats.inning ~= inning
or newStats.battingTeam ~= battingTeam
then
newStats = {
homeScore = homeScore,
awayScore = awayScore,
outs = outs,
inning = inning,
battingTeam = battingTeam,
}
playdate.timer.new(C.ScoreboardDelayMs, function()
stats = newStats
end)
end
drawScoreboardImpl(x, y)
end