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.
This commit is contained in:
parent
14629a5346
commit
5d01769eb1
67
src/main.lua
67
src/main.lua
|
@ -64,11 +64,20 @@ end
|
|||
|
||||
local BallOffscreen <const> = 999
|
||||
|
||||
local PitchFlyMs <const> = 2500
|
||||
local PitchFlyMs <const> = 1000
|
||||
local PitchStartX <const> = 200
|
||||
local PitchStartY <const>, PitchEndY <const> = 90, 250
|
||||
local PitchStartY <const>, PitchEndY <const> = 90, 240
|
||||
|
||||
local PitchAnimator <const> = gfx.animator.new(PitchFlyMs, PitchStartY, PitchEndY, playdate.easingFunctions.outQuint)
|
||||
local PitchesX <const> = {
|
||||
-- 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 <const> = gfx.animator.new(PitchFlyMs, PitchStartY, PitchEndY, playdate.easingFunctions.linear)
|
||||
|
||||
local CrankOffsetDeg <const> = 90
|
||||
local BatOffset <const> = 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 <const> = {
|
|||
|
||||
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
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
local ScoreFont <const> = playdate.graphics.font.new("fonts/font-full-circle.pft")
|
||||
local OutBubbleRadius <const> = 5
|
||||
local ScoreboardMarginX <const> = 6
|
||||
local ScoreboardMarginRight <const> = 4
|
||||
local ScoreboardHeight <const> = 55
|
||||
local Indicator = "> "
|
||||
local IndicatorWidth <const> = 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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue