169 lines
5.7 KiB
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
|