parent
eb28a628f2
commit
4fc49d3631
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
90
src/main.lua
90
src/main.lua
|
@ -54,6 +54,7 @@ local BootTune <const> = playdate.sound.sampleplayer.new("sounds/boot-tune.wav")
|
||||||
local TinnyBackground <const> = playdate.sound.sampleplayer.new("sounds/tinny-background.wav")
|
local TinnyBackground <const> = playdate.sound.sampleplayer.new("sounds/tinny-background.wav")
|
||||||
local BatCrackSound <const> = playdate.sound.sampleplayer.new("sounds/bat-crack-reverb.wav")
|
local BatCrackSound <const> = playdate.sound.sampleplayer.new("sounds/bat-crack-reverb.wav")
|
||||||
local GrassBackground <const> = gfx.image.new("images/game/grass.png") --[[@as pd_image]]
|
local GrassBackground <const> = gfx.image.new("images/game/grass.png") --[[@as pd_image]]
|
||||||
|
local Minimap <const> = gfx.image.new("images/game/minimap.png") --[[@as pd_image]]
|
||||||
local PlayerFrown <const> = gfx.image.new("images/game/player-frown.png") --[[@as pd_image]]
|
local PlayerFrown <const> = gfx.image.new("images/game/player-frown.png") --[[@as pd_image]]
|
||||||
local PlayerSmile <const> = gfx.image.new("images/game/player.png") --[[@as pd_image]]
|
local PlayerSmile <const> = gfx.image.new("images/game/player.png") --[[@as pd_image]]
|
||||||
local PlayerBack <const> = gfx.image.new("images/game/player-back.png") --[[@as pd_image]]
|
local PlayerBack <const> = gfx.image.new("images/game/player-back.png") --[[@as pd_image]]
|
||||||
|
@ -327,7 +328,7 @@ function pitch(pitchFlyTimeMs, pitchTypeIndex)
|
||||||
catcherThrownBall = false
|
catcherThrownBall = false
|
||||||
offenseMode = Offense.batting
|
offenseMode = Offense.batting
|
||||||
|
|
||||||
local current = Pitches[pitchTypeIndex or math.random(#Pitches)]
|
local current = Pitches[pitchTypeIndex]
|
||||||
ballAnimatorX = current.x
|
ballAnimatorX = current.x
|
||||||
ballAnimatorY = current.y or Pitches[1].y
|
ballAnimatorY = current.y or Pitches[1].y
|
||||||
|
|
||||||
|
@ -355,13 +356,9 @@ local BaseHitbox = 10
|
||||||
---@param y number
|
---@param y number
|
||||||
---@return Base | nil
|
---@return Base | nil
|
||||||
function isTouchingBase(x, y)
|
function isTouchingBase(x, y)
|
||||||
for _, base in ipairs(Bases) do
|
return utils.first(Bases, function(base)
|
||||||
if utils.distanceBetween(x, y, base.x, base.y) < BaseHitbox then
|
return utils.distanceBetween(x, y, base.x, base.y) < BaseHitbox
|
||||||
return base
|
end)
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local BallCatchHitbox = 3
|
local BallCatchHitbox = 3
|
||||||
|
@ -377,19 +374,16 @@ end
|
||||||
|
|
||||||
---@param base Base
|
---@param base Base
|
||||||
---@return Runner | nil
|
---@return Runner | nil
|
||||||
function getRunnerTargeting(base)
|
function getRunnerWithNextBase(base)
|
||||||
for _, runner in pairs(runners) do
|
return utils.first(runners, function(runner)
|
||||||
if runner.nextBase == base then
|
return runner.nextBase == base
|
||||||
return runner
|
end)
|
||||||
end
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function updateForcedRunners()
|
function updateForcedRunners()
|
||||||
local stillForced = true
|
local stillForced = true
|
||||||
for _, base in ipairs(Bases) do
|
for _, base in ipairs(Bases) do
|
||||||
local runnerTargetingBase = getRunnerTargeting(base)
|
local runnerTargetingBase = getRunnerWithNextBase(base)
|
||||||
if runnerTargetingBase then
|
if runnerTargetingBase then
|
||||||
if stillForced then
|
if stillForced then
|
||||||
runnerTargetingBase.forcedTo = base
|
runnerTargetingBase.forcedTo = base
|
||||||
|
@ -453,7 +447,7 @@ end
|
||||||
function getForcedOutTargets()
|
function getForcedOutTargets()
|
||||||
local targets = {}
|
local targets = {}
|
||||||
for _, base in ipairs(Bases) do
|
for _, base in ipairs(Bases) do
|
||||||
local runnerTargetingBase = getRunnerTargeting(base)
|
local runnerTargetingBase = getRunnerWithNextBase(base)
|
||||||
if runnerTargetingBase then
|
if runnerTargetingBase then
|
||||||
targets[#targets + 1] = base
|
targets[#targets + 1] = base
|
||||||
else
|
else
|
||||||
|
@ -490,7 +484,6 @@ function getNextOutTarget()
|
||||||
end
|
end
|
||||||
|
|
||||||
local baseCloseToStrandedRunner = getBaseOfStrandedRunner()
|
local baseCloseToStrandedRunner = getBaseOfStrandedRunner()
|
||||||
-- TODO: If another fielder is closer, throw it to them, instead
|
|
||||||
if baseCloseToStrandedRunner then
|
if baseCloseToStrandedRunner then
|
||||||
return baseCloseToStrandedRunner.x, baseCloseToStrandedRunner.y
|
return baseCloseToStrandedRunner.x, baseCloseToStrandedRunner.y
|
||||||
end
|
end
|
||||||
|
@ -510,28 +503,10 @@ function tryToMakeAnOut(fielder)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Push the given obect at the given speed toward a target. Speed should be pre-multiplied by the frame's delta time.
|
|
||||||
--- Stops when within 1. Returns true only if the object did actually move.
|
|
||||||
---@param mover { x: number, y: number }
|
|
||||||
---@param speed number
|
|
||||||
---@param target { x: number, y: number }
|
|
||||||
---@return boolean
|
|
||||||
function moveAtSpeed(mover, speed, target)
|
|
||||||
local x, y, distance = utils.normalizeVector(mover.x, mover.y, target.x, target.y)
|
|
||||||
|
|
||||||
if distance > 1 then
|
|
||||||
mover.x = mover.x - (x * speed)
|
|
||||||
mover.y = mover.y - (y * speed)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param fielder Fielder
|
---@param fielder Fielder
|
||||||
function updateFielder(fielder)
|
function updateFielder(fielder)
|
||||||
if fielder.target ~= nil then
|
if fielder.target ~= nil then
|
||||||
if not moveAtSpeed(fielder, fielder.speed * deltaSeconds, fielder.target) then
|
if not utils.moveAtSpeed(fielder, fielder.speed * deltaSeconds, fielder.target) then
|
||||||
fielder.target = nil
|
fielder.target = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -540,7 +515,6 @@ function updateFielder(fielder)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: Check for double-plays or other available outs.
|
|
||||||
local touchedBase = isTouchingBase(fielder.x, fielder.y)
|
local touchedBase = isTouchingBase(fielder.x, fielder.y)
|
||||||
for i, runner in pairs(runners) do
|
for i, runner in pairs(runners) do
|
||||||
local runnerOnBase = isTouchingBase(runner.x, runner.y)
|
local runnerOnBase = isTouchingBase(runner.x, runner.y)
|
||||||
|
@ -570,7 +544,7 @@ function updateFielders()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- if offenseMode == Offense.batting then
|
-- if offenseMode == Offense.batting then
|
||||||
-- moveAtSpeed(
|
-- utils.moveAtSpeed(
|
||||||
-- fielders.catcher,
|
-- fielders.catcher,
|
||||||
-- fielders.catcher.speed * 2 * deltaSeconds,
|
-- fielders.catcher.speed * 2 * deltaSeconds,
|
||||||
-- { x = math.min(Center.x + 15, ball.x), y = fielders.catcher.y }
|
-- { x = math.min(Center.x + 15, ball.x), y = fielders.catcher.y }
|
||||||
|
@ -623,7 +597,6 @@ function updateRunner(runner, runnerIndex, appliedSpeed)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: Also move if forced to 😅
|
|
||||||
local autoRun = (nearestBaseDistance > 40 or runner.forcedTo) and mult * autoRunSpeed
|
local autoRun = (nearestBaseDistance > 40 or runner.forcedTo) and mult * autoRunSpeed
|
||||||
or nearestBaseDistance < 5 and 0
|
or nearestBaseDistance < 5 and 0
|
||||||
or (nearestBase == runner.nextBase and autoRunSpeed or -1 * autoRunSpeed)
|
or (nearestBase == runner.nextBase and autoRunSpeed or -1 * autoRunSpeed)
|
||||||
|
@ -698,16 +671,14 @@ end
|
||||||
function updateRunning(appliedSpeed)
|
function updateRunning(appliedSpeed)
|
||||||
ball.size = ballSizeAnimator:currentValue()
|
ball.size = ballSizeAnimator:currentValue()
|
||||||
|
|
||||||
local nonBatterRunners = utils.filter(runners, function(runner)
|
|
||||||
return runner ~= batter
|
|
||||||
end)
|
|
||||||
|
|
||||||
local runnerMoved = false
|
local runnerMoved = false
|
||||||
|
|
||||||
-- TODO: Filter for the runner closest to the currently-held direction button
|
-- TODO: Filter for the runner closest to the currently-held direction button
|
||||||
for runnerIndex, runner in ipairs(nonBatterRunners) do
|
for runnerIndex, runner in ipairs(runners) do
|
||||||
|
if runner ~= batter then
|
||||||
runnerMoved = updateRunner(runner, runnerIndex, appliedSpeed) or runnerMoved
|
runnerMoved = updateRunner(runner, runnerIndex, appliedSpeed) or runnerMoved
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return runnerMoved
|
return runnerMoved
|
||||||
end
|
end
|
||||||
|
@ -768,7 +739,7 @@ function buttonControlledThrow(thrower, throwFlyMs, forbidThrowHome)
|
||||||
if playdate.buttonIsPressed(playdate.kButtonLeft) then
|
if playdate.buttonIsPressed(playdate.kButtonLeft) then
|
||||||
targetBase = Bases[Third]
|
targetBase = Bases[Third]
|
||||||
elseif playdate.buttonIsPressed(playdate.kButtonUp) then
|
elseif playdate.buttonIsPressed(playdate.kButtonUp) then
|
||||||
targetBase = Bases[Second] -- TODO - or shortstop - whoever's closer
|
targetBase = Bases[Second]
|
||||||
elseif playdate.buttonIsPressed(playdate.kButtonRight) then
|
elseif playdate.buttonIsPressed(playdate.kButtonRight) then
|
||||||
targetBase = Bases[First]
|
targetBase = Bases[First]
|
||||||
elseif not forbidThrowHome and playdate.buttonIsPressed(playdate.kButtonDown) then
|
elseif not forbidThrowHome and playdate.buttonIsPressed(playdate.kButtonDown) then
|
||||||
|
@ -820,7 +791,7 @@ function updateGameState()
|
||||||
|
|
||||||
if secondsSincePitchAllowed > PitchAfterSeconds then
|
if secondsSincePitchAllowed > PitchAfterSeconds then
|
||||||
if playerOnOffense then
|
if playerOnOffense then
|
||||||
pitch(PitchFlyMs)
|
pitch(PitchFlyMs, math.random(#Pitches))
|
||||||
else
|
else
|
||||||
local throwFly = readThrow()
|
local throwFly = readThrow()
|
||||||
if throwFly and not buttonControlledThrow(fielders.pitcher, throwFly, true) then
|
if throwFly and not buttonControlledThrow(fielders.pitcher, throwFly, true) then
|
||||||
|
@ -864,8 +835,25 @@ function updateGameState()
|
||||||
walkAwayOutRunners()
|
walkAwayOutRunners()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO
|
local MinimapSizeX, MinimapSizeY <const> = Minimap:getSize()
|
||||||
function drawMinimap() end
|
local MinimapPosX, MinimapPosY = Screen.W - MinimapSizeX, Screen.H - MinimapSizeY
|
||||||
|
|
||||||
|
local FieldHeight <const> = Bases[Home].y - Bases[Second].y
|
||||||
|
|
||||||
|
local MinimapMultX <const> = 0.75 * MinimapSizeX / Screen.W
|
||||||
|
local MinimapOffsetX <const> = MinimapPosX + 5
|
||||||
|
local MinimapMultY <const> = 0.70 * MinimapSizeY / FieldHeight
|
||||||
|
local MinimapOffsetY <const> = MinimapPosY - 15
|
||||||
|
|
||||||
|
function drawMinimap()
|
||||||
|
Minimap:draw(MinimapPosX, MinimapPosY)
|
||||||
|
gfx.setColor(gfx.kColorBlack)
|
||||||
|
for _, runner in pairs(runners) do
|
||||||
|
local x = (MinimapMultX * runner.x) + MinimapOffsetX
|
||||||
|
local y = (MinimapMultY * runner.y) + MinimapOffsetY
|
||||||
|
gfx.fillRect(x, y, 8, 8)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
---@param fielder Fielder
|
---@param fielder Fielder
|
||||||
---@return boolean isHoldingBall
|
---@return boolean isHoldingBall
|
||||||
|
@ -916,7 +904,7 @@ function playdate.update()
|
||||||
playdate.ui.crankIndicator:draw()
|
playdate.ui.crankIndicator:draw()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO? Change blip speed depending on runner speed?
|
-- TODO? Scale sprites down as y increases
|
||||||
for _, runner in pairs(runners) do
|
for _, runner in pairs(runners) do
|
||||||
if runner == batter then
|
if runner == batter then
|
||||||
if batAngleDeg > 50 and batAngleDeg < 200 then
|
if batAngleDeg > 50 and batAngleDeg < 200 then
|
||||||
|
@ -925,7 +913,7 @@ function playdate.update()
|
||||||
PlayerSmile:draw(runner.x, runner.y)
|
PlayerSmile:draw(runner.x, runner.y)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- TODO? Scale sprites down as y increases
|
-- TODO? Change blip speed depending on runner speed?
|
||||||
PlayerImageBlipper:draw(false, runner.x, runner.y)
|
PlayerImageBlipper:draw(false, runner.x, runner.y)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -47,6 +47,24 @@ function utils.normalizeVector(x1, y1, x2, y2)
|
||||||
return x / distance, y / distance, distance
|
return x / distance, y / distance, distance
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Push the given obect at the given speed toward a target. Speed should be pre-multiplied by the frame's delta time.
|
||||||
|
--- Stops when within 1. Returns true only if the object did actually move.
|
||||||
|
---@param mover { x: number, y: number }
|
||||||
|
---@param speed number
|
||||||
|
---@param target { x: number, y: number }
|
||||||
|
---@return boolean
|
||||||
|
function utils.moveAtSpeed(mover, speed, target)
|
||||||
|
local x, y, distance = utils.normalizeVector(mover.x, mover.y, target.x, target.y)
|
||||||
|
|
||||||
|
if distance > 1 then
|
||||||
|
mover.x = mover.x - (x * speed)
|
||||||
|
mover.y = mover.y - (y * speed)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
---@generic T
|
---@generic T
|
||||||
---@param array T[]
|
---@param array T[]
|
||||||
---@param condition fun(T): boolean
|
---@param condition fun(T): boolean
|
||||||
|
@ -61,6 +79,19 @@ function utils.filter(array, condition)
|
||||||
return newArray
|
return newArray
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@generic T
|
||||||
|
---@param array T[]
|
||||||
|
---@param condition fun(T): boolean
|
||||||
|
---@return T | nil
|
||||||
|
function utils.first(array, condition)
|
||||||
|
for _, element in ipairs(array) do
|
||||||
|
if condition(element) then
|
||||||
|
return element
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
---@return number distance, number x, number y
|
---@return number distance, number x, number y
|
||||||
function utils.distanceBetween(x1, y1, x2, y2)
|
function utils.distanceBetween(x1, y1, x2, y2)
|
||||||
local x = x1 - x2
|
local x = x1 - x2
|
||||||
|
@ -102,7 +133,7 @@ end
|
||||||
---@param array T[]
|
---@param array T[]
|
||||||
---@param x number
|
---@param x number
|
||||||
---@param y number
|
---@param y number
|
||||||
---@return T,number|nil
|
---@return T nearest,number |nil distance
|
||||||
function utils.getNearestOf(array, x, y, extraCondition)
|
function utils.getNearestOf(array, x, y, extraCondition)
|
||||||
local nearest, nearestDistance = nil, nil
|
local nearest, nearestDistance = nil, nil
|
||||||
for _, element in pairs(array) do
|
for _, element in pairs(array) do
|
||||||
|
|
Loading…
Reference in New Issue