From 5d01769eb12083aaac7815d8f7f8dfe317e167e3 Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt Date: Mon, 3 Feb 2025 18:57:45 -0500 Subject: [PATCH] Multiple pitches. Track innings. Have catcher throw ball back to pitcher. NOTE: Bit of a timer hack in init() to get the ball to the pitcher at the beginning of the game. --- src/main.lua | 67 ++++++++++++++++++++++++++++++++++++---------- src/scoreboard.lua | 10 +++++-- 2 files changed, 61 insertions(+), 16 deletions(-) diff --git a/src/main.lua b/src/main.lua index 5277f2c..0282181 100644 --- a/src/main.lua +++ b/src/main.lua @@ -64,11 +64,20 @@ end local BallOffscreen = 999 -local PitchFlyMs = 2500 +local PitchFlyMs = 1000 local PitchStartX = 200 -local PitchStartY , PitchEndY = 90, 250 +local PitchStartY , PitchEndY = 90, 240 -local PitchAnimator = gfx.animator.new(PitchFlyMs, PitchStartY, PitchEndY, playdate.easingFunctions.outQuint) +local PitchesX = { + -- Fastball + gfx.animator.new(0, PitchStartX, PitchStartX, playdate.easingFunctions.linear), + -- Slider + gfx.animator.new(PitchFlyMs, PitchStartX - 20, PitchStartX, easingHill), + -- Curve ball + gfx.animator.new(PitchFlyMs, PitchStartX + 20, PitchStartX, easingHill), +} + +local PitchAnimatorY = gfx.animator.new(PitchFlyMs, PitchStartY, PitchEndY, playdate.easingFunctions.linear) local CrankOffsetDeg = 90 local BatOffset = xy(10, 25) @@ -211,15 +220,21 @@ function throwBall(destX, destY, easingFunc, flyTimeMs, floaty) end end -local PitchAfterSeconds = 5 +local PitchAfterSeconds = 7 -- TODO: Replace with a timer, repeatedly reset instead of setting to 0 local secondsSincePitchAllowed = -5 +local catcherThrownBall = false + function pitch() + catcherThrownBall = false currentMode = Modes.batting - ballAnimatorX = gfx.animator.new(0, PitchStartX, PitchStartX, playdate.easingFunctions.linear) - ballAnimatorY = PitchAnimator - PitchAnimator:reset() + ballAnimatorX = PitchesX[math.random(#PitchesX)] + ballAnimatorY = PitchAnimatorY + + ballAnimatorX:reset() + ballAnimatorY:reset() + secondsSincePitchAllowed = 0 end @@ -256,6 +271,7 @@ local teams = { local battingTeam = teams.away local outs = 0 +local inning = 1 ---@param base Base ---@return Runner | nil @@ -293,12 +309,26 @@ function outRunner(runnerIndex) updateForcedRunners() announcer:say("YOU'RE OUT!") if outs == 3 then - outs = 0 - announcer:say("SWITCHING SIDES...") + local gameOver = inning == 9 and teams.away.score ~= teams.home.score + if not gameOver then + announcer:say("SWITCHING SIDES...") + end while #runners > 0 do outRunners[#outRunners + 1] = table.remove(runners, #runners) end - battingTeam = battingTeam == teams.home and teams.away or teams.home + -- Delay to keep end-of-inning on the scoreboard for a few seconds + playdate.timer.new(3000, function() + outs = 0 + if battingTeam == teams.home then + battingTeam = teams.away + inning = inning + 1 + else + battingTeam = teams.home + end + if gameOver then + announcer:say("AND THAT'S THE BALL GAME!") + end + end) end end @@ -333,11 +363,12 @@ function updateFielders() end if currentMode == Modes.running and isTouchingBall(fielder.x, fielder.y) then + -- TODO: Check for double-plays or other available outs. local touchedBase = isTouchingBase(fielder.x, fielder.y) for i, runner in pairs(runners) do if touchedBase - and runner.prevBase -- Check if the runner is standing at home + and runner.prevBase -- Make sure the runner is not standing at home and runner.forcedTo == touchedBase and touchedBase ~= touchingBaseCache.get(runner) then @@ -454,7 +485,7 @@ function getNextThrowTarget() end end -local ResetFieldersAfterSeconds = 4 +local ResetFieldersAfterSeconds = 2 -- TODO: Replace with a timer, repeatedly reset instead of setting to 0 local secondsSinceLastRunnerMove = 0 @@ -464,6 +495,10 @@ function init() playdate.setMenuImage(gfx.image.new("images/game/menu-image.png")) resetFielderPositions(true) playdate.getSystemMenu():addMenuItem("Restart game", function() end) + + playdate.timer.new(2000, function() + throwBall(PitchStartX, PitchStartY, playdate.easingFunctions.linear, nil, false) + end) end function tryToThrowOut(self) @@ -527,7 +562,7 @@ function updateBatting() end function updateRunning() - local nonBatterRunners = filter(runners, function (runner) + local nonBatterRunners = filter(runners, function(runner) return runner ~= batter end) ball.size = ballSizeAnimator:currentValue() @@ -571,6 +606,10 @@ function updateGameState() if currentMode == Modes.batting then secondsSincePitchAllowed = secondsSincePitchAllowed + deltaSeconds + if secondsSincePitchAllowed > 3.5 and not catcherThrownBall then + throwBall(PitchStartX, PitchStartY, playdate.easingFunctions.linear, nil, true) + catcherThrownBall = true + end if secondsSincePitchAllowed > PitchAfterSeconds then pitch() end @@ -629,7 +668,7 @@ function playdate.update() end gfx.setDrawOffset(0, 0) - drawScoreboard(0, Screen.H * 0.77, teams, outs, battingTeam) + drawScoreboard(0, Screen.H * 0.77, teams, outs, battingTeam, inning) announcer:draw(Center.x, 10) end diff --git a/src/scoreboard.lua b/src/scoreboard.lua index 83bbd85..3c035cc 100644 --- a/src/scoreboard.lua +++ b/src/scoreboard.lua @@ -1,6 +1,7 @@ local ScoreFont = playdate.graphics.font.new("fonts/font-full-circle.pft") local OutBubbleRadius = 5 local ScoreboardMarginX = 6 +local ScoreboardMarginRight = 4 local ScoreboardHeight = 55 local Indicator = "> " local IndicatorWidth = ScoreFont:getTextWidth(Indicator) @@ -15,7 +16,7 @@ function getIndicators(teams, battingTeam) return "", IndicatorWidth, Indicator, 0 end -function drawScoreboard(x, y, teams, outs, battingTeam) +function drawScoreboard(x, y, teams, outs, battingTeam, inning) local gfx = playdate.graphics local homeScore = teams.home.score @@ -26,7 +27,10 @@ function drawScoreboard(x, y, teams, outs, 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) + ScoreFont:getTextWidth(homeScoreText) + homeOffset + local rectWidth = (ScoreboardMarginX * 2) + + ScoreboardMarginRight + + ScoreFont:getTextWidth(homeScoreText) + + homeOffset gfx.setLineWidth(1) gfx.setColor(gfx.kColorBlack) @@ -37,6 +41,8 @@ function drawScoreboard(x, y, teams, outs, battingTeam) 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(inning, inningOffsetX, y + 39) gfx.setImageDrawMode(originalDrawMode)