diff --git a/src/announcer.lua b/src/announcer.lua index df7018d..fda410d 100644 --- a/src/announcer.lua +++ b/src/announcer.lua @@ -44,6 +44,7 @@ function Announcer:popIn() end) end +---@param text string function Announcer:say(text) self.textQueue[#self.textQueue + 1] = text if #self.textQueue == 1 then diff --git a/src/assets.lua b/src/assets.lua index 2452ba1..1a9b8a6 100644 --- a/src/assets.lua +++ b/src/assets.lua @@ -8,6 +8,8 @@ Glove = playdate.graphics.image.new("images/game/Glove.png") -- luacheck: ignore PlayerFrown = playdate.graphics.image.new("images/game/PlayerFrown.png") -- luacheck: ignore +BigBat = playdate.graphics.image.new("images/game/BigBat.png") +-- luacheck: ignore GloveHoldingBall = playdate.graphics.image.new("images/game/GloveHoldingBall.png") -- luacheck: ignore GameLogo = playdate.graphics.image.new("images/game/GameLogo.png") diff --git a/src/constants.lua b/src/constants.lua index 177fbcd..d5100f1 100644 --- a/src/constants.lua +++ b/src/constants.lua @@ -125,6 +125,18 @@ C.WalkedRunnerSpeed = 10 C.ResetFieldersAfterSeconds = 2.5 +C.OutfieldWall = { + { x = 0, y = 137 }, + { x = 233, y = 32 }, + { x = 450, y = 29 }, + { x = 550, y = 59 }, + { x = 739, y = 64 }, + { x = 850, y = 19 }, + { x = 1100, y = 31 }, + { x = 1185, y = 181 }, + { x = 1201, y = 224 }, +} + if not playdate then return C end diff --git a/src/dbg.lua b/src/dbg.lua index 758c0b8..f92ffa6 100644 --- a/src/dbg.lua +++ b/src/dbg.lua @@ -35,8 +35,23 @@ function dbg.loadTheBases(br) br.runners[4].nextBase = C.Bases[C.Home] end +---@return BoxScoreData +function dbg.mockBoxScoreData(inningCount) + inningCount = inningCount or 9 + local data = { + home = {}, + away = {}, + } + for i = 1, inningCount do + data.home[i] = math.floor(math.random() * 5) + data.away[i] = math.floor(math.random() * 5) + end + return data +end + ---@param points XyPair[] function dbg.drawLine(points) + playdate.graphics.setColor(playdate.graphics.kColorWhite) for i = 2, #points do local prev = points[i - 1] local next = points[i] diff --git a/src/draw/box-score.lua b/src/draw/box-score.lua new file mode 100644 index 0000000..6fcd8e1 --- /dev/null +++ b/src/draw/box-score.lua @@ -0,0 +1,79 @@ +---@class BoxScore +---@field data BoxScoreData +BoxScore = {} + +---@param data BoxScoreData +function BoxScore.new(data) + return setmetatable({ + data = data, + }, { __index = BoxScore }) +end + +-- TODO: Convert the box-score into a whole "scene" +-- * Scroll left and right through games that go into extra innings +-- * Scroll up and down through other stats. +-- + Balls and strikes +-- + Batting average +-- + Graph of team scores over time +-- + Farthest hit ball + +local MarginY = 70 + +local ScoreFont = playdate.graphics.font.new("fonts/Asheville-Sans-14-Bold.pft") +local NumWidth = ScoreFont:getTextWidth("0") +local NumHeight = ScoreFont:getHeight() +local AwayWidth = ScoreFont:getTextWidth("AWAY") +local InningMargin = 4 + +local InningDrawWidth = (InningMargin * 2) + (NumWidth * 2) +local ScoreDrawHeight = NumHeight * 2 + +-- luacheck: ignore 143 +---@type pd_graphics_lib +local gfx = playdate.graphics + +local function formatScore(n) + if n <= 9 then + return " " .. n + elseif n <= 19 then + return " " .. n + else + return tostring(n) + end +end + +local HomeY = -4 + (NumHeight * 2) + MarginY +local AwayY = -4 + (NumHeight * 3) + MarginY + +local function drawInning(x, inningNumber, homeScore, awayScore) + gfx.setColor(gfx.kColorBlack) + gfx.setColor(gfx.kColorWhite) + gfx.setLineWidth(1) + gfx.drawRect(x, 34 + MarginY, InningDrawWidth, ScoreDrawHeight) + + inningNumber = " " .. inningNumber + homeScore = formatScore(homeScore) + awayScore = formatScore(awayScore) + + x = x - 8 + (InningDrawWidth / 2) + ScoreFont:drawTextAligned(inningNumber, x, -4 + NumHeight + MarginY, gfx.kAlignRight) + ScoreFont:drawTextAligned(awayScore, x, HomeY, gfx.kAlignRight) + ScoreFont:drawTextAligned(homeScore, x, AwayY, gfx.kAlignRight) +end + +function BoxScore:update() + local originalDrawMode = gfx.getImageDrawMode() + gfx.clear(gfx.kColorBlack) + gfx.setImageDrawMode(gfx.kDrawModeInverted) + gfx.setColor(gfx.kColorBlack) + local inningStart = 4 + (AwayWidth * 1.5) + local widthAndMarg = InningDrawWidth + 4 + ScoreFont:drawTextAligned(" HOME", 10, HomeY, gfx.kAlignRight) + ScoreFont:drawTextAligned("AWAY", 10, AwayY, gfx.kAlignRight) + for i = 1, #self.data.away do + drawInning(inningStart + ((i - 1) * widthAndMarg), i, self.data.home[i], self.data.away[i]) + end + local homeScore, awayScore = utils.totalScores(self.data) + drawInning(4 + inningStart + (widthAndMarg * #self.data.away), "F", homeScore, awayScore) + gfx.setImageDrawMode(originalDrawMode) +end diff --git a/src/draw/overlay.lua b/src/draw/overlay.lua index a1288db..cfa5c4a 100644 --- a/src/draw/overlay.lua +++ b/src/draw/overlay.lua @@ -83,11 +83,10 @@ local ScoreboardHeight = 55 local Indicator = "> " local IndicatorWidth = ScoreFont:getTextWidth(Indicator) ----@param teams any ---@param battingTeam any ---@return string, number, string, number -function getIndicators(teams, battingTeam) - if teams.home == battingTeam then +function getIndicators(battingTeam) + if battingTeam == "home" then return Indicator, 0, "", IndicatorWidth end return "", IndicatorWidth, Indicator, 0 @@ -101,11 +100,11 @@ local stats = { battingTeam = nil, } -function drawScoreboardImpl(x, y, teams) +function drawScoreboardImpl(x, y) local homeScore = stats.homeScore local awayScore = stats.awayScore - local homeIndicator, homeOffset, awayIndicator, awayOffset = getIndicators(teams, stats.battingTeam) + 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) @@ -146,17 +145,17 @@ end local newStats = stats -function drawScoreboard(x, y, teams, outs, battingTeam, inning) +function drawScoreboard(x, y, homeScore, awayScore, outs, battingTeam, inning) if - newStats.homeScore ~= teams.home.score - or newStats.awayScore ~= teams.away.score + newStats.homeScore ~= homeScore + or newStats.awayScore ~= awayScore or newStats.outs ~= outs or newStats.inning ~= inning or newStats.battingTeam ~= battingTeam then newStats = { - homeScore = teams.home.score, - awayScore = teams.away.score, + homeScore = homeScore, + awayScore = awayScore, outs = outs, inning = inning, battingTeam = battingTeam, @@ -165,5 +164,5 @@ function drawScoreboard(x, y, teams, outs, battingTeam, inning) stats = newStats end) end - drawScoreboardImpl(x, y, teams) + drawScoreboardImpl(x, y) end diff --git a/src/draw/transitions.lua b/src/draw/transitions.lua new file mode 100644 index 0000000..35d700c --- /dev/null +++ b/src/draw/transitions.lua @@ -0,0 +1,106 @@ +Transitions = { + ---@type Scene | nil + nextScene = nil, + ---@type Scene | nil + previousScene = nil, +} + +local gfx = playdate.graphics + +-- local function animateOut() end +-- local function animateIn() end + +local previousSceneImage +local previousSceneMask + +local nextSceneImage + +-- local nextSceneOffScreen = false +-- local stillAnimating = false + +-- TODO: Okay but like imagine. +-- Push a blank image context, +-- draw the previous scene on one side, +-- draw the next scene on the other, +-- SWING a bat to cover the seam. + +local batImageTable = {} + +local batOffset = 80 + +local degStep = 3 + +function loadBatImageTable() + for deg = 90 - (degStep * 3), 270 + (degStep * 3), degStep do + local img = gfx.image.new(C.Screen.W, C.Screen.H) + gfx.pushContext(img) + BigBat:drawRotated(C.Center.x, C.Screen.H + batOffset, 90 + deg) + gfx.popContext() + batImageTable[deg] = img + end +end +loadBatImageTable() + +local function update() + local lastAngle + local seamAngle = math.rad(270) + while seamAngle > math.rad(90) do + local deltaSeconds = playdate.getElapsedTime() + playdate.resetElapsedTime() + seamAngle = seamAngle - (deltaSeconds * 3) + local seamAngleDeg = math.floor(math.deg(seamAngle)) + seamAngleDeg = seamAngleDeg - (seamAngleDeg % degStep) + + -- Skip re-drawing if no change + if lastAngle ~= seamAngleDeg then + lastAngle = seamAngleDeg + nextSceneImage:draw(0, 0) + + gfx.pushContext(previousSceneMask) + gfx.setImageDrawMode(gfx.kDrawModeFillBlack) + batImageTable[seamAngleDeg]:draw(0, 0) + gfx.popContext() + + previousSceneImage:setMaskImage(previousSceneMask) + previousSceneImage:draw(0, 0) + batImageTable[seamAngleDeg]:draw(0, 0) + end + + coroutine.yield() + end + playdate.update = function() + Transitions.nextScene:update() + end +end + +---@param nextScene fun() The next playdate.update function +function transitionTo(nextScene) + if not Transitions.nextScene then + error("Expected Transitions to already have nextScene defined! E.g. by calling transitionBetween") + end + local previousScene = Transitions.nextScene + transitionBetween(previousScene, nextScene) +end + +---@param previousScene Scene Has the current playdate.update function +---@param nextScene Scene Has the next playdate.update function +function transitionBetween(previousScene, nextScene) + playdate.wait(2) -- TODO: There's some sort of timing wack here. + playdate.update = update + + previousSceneImage = gfx.image.new(C.Screen.W, C.Screen.H) + gfx.pushContext(previousSceneImage) + previousScene:update() + gfx.popContext() + + nextSceneImage = gfx.image.new(C.Screen.W, C.Screen.H) + gfx.pushContext(nextSceneImage) + nextScene:update() + gfx.popContext() + + previousSceneMask = gfx.image.new(C.Screen.W, C.Screen.H, gfx.kColorWhite) + previousSceneImage:setMaskImage(previousSceneMask) + + Transitions.nextScene = nextScene + Transitions.previousScene = previousScene +end diff --git a/src/fielding.lua b/src/fielding.lua index e755987..6587e10 100644 --- a/src/fielding.lua +++ b/src/fielding.lua @@ -182,7 +182,7 @@ function Fielding:userThrowTo(targetBase, ball, throwFlyMs) end) end -function Fielding:celebrate() +function Fielding.celebrate() FielderDanceAnimator:reset(C.DanceBounceMs) end diff --git a/src/fonts/Asheville-Sans-14-Bold-table-20-20.png b/src/fonts/Asheville-Sans-14-Bold-table-20-20.png new file mode 100755 index 0000000..2b3c6a8 Binary files /dev/null and b/src/fonts/Asheville-Sans-14-Bold-table-20-20.png differ diff --git a/src/fonts/Asheville-Sans-14-Bold.fnt b/src/fonts/Asheville-Sans-14-Bold.fnt new file mode 100755 index 0000000..3ee7fa3 --- /dev/null +++ b/src/fonts/Asheville-Sans-14-Bold.fnt @@ -0,0 +1,295 @@ +tracking=1 +space 3 +! 2 +" 5 +# 9 +$ 8 +% 12 +& 11 +' 3 +( 5 +) 5 +* 8 ++ 8 +, 3 +- 6 +. 2 +/ 6 +0 9 +1 4 +2 9 +3 9 +4 9 +5 9 +6 9 +7 9 +8 10 +9 9 +: 2 +; 2 +< 7 += 7 +> 7 +? 9 +@ 11 +A 10 +B 9 +C 9 +D 9 +E 8 +F 8 +G 9 +H 9 +I 2 +J 8 +K 10 +L 9 +M 12 +N 9 +O 9 +P 9 +Q 9 +R 9 +S 9 +T 10 +U 9 +V 10 +W 14 +X 8 +Y 8 +Z 8 +[ 3 +\ 6 +] 3 +^ 6 +_ 8 +` 3 +a 8 +b 8 +c 8 +d 8 +e 8 +f 6 +g 8 +h 8 +i 2 +j 4 +k 8 +l 2 +m 12 +n 8 +o 8 +p 8 +q 8 +r 6 +s 8 +t 6 +u 8 +v 8 +w 12 +x 9 +y 8 +z 8 +{ 6 +| 2 +} 6 +~ 10 +… 8 +¥ 8 +‼ 5 +™ 8 +© 11 +® 11 +。 16 +、 16 +ぁ 16 +あ 16 +ぃ 16 +い 16 +ぅ 16 +う 16 +ぇ 16 +え 16 +ぉ 16 +お 16 +か 16 +が 16 +き 16 +ぎ 16 +く 16 +ぐ 16 +け 16 +げ 16 +こ 16 +ご 16 +さ 16 +ざ 16 +し 16 +じ 16 +す 16 +ず 16 +せ 16 +ぜ 16 +そ 16 +ぞ 16 +た 16 +だ 16 +ち 16 +ぢ 16 +っ 16 +つ 16 +づ 16 +て 16 +で 16 +と 16 +ど 16 +な 16 +に 16 +ぬ 16 +ね 16 +の 16 +は 16 +ば 16 +ぱ 16 +ひ 16 +び 16 +ぴ 16 +ふ 16 +ぶ 16 +ぷ 16 +へ 16 +べ 16 +ぺ 16 +ほ 16 +ぼ 16 +ぽ 16 +ま 16 +み 16 +む 16 +め 16 +も 16 +ゃ 16 +や 16 +ゅ 16 +ゆ 16 +ょ 16 +よ 16 +ら 16 +り 16 +る 16 +れ 16 +ろ 16 +ゎ 16 +わ 16 +ゐ 16 +ゑ 16 +を 16 +ん 16 +ゔ 16 +ゕ 16 +ゖ 16 +゛ 1 +゜ 0 +ゝ 16 +ゞ 16 +ゟ 16 +゠ 16 +ァ 16 +ア 16 +ィ 16 +イ 16 +ゥ 16 +ウ 16 +ェ 16 +エ 16 +ォ 16 +オ 16 +カ 16 +ガ 16 +キ 16 +ギ 16 +ク 16 +グ 16 +ケ 16 +ゲ 16 +コ 16 +ゴ 16 +サ 16 +ザ 16 +シ 16 +ジ 16 +ス 16 +ズ 16 +セ 16 +ゼ 16 +ソ 16 +ゾ 16 +タ 16 +ダ 16 +チ 16 +ヂ 16 +ッ 16 +ツ 16 +ヅ 16 +テ 16 +デ 16 +ト 16 +ド 16 +ナ 16 +ニ 16 +ヌ 16 +ネ 16 +ノ 16 +ハ 16 +バ 16 +パ 16 +ヒ 16 +ビ 16 +ピ 16 +フ 16 +ブ 16 +プ 16 +ヘ 16 +ベ 16 +ペ 16 +ホ 16 +ボ 16 +ポ 16 +マ 16 +ミ 16 +ム 16 +メ 16 +モ 16 +ャ 16 +ヤ 16 +ュ 16 +ユ 16 +ョ 16 +ヨ 16 +ラ 16 +リ 16 +ル 16 +レ 16 +ロ 16 +ヮ 16 +ワ 16 +ヰ 16 +ヱ 16 +ヲ 16 +ン 16 +ヴ 16 +ヵ 16 +ヶ 16 +ヷ 16 +ヸ 16 +ヹ 16 +ヺ 16 +・ 16 +ー 16 +ヽ 16 +ヾ 16 +ヿ 16 +「 16 +」 16 +円 16 +� 13 \ No newline at end of file diff --git a/src/fonts/Roobert-20-Medium-table-32-32.png b/src/fonts/Roobert-20-Medium-table-32-32.png index 0e7b41b..fad1a25 100644 Binary files a/src/fonts/Roobert-20-Medium-table-32-32.png and b/src/fonts/Roobert-20-Medium-table-32-32.png differ diff --git a/src/images/game/BigBat.png b/src/images/game/BigBat.png new file mode 100644 index 0000000..038da28 Binary files /dev/null and b/src/images/game/BigBat.png differ diff --git a/src/images/game/GrassBackground.png b/src/images/game/GrassBackground.png index a33353f..b01de02 100644 Binary files a/src/images/game/GrassBackground.png and b/src/images/game/GrassBackground.png differ diff --git a/src/main-menu.lua b/src/main-menu.lua index f0afb97..4a21e2c 100644 --- a/src/main-menu.lua +++ b/src/main-menu.lua @@ -24,9 +24,7 @@ local function startGame() awayTeamSprites = AwayTeamSprites, }) playdate.resetElapsedTime() - playdate.update = function() - next:update() - end + transitionBetween(MainMenu, next) end local function pausingEaser(baseEaser) @@ -64,9 +62,10 @@ local function arrayElementFromCrank(array, crankPosition) return array[i] end -local currentLogo = nil +local currentLogo -function MainMenu.update() +--luacheck: ignore +function MainMenu:update() playdate.timer.updateTimers() crankStartPos = crankStartPos or playdate.getCrankPosition() diff --git a/src/main.lua b/src/main.lua index 268012c..64c37eb 100644 --- a/src/main.lua +++ b/src/main.lua @@ -8,6 +8,8 @@ import 'CoreLibs/timer.lua' import 'CoreLibs/ui.lua' -- stylua: ignore end +--- @alias Scene { update: fun(self: self) } + --- @alias EasingFunc fun(number, number, number, number): number --- @alias LaunchBall fun( @@ -24,9 +26,11 @@ import 'CoreLibs/ui.lua' import 'utils.lua' import 'constants.lua' import 'assets.lua' -import 'draw/player.lua' -import 'draw/overlay.lua' +import 'draw/box-score.lua' import 'draw/fielder.lua' +import 'draw/overlay.lua' +import 'draw/player.lua' +import 'draw/transitions.lua' import 'main-menu.lua' @@ -44,19 +48,18 @@ import 'npc.lua' local gfx , C = playdate.graphics, C ----@alias Team { score: number, benchPosition: XyPair } +---@alias Team { benchPosition: XyPair } ---@type table local teams = { home = { - score = 0, -- TODO: Extract this last bit of global mutable state. benchPosition = utils.xy(C.Screen.W + 10, C.Center.y), }, away = { - score = 0, benchPosition = utils.xy(-10, C.Center.y), }, } +---@alias BoxScoreData table ---@alias TeamId 'home' | 'away' --- Well, maybe not "Settings", but passive state that probably won't change much, if at all, during a game. @@ -73,6 +76,7 @@ local teams = { ---@field catcherThrownBall boolean ---@field offenseState OffenseState ---@field inning number +---@field boxScore BoxScoreData ---@field batBase XyPair ---@field batTip XyPair ---@field batAngleDeg number @@ -104,8 +108,6 @@ Game = {} ---@param state MutableState | nil ---@return Game function Game.new(settings, announcer, fielding, baserunning, npc, state) - teams.away.score = 0 - teams.home.score = 0 announcer = announcer or Announcer.new() fielding = fielding or Fielding.new() settings.userTeam = nil -- "away" @@ -137,6 +139,10 @@ function Game.new(settings, announcer, fielding, baserunning, npc, state) battingTeamSprites = settings.awayTeamSprites, fieldingTeamSprites = settings.homeTeamSprites, runnerBlipper = runnerBlipper, + boxScore = { + home = { 0 }, + away = { 0 }, + }, }, }, { __index = Game }) @@ -210,10 +216,6 @@ local function getOppositeTeamId(teamId) end end -function Game:getBattingTeam() - return teams[self.state.battingTeam] or error("Unknown battingTeam: " .. (self.state.battingTeam or "nil")) -end - function Game:getFieldingTeam() return teams[getOppositeTeamId(self.state.battingTeam)] end @@ -265,40 +267,49 @@ end function Game:nextHalfInning() pitchTracker:reset() - local gameOver = self.state.inning == self.settings.finalInning and teams.away.score ~= teams.home.score - if not gameOver then - self.fielding:celebrate() - self.state.secondsSinceLastRunnerMove = -7 - self.fielding:benchTo(self:getFieldingTeam().benchPosition) - self.announcer:say("SWITCHING SIDES...") - end + local homeScore, awayScore = utils.totalScores(self.state.boxScore) + local gameOver = self.state.battingTeam == "home" + and self.state.inning == self.settings.finalInning + and awayScore ~= homeScore if gameOver then self.announcer:say("AND THAT'S THE BALL GAME!") - else - self.fielding:resetFielderPositions() - if self.state.battingTeam == teams.home then - self.state.inning = self.state.inning + 1 - end - self.state.battingTeam = getOppositeTeamId(self.state.battingTeam) - playdate.timer.new(2000, function() - if self.state.battingTeam == teams.home then - self.state.battingTeamSprites = self.settings.homeTeamSprites - self.state.runnerBlipper = self.homeTeamBlipper - self.state.fieldingTeamSprites = self.settings.awayTeamSprites - else - self.state.battingTeamSprites = self.settings.awayTeamSprites - self.state.fieldingTeamSprites = self.settings.homeTeamSprites - self.state.runnerBlipper = self.awayTeamBlipper - end + playdate.timer.new(3000, function() + transitionTo(BoxScore.new(self.state.boxScore)) end) + return end + + Fielding.celebrate() + self.state.secondsSinceLastRunnerMove = -7 + self.fielding:benchTo(self:getFieldingTeam().benchPosition) + self.announcer:say("SWITCHING SIDES...") + + self.fielding:resetFielderPositions() + if self.state.battingTeam == "home" then + self.state.inning = self.state.inning + 1 + self.state.boxScore.home[self.state.inning] = 0 + self.state.boxScore.away[self.state.inning] = 0 + end + self.state.battingTeam = getOppositeTeamId(self.state.battingTeam) + playdate.timer.new(2000, function() + if self.state.battingTeam == "home" then + self.state.battingTeamSprites = self.settings.homeTeamSprites + self.state.runnerBlipper = self.homeTeamBlipper + self.state.fieldingTeamSprites = self.settings.awayTeamSprites + else + self.state.battingTeamSprites = self.settings.awayTeamSprites + self.state.fieldingTeamSprites = self.settings.homeTeamSprites + self.state.runnerBlipper = self.awayTeamBlipper + end + end) end ---@param scoredRunCount number function Game:score(scoredRunCount) - local batting = self:getBattingTeam() - batting.score = batting.score + scoredRunCount + local battingTeamBoxScore = self.state.boxScore[self.state.battingTeam] + battingTeamBoxScore[self.state.inning] = battingTeamBoxScore[self.state.inning] + scoredRunCount + self.announcer:say("SCORE!") end @@ -513,7 +524,8 @@ function Game:updateGameState() if self.state.secondsSinceLastRunnerMove > C.ResetFieldersAfterSeconds then -- End of play. Throw the ball back to the pitcher self.state.ball:launch(C.PitchStartX, C.PitchStartY, playdate.easingFunctions.linear, nil, true) - self.fielding:markAllIneligible() -- This is ugly, and ideally would not be necessary if Fielding handled the return throw directly. + -- This is ugly, and ideally would not be necessary if Fielding handled the return throw directly. + self.fielding:markAllIneligible() self.fielding:resetFielderPositions() self.state.offenseState = C.Offense.batting -- TODO: Remove, or replace with nextBatter() @@ -629,11 +641,21 @@ function Game:update() if math.abs(offsetX) > 10 or math.abs(offsetY) > 10 then drawMinimap(self.baserunning.runners, self.fielding.fielders) end - drawScoreboard(0, C.Screen.H * 0.77, teams, self.baserunning.outs, self:getBattingTeam(), self.state.inning) + local homeScore, awayScore = utils.totalScores(self.state.boxScore) + drawScoreboard( + 0, + C.Screen.H * 0.77, + homeScore, + awayScore, + self.baserunning.outs, + self.state.battingTeam, + self.state.inning + ) drawBallsAndStrikes(290, C.Screen.H - 20, pitchTracker.balls, pitchTracker.strikes) self.announcer:draw(C.Center.x, 10) if playdate.isCrankDocked() then + -- luacheck: ignore playdate.ui.crankIndicator:draw() end end diff --git a/src/npc.lua b/src/npc.lua index 812be91..e5148e6 100644 --- a/src/npc.lua +++ b/src/npc.lua @@ -22,6 +22,7 @@ end ---@param catcherThrownBall boolean ---@param deltaSec number ---@return number +-- luacheck: no unused function Npc:updateBatAngle(ball, catcherThrownBall, deltaSec) if not catcherThrownBall and ball.y > 200 and ball.y < 230 and (ball.x < C.Center.x + 15) then npcBatDeg = npcBatDeg + (deltaSec * npcBatSpeed) diff --git a/src/utils.lua b/src/utils.lua index 589fbaf..7f55c63 100644 --- a/src/utils.lua +++ b/src/utils.lua @@ -232,6 +232,22 @@ function utils.getNearestOf(array, x, y, extraCondition) return nearest, nearestDistance end +---@param box BoxScore +---@return number homeScore, number awayScore +function utils.totalScores(box) + local homeScore = 0 + for _, score in pairs(box.home) do + homeScore = homeScore + score + end + + local awayScore = 0 + for _, score in pairs(box.away) do + awayScore = awayScore + score + end + + return homeScore, awayScore +end + PitchOutcomes = { StrikeOut = {}, Walk = {},