parent
eb28a628f2
commit
4fc49d3631
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
92
src/main.lua
92
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 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 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 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]]
|
||||
|
@ -327,7 +328,7 @@ function pitch(pitchFlyTimeMs, pitchTypeIndex)
|
|||
catcherThrownBall = false
|
||||
offenseMode = Offense.batting
|
||||
|
||||
local current = Pitches[pitchTypeIndex or math.random(#Pitches)]
|
||||
local current = Pitches[pitchTypeIndex]
|
||||
ballAnimatorX = current.x
|
||||
ballAnimatorY = current.y or Pitches[1].y
|
||||
|
||||
|
@ -355,13 +356,9 @@ local BaseHitbox = 10
|
|||
---@param y number
|
||||
---@return Base | nil
|
||||
function isTouchingBase(x, y)
|
||||
for _, base in ipairs(Bases) do
|
||||
if utils.distanceBetween(x, y, base.x, base.y) < BaseHitbox then
|
||||
return base
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
return utils.first(Bases, function(base)
|
||||
return utils.distanceBetween(x, y, base.x, base.y) < BaseHitbox
|
||||
end)
|
||||
end
|
||||
|
||||
local BallCatchHitbox = 3
|
||||
|
@ -377,19 +374,16 @@ end
|
|||
|
||||
---@param base Base
|
||||
---@return Runner | nil
|
||||
function getRunnerTargeting(base)
|
||||
for _, runner in pairs(runners) do
|
||||
if runner.nextBase == base then
|
||||
return runner
|
||||
end
|
||||
end
|
||||
return nil
|
||||
function getRunnerWithNextBase(base)
|
||||
return utils.first(runners, function(runner)
|
||||
return runner.nextBase == base
|
||||
end)
|
||||
end
|
||||
|
||||
function updateForcedRunners()
|
||||
local stillForced = true
|
||||
for _, base in ipairs(Bases) do
|
||||
local runnerTargetingBase = getRunnerTargeting(base)
|
||||
local runnerTargetingBase = getRunnerWithNextBase(base)
|
||||
if runnerTargetingBase then
|
||||
if stillForced then
|
||||
runnerTargetingBase.forcedTo = base
|
||||
|
@ -453,7 +447,7 @@ end
|
|||
function getForcedOutTargets()
|
||||
local targets = {}
|
||||
for _, base in ipairs(Bases) do
|
||||
local runnerTargetingBase = getRunnerTargeting(base)
|
||||
local runnerTargetingBase = getRunnerWithNextBase(base)
|
||||
if runnerTargetingBase then
|
||||
targets[#targets + 1] = base
|
||||
else
|
||||
|
@ -490,7 +484,6 @@ function getNextOutTarget()
|
|||
end
|
||||
|
||||
local baseCloseToStrandedRunner = getBaseOfStrandedRunner()
|
||||
-- TODO: If another fielder is closer, throw it to them, instead
|
||||
if baseCloseToStrandedRunner then
|
||||
return baseCloseToStrandedRunner.x, baseCloseToStrandedRunner.y
|
||||
end
|
||||
|
@ -510,28 +503,10 @@ function tryToMakeAnOut(fielder)
|
|||
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
|
||||
function updateFielder(fielder)
|
||||
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
|
||||
end
|
||||
end
|
||||
|
@ -540,7 +515,6 @@ function updateFielder(fielder)
|
|||
return
|
||||
end
|
||||
|
||||
-- TODO: Check for double-plays or other available outs.
|
||||
local touchedBase = isTouchingBase(fielder.x, fielder.y)
|
||||
for i, runner in pairs(runners) do
|
||||
local runnerOnBase = isTouchingBase(runner.x, runner.y)
|
||||
|
@ -570,7 +544,7 @@ function updateFielders()
|
|||
end
|
||||
|
||||
-- if offenseMode == Offense.batting then
|
||||
-- moveAtSpeed(
|
||||
-- utils.moveAtSpeed(
|
||||
-- fielders.catcher,
|
||||
-- fielders.catcher.speed * 2 * deltaSeconds,
|
||||
-- { x = math.min(Center.x + 15, ball.x), y = fielders.catcher.y }
|
||||
|
@ -623,7 +597,6 @@ function updateRunner(runner, runnerIndex, appliedSpeed)
|
|||
end
|
||||
end
|
||||
|
||||
-- TODO: Also move if forced to 😅
|
||||
local autoRun = (nearestBaseDistance > 40 or runner.forcedTo) and mult * autoRunSpeed
|
||||
or nearestBaseDistance < 5 and 0
|
||||
or (nearestBase == runner.nextBase and autoRunSpeed or -1 * autoRunSpeed)
|
||||
|
@ -698,15 +671,13 @@ end
|
|||
function updateRunning(appliedSpeed)
|
||||
ball.size = ballSizeAnimator:currentValue()
|
||||
|
||||
local nonBatterRunners = utils.filter(runners, function(runner)
|
||||
return runner ~= batter
|
||||
end)
|
||||
|
||||
local runnerMoved = false
|
||||
|
||||
-- TODO: Filter for the runner closest to the currently-held direction button
|
||||
for runnerIndex, runner in ipairs(nonBatterRunners) do
|
||||
runnerMoved = updateRunner(runner, runnerIndex, appliedSpeed) or runnerMoved
|
||||
for runnerIndex, runner in ipairs(runners) do
|
||||
if runner ~= batter then
|
||||
runnerMoved = updateRunner(runner, runnerIndex, appliedSpeed) or runnerMoved
|
||||
end
|
||||
end
|
||||
|
||||
return runnerMoved
|
||||
|
@ -768,7 +739,7 @@ function buttonControlledThrow(thrower, throwFlyMs, forbidThrowHome)
|
|||
if playdate.buttonIsPressed(playdate.kButtonLeft) then
|
||||
targetBase = Bases[Third]
|
||||
elseif playdate.buttonIsPressed(playdate.kButtonUp) then
|
||||
targetBase = Bases[Second] -- TODO - or shortstop - whoever's closer
|
||||
targetBase = Bases[Second]
|
||||
elseif playdate.buttonIsPressed(playdate.kButtonRight) then
|
||||
targetBase = Bases[First]
|
||||
elseif not forbidThrowHome and playdate.buttonIsPressed(playdate.kButtonDown) then
|
||||
|
@ -820,7 +791,7 @@ function updateGameState()
|
|||
|
||||
if secondsSincePitchAllowed > PitchAfterSeconds then
|
||||
if playerOnOffense then
|
||||
pitch(PitchFlyMs)
|
||||
pitch(PitchFlyMs, math.random(#Pitches))
|
||||
else
|
||||
local throwFly = readThrow()
|
||||
if throwFly and not buttonControlledThrow(fielders.pitcher, throwFly, true) then
|
||||
|
@ -864,8 +835,25 @@ function updateGameState()
|
|||
walkAwayOutRunners()
|
||||
end
|
||||
|
||||
-- TODO
|
||||
function drawMinimap() end
|
||||
local MinimapSizeX, MinimapSizeY <const> = Minimap:getSize()
|
||||
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
|
||||
---@return boolean isHoldingBall
|
||||
|
@ -916,7 +904,7 @@ function playdate.update()
|
|||
playdate.ui.crankIndicator:draw()
|
||||
end
|
||||
|
||||
-- TODO? Change blip speed depending on runner speed?
|
||||
-- TODO? Scale sprites down as y increases
|
||||
for _, runner in pairs(runners) do
|
||||
if runner == batter then
|
||||
if batAngleDeg > 50 and batAngleDeg < 200 then
|
||||
|
@ -925,7 +913,7 @@ function playdate.update()
|
|||
PlayerSmile:draw(runner.x, runner.y)
|
||||
end
|
||||
else
|
||||
-- TODO? Scale sprites down as y increases
|
||||
-- TODO? Change blip speed depending on runner speed?
|
||||
PlayerImageBlipper:draw(false, runner.x, runner.y)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -47,6 +47,24 @@ function utils.normalizeVector(x1, y1, x2, y2)
|
|||
return x / distance, y / distance, distance
|
||||
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
|
||||
---@param array T[]
|
||||
---@param condition fun(T): boolean
|
||||
|
@ -61,6 +79,19 @@ function utils.filter(array, condition)
|
|||
return newArray
|
||||
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
|
||||
function utils.distanceBetween(x1, y1, x2, y2)
|
||||
local x = x1 - x2
|
||||
|
@ -102,7 +133,7 @@ end
|
|||
---@param array T[]
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@return T,number|nil
|
||||
---@return T nearest,number |nil distance
|
||||
function utils.getNearestOf(array, x, y, extraCondition)
|
||||
local nearest, nearestDistance = nil, nil
|
||||
for _, element in pairs(array) do
|
||||
|
|
Loading…
Reference in New Issue