Add basic home-run handling
Still needs to pan the camera back from the home run while the runners circle the bases. Also add a wrapping-pattern.png, though I'm not sure if it's actually used?
This commit is contained in:
parent
1bdcc62347
commit
2d812f2046
|
@ -16,7 +16,8 @@
|
|||
---@field onThirdOut fun()
|
||||
Baserunning = {}
|
||||
|
||||
-- TODO: Implement slides. Would require making fielders' gloves "real objects" whose state is tracked.
|
||||
-- TODO: Implement slides? Would require making fielders' gloves "real objects" whose state is tracked.
|
||||
-- TODO: Don't allow runners to occupy the same base!
|
||||
|
||||
---@param announcer Announcer
|
||||
---@return Baserunning
|
||||
|
|
|
@ -98,6 +98,7 @@ C.Offense = {
|
|||
batting = "batting",
|
||||
running = "running",
|
||||
walking = "walking",
|
||||
homeRun = "homeRun",
|
||||
}
|
||||
|
||||
---@alias Side "offense" | "defense"
|
||||
|
@ -124,17 +125,23 @@ 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 },
|
||||
{ x = -400, y = -103 },
|
||||
{ x = -167, y = -208 },
|
||||
{ x = 50, y = -211 },
|
||||
{ x = 150, y = -181 },
|
||||
{ x = 339, y = -176 },
|
||||
{ x = 450, y = -221 },
|
||||
{ x = 700, y = -209 },
|
||||
{ x = 785, y = -59 },
|
||||
{ x = 801, y = -16 },
|
||||
}
|
||||
|
||||
C.BottomOfOutfieldWall = {}
|
||||
|
||||
for i, v in ipairs(C.OutfieldWall) do
|
||||
C.BottomOfOutfieldWall[i] = utils.xy(v.x, v.y + 40)
|
||||
end
|
||||
|
||||
if not playdate then
|
||||
return C
|
||||
end
|
||||
|
|
|
@ -80,7 +80,10 @@ end
|
|||
---@return boolean inCatchingRange
|
||||
local function updateFielderPosition(deltaSeconds, fielder, ballPos)
|
||||
if fielder.target ~= nil then
|
||||
if not utils.moveAtSpeed(fielder, fielder.speed * deltaSeconds, fielder.target) then
|
||||
if
|
||||
utils.pointIsSquarelyAboveLine(fielder, C.BottomOfOutfieldWall)
|
||||
or not utils.moveAtSpeed(fielder, fielder.speed * deltaSeconds, fielder.target)
|
||||
then
|
||||
fielder.target = nil
|
||||
end
|
||||
end
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
33
src/main.lua
33
src/main.lua
|
@ -416,8 +416,7 @@ function Game:updateBatting(batDeg, batSpeed)
|
|||
local ballDestX = self.state.ball.x + (ballVelX * C.BattingPower)
|
||||
local ballDestY = self.state.ball.y + (ballVelY * C.BattingPower)
|
||||
pitchTracker:reset()
|
||||
local hitBallScaler = gfx.animator.new(2000, 9 + (mult * mult * 0.5), C.SmallestBallRadius, utils.easingHill)
|
||||
self.state.ball:launch(ballDestX, ballDestY, playdate.easingFunctions.outQuint, 2000, nil, hitBallScaler)
|
||||
local flyTimeMs = 2000
|
||||
-- TODO? A dramatic eye-level view on a home-run could be sick.
|
||||
local battingTeamStats = self:battingTeamCurrentInning()
|
||||
battingTeamStats.hits[#battingTeamStats.hits + 1] = utils.xy(ballDestX, ballDestY)
|
||||
|
@ -428,8 +427,21 @@ function Game:updateBatting(batDeg, batSpeed)
|
|||
-- TODO: Have a fielder chase for the fly-out
|
||||
return
|
||||
end
|
||||
self.baserunning:convertBatterToRunner()
|
||||
|
||||
if utils.pointIsSquarelyAboveLine(utils.xy(ballDestX, ballDestY), C.OutfieldWall) then
|
||||
playdate.timer.new(flyTimeMs, function()
|
||||
-- Verify that the home run wasn't intercepted
|
||||
if utils.within(1, self.state.ball.x, ballDestX) and utils.within(1, self.state.ball.y, ballDestY) then
|
||||
self.announcer:say("HOME RUN!")
|
||||
self.state.offenseState = C.Offense.homeRun
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local hitBallScaler = gfx.animator.new(2000, 9 + (mult * mult * 0.5), C.SmallestBallRadius, utils.easingHill)
|
||||
self.state.ball:launch(ballDestX, ballDestY, playdate.easingFunctions.outQuint, flyTimeMs, nil, hitBallScaler)
|
||||
|
||||
self.baserunning:convertBatterToRunner()
|
||||
self.fielding:haveSomeoneChase(ballDestX, ballDestY)
|
||||
end
|
||||
end
|
||||
|
@ -490,14 +502,7 @@ function Game:updateGameState()
|
|||
end
|
||||
|
||||
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
|
||||
end
|
||||
if outcome == PitchOutcomes.Ball or outcome == PitchOutcomes.Walk then
|
||||
currentPitchingStats.balls = currentPitchingStats.balls + 1
|
||||
end
|
||||
local outcome = pitchTracker:updatePitchCounts(self.state.didSwing, self:fieldingTeamCurrentInning())
|
||||
if outcome == PitchOutcomes.StrikeOut then
|
||||
self:strikeOut()
|
||||
elseif outcome == PitchOutcomes.Walk then
|
||||
|
@ -560,6 +565,12 @@ function Game:updateGameState()
|
|||
if not self:updateNonBatterRunners(C.WalkedRunnerSpeed, true) then
|
||||
self.state.offenseState = C.Offense.batting
|
||||
end
|
||||
elseif self.state.offenseState == C.Offense.homeRun then
|
||||
self:updateNonBatterRunners(C.WalkedRunnerSpeed * 3, false)
|
||||
if #self.baserunning.runners == 0 then
|
||||
self.state.offenseState = C.Offense.batting
|
||||
self.baserunning:pushNewBatter()
|
||||
end
|
||||
end
|
||||
|
||||
local fielderHoldingBall = self.fielding:updateFielderPositions(self.state.ball, self.state.deltaSeconds)
|
||||
|
|
|
@ -83,6 +83,10 @@ function utils.moveAtSpeed(mover, speed, target)
|
|||
return false
|
||||
end
|
||||
|
||||
function utils.within(within, n1, n2)
|
||||
return math.abs(n1 - n2) < within
|
||||
end
|
||||
|
||||
---@generic T
|
||||
---@param array T[]
|
||||
---@param condition fun(T): boolean
|
||||
|
@ -266,19 +270,24 @@ pitchTracker = {
|
|||
end,
|
||||
|
||||
---@param didSwing boolean
|
||||
updatePitchCounts = function(self, didSwing)
|
||||
---@param fieldingTeamInningData TeamInningData
|
||||
updatePitchCounts = function(self, didSwing, fieldingTeamInningData)
|
||||
if not self.recordedPitchX then
|
||||
return
|
||||
end
|
||||
|
||||
local currentPitchingStats = fieldingTeamInningData.pitching
|
||||
|
||||
if didSwing or self.recordedPitchX > C.StrikeZoneStartX and self.recordedPitchX < C.StrikeZoneEndX then
|
||||
self.strikes = self.strikes + 1
|
||||
currentPitchingStats.strikes = currentPitchingStats.strikes + 1
|
||||
if self.strikes >= 3 then
|
||||
self:reset()
|
||||
return PitchOutcomes.StrikeOut
|
||||
end
|
||||
else
|
||||
self.balls = self.balls + 1
|
||||
currentPitchingStats.balls = currentPitchingStats.balls + 1
|
||||
if self.balls >= 4 then
|
||||
self:reset()
|
||||
return PitchOutcomes.Walk
|
||||
|
|
Loading…
Reference in New Issue