Add swing-and-a-miss strikes

This commit is contained in:
Sage Vaillancourt 2025-02-17 20:37:16 -05:00
parent 4c9fbcdee7
commit e20ad0d3ad
3 changed files with 24 additions and 14 deletions

View File

@ -72,7 +72,8 @@ local teams <const> = {
---@field deltaSeconds number
---@field ball Ball
---@field battingTeam TeamId
---@field catcherThrownBall boolean
---@field pitchIsOver boolean
---@field didSwing boolean
---@field offenseState OffenseState
---@field inning number
---@field stats Statistics
@ -109,7 +110,7 @@ Game = {}
function Game.new(settings, announcer, fielding, baserunning, npc, state)
announcer = announcer or Announcer.new()
fielding = fielding or Fielding.new()
settings.userTeam = nil -- "away"
settings.userTeam = "away"
local homeTeamBlipper = blipper.new(100, settings.homeTeamSprites.smiling, settings.homeTeamSprites.lowHat)
local awayTeamBlipper = blipper.new(100, settings.awayTeamSprites.smiling, settings.awayTeamSprites.lowHat)
@ -132,7 +133,8 @@ function Game.new(settings, announcer, fielding, baserunning, npc, state)
battingTeam = battingTeam,
offenseState = C.Offense.batting,
inning = 1,
catcherThrownBall = false,
pitchIsOver = false,
didSwing = false,
secondsSinceLastRunnerMove = 0,
secondsSincePitchAllowed = 0,
battingTeamSprites = settings.awayTeamSprites,
@ -237,7 +239,7 @@ end
function Game:pitch(pitchFlyTimeMs, pitchTypeIndex)
Fielding.markIneligible(self.fielding.fielders.pitcher)
self.state.ball.heldBy = nil
self.state.catcherThrownBall = false
self.state.pitchIsOver = false
self.state.offenseState = C.Offense.batting
local current = Pitches[pitchTypeIndex](self.state.ball)
@ -370,8 +372,14 @@ function Game:strikeOut()
self:nextBatter()
end
local SwingBackDeg <const> = 30
local SwingForwardDeg <const> = 170
---@param batDeg number
function Game:updateBatting(batDeg, batSpeed)
if not self.state.pitchIsOver and batDeg > SwingBackDeg and batDeg < SwingForwardDeg then
self.state.didSwing = true
end
local batAngle = math.rad(batDeg)
-- TODO: animate bat-flip or something
self.state.batBase.x = self.baserunning.batter and (self.baserunning.batter.x + C.BatterHandPos.x) or 0
@ -480,8 +488,8 @@ function Game:updateGameState()
self.state.secondsSincePitchAllowed = self.state.secondsSincePitchAllowed + self.state.deltaSeconds
end
if self.state.secondsSincePitchAllowed > C.ReturnToPitcherAfterSeconds and not self.state.catcherThrownBall then
local outcome = pitchTracker:updatePitchCounts()
if self.state.secondsSincePitchAllowed > C.ReturnToPitcherAfterSeconds and not self.state.pitchIsOver then
local outcome = pitchTracker:updatePitchCounts(self.state.didSwing)
local currentPitchingStats = self:fieldingTeamCurrentInning().pitching
if outcome == PitchOutcomes.Strike or outcome == PitchOutcomes.StrikeOut then
currentPitchingStats.strikes = currentPitchingStats.strikes + 1
@ -496,7 +504,8 @@ function Game:updateGameState()
end
-- Catcher has the ball. Throw it back to the pitcher
self.state.ball:launch(C.PitchStartX, C.PitchStartY, playdate.easingFunctions.linear, nil, true)
self.state.catcherThrownBall = true
self.state.pitchIsOver = true
self.state.didSwing = false
end
local batSpeed
@ -505,7 +514,7 @@ function Game:updateGameState()
batSpeed = crankLimited
else
self.state.batAngleDeg =
self.npc:updateBatAngle(self.state.ball, self.state.catcherThrownBall, self.state.deltaSeconds)
self.npc:updateBatAngle(self.state.ball, self.state.pitchIsOver, self.state.deltaSeconds)
batSpeed = self.npc:batSpeed() * self.state.deltaSeconds
end
@ -521,7 +530,7 @@ function Game:updateGameState()
self:userPitch(throwFly)
end
else
self:pitch(C.PitchFlyMs / self.npc:pitchSpeed(), math.random(#Pitches))
self:pitch(C.PitchFlyMs / self.npc:pitchSpeed(), 2)
end
end
elseif self.state.offenseState == C.Offense.running then

View File

@ -19,12 +19,12 @@ function Npc.new(runners, fielders)
end
---@param ball XyPair
---@param catcherThrownBall boolean
---@param pitchIsOver 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
function Npc:updateBatAngle(ball, pitchIsOver, deltaSec)
if not pitchIsOver and ball.y > 200 and ball.y < 230 and (ball.x < C.Center.x + 15) then
npcBatDeg = npcBatDeg + (deltaSec * npcBatSpeed)
else
npcBatSpeed = (1 + math.random()) * BaseNpcBatSpeed

View File

@ -265,12 +265,13 @@ pitchTracker = {
self.balls = 0
end,
updatePitchCounts = function(self)
---@param didSwing boolean
updatePitchCounts = function(self, didSwing)
if not self.recordedPitchX then
return
end
if self.recordedPitchX > C.StrikeZoneStartX and self.recordedPitchX < C.StrikeZoneEndX then
if didSwing or self.recordedPitchX > C.StrikeZoneStartX and self.recordedPitchX < C.StrikeZoneEndX then
self.strikes = self.strikes + 1
if self.strikes >= 3 then
self:reset()