XYPair -> XyPair, throwBall() -> launchBall()

Add Point3d type.
This commit is contained in:
Sage Vaillancourt 2025-02-09 11:35:19 -05:00
parent d74332f685
commit fed1151179
5 changed files with 41 additions and 34 deletions

View File

@ -4,6 +4,7 @@ local gfx = playdate.graphics
local GloveSizeX, GloveSizeY <const> = Glove:getSize() local GloveSizeX, GloveSizeY <const> = Glove:getSize()
local GloveOffX, GloveOffY <const> = GloveSizeX / 2, GloveSizeY / 2 local GloveOffX, GloveOffY <const> = GloveSizeX / 2, GloveSizeY / 2
---@param ball Point3d
---@param fielderX number ---@param fielderX number
---@param fielderY number ---@param fielderY number
---@return boolean isHoldingBall ---@return boolean isHoldingBall

View File

@ -33,7 +33,7 @@ function Fielding.new()
end end
--- Actually only benches the infield, because outfielders are far away! --- Actually only benches the infield, because outfielders are far away!
---@param position XYPair ---@param position XyPair
function Fielding:benchTo(position) function Fielding:benchTo(position)
self.fielders.first.target = position self.fielders.first.target = position
self.fielders.second.target = position self.fielders.second.target = position
@ -44,7 +44,7 @@ function Fielding:benchTo(position)
end end
--- Resets the target positions of all fielders to their defaults (at their field positions). --- Resets the target positions of all fielders to their defaults (at their field positions).
---@param fromOffTheField XYPair | nil If provided, also sets all runners' current position to one centralized location. ---@param fromOffTheField XyPair | nil If provided, also sets all runners' current position to one centralized location.
function Fielding:resetFielderPositions(fromOffTheField) function Fielding:resetFielderPositions(fromOffTheField)
if fromOffTheField then if fromOffTheField then
for _, fielder in pairs(self.fielders) do for _, fielder in pairs(self.fielders) do
@ -66,7 +66,7 @@ end
---@param deltaSeconds number ---@param deltaSeconds number
---@param fielder Fielder ---@param fielder Fielder
---@param ballPos XYPair ---@param ballPos XyPair
---@return boolean isTouchingBall ---@return boolean isTouchingBall
local function updateFielderPosition(deltaSeconds, fielder, ballPos) local function updateFielderPosition(deltaSeconds, fielder, ballPos)
if fielder.target ~= nil then if fielder.target ~= nil then
@ -96,7 +96,7 @@ function Fielding:haveSomeoneChase(ballDestX, ballDestY)
end end
end end
---@param ball XYPair ---@param ball XyPair
---@param deltaSeconds number ---@param deltaSeconds number
---@return Fielder | nil fielderTouchingBall nil if no fielder is currently touching the ball ---@return Fielder | nil fielderTouchingBall nil if no fielder is currently touching the ball
function Fielding:updateFielderPositions(ball, deltaSeconds) function Fielding:updateFielderPositions(ball, deltaSeconds)
@ -114,10 +114,10 @@ end
-- TODO? Start moving target fielders close sooner? -- TODO? Start moving target fielders close sooner?
---@param field table ---@param field table
---@param targetBase Base ---@param targetBase Base
---@param throwBall ThrowBall ---@param launchBall LaunchBall
---@param throwFlyMs number ---@param throwFlyMs number
---@return ActionResult ---@return ActionResult
local function playerThrowToImpl(field, targetBase, throwBall, throwFlyMs) local function playerThrowToImpl(field, targetBase, launchBall, throwFlyMs)
if field.fielderTouchingBall == nil then if field.fielderTouchingBall == nil then
return ActionResult.NeedsMoreTime return ActionResult.NeedsMoreTime
end end
@ -126,18 +126,18 @@ local function playerThrowToImpl(field, targetBase, throwBall, throwFlyMs)
end) end)
closestFielder.target = targetBase closestFielder.target = targetBase
throwBall(targetBase.x, targetBase.y, playdate.easingFunctions.linear, throwFlyMs) launchBall(targetBase.x, targetBase.y, playdate.easingFunctions.linear, throwFlyMs)
return ActionResult.Succeeded return ActionResult.Succeeded
end end
--- Buffer in a fielder throw action. --- Buffer in a fielder throw action.
---@param self table ---@param self table
---@param targetBase Base ---@param targetBase Base
---@param throwBall ThrowBall ---@param launchBall LaunchBall
---@param throwFlyMs number ---@param throwFlyMs number
function Fielding:playerThrowTo(targetBase, throwBall, throwFlyMs) function Fielding:playerThrowTo(targetBase, launchBall, throwFlyMs)
local maxTryTimeMs = 5000 local maxTryTimeMs = 5000
actionQueue:upsert('playerThrowTo', maxTryTimeMs, function() actionQueue:upsert('playerThrowTo', maxTryTimeMs, function()
return playerThrowToImpl(self, targetBase, throwBall, throwFlyMs) return playerThrowToImpl(self, targetBase, launchBall, throwFlyMs)
end) end)
end end

View File

@ -11,13 +11,13 @@ import 'CoreLibs/ui.lua'
--- @alias Fielder { --- @alias Fielder {
--- x: number, --- x: number,
--- y: number, --- y: number,
--- target: XYPair | nil, --- target: XyPair | nil,
--- speed: number, --- speed: number,
--- } --- }
--- @alias EasingFunc fun(number, number, number, number): number --- @alias EasingFunc fun(number, number, number, number): number
--- @alias ThrowBall fun(destX: number, destY: number, easingFunc: EasingFunc, flyTimeMs: number | nil, floaty: boolean | nil, customBallScaler: pd_animator | nil) --- @alias LaunchBall fun(destX: number, destY: number, easingFunc: EasingFunc, flyTimeMs: number | nil, floaty: boolean | nil, customBallScaler: pd_animator | nil)
-- stylua: ignore start -- stylua: ignore start
import 'utils.lua' import 'utils.lua'
@ -63,7 +63,7 @@ local ball <const> = {
floatAnimator = gfx.animator.new(2000, -60, 0, utils.easingHill), floatAnimator = gfx.animator.new(2000, -60, 0, utils.easingHill),
} }
---@alias Team { score: number, benchPosition: XYPair } ---@alias Team { score: number, benchPosition: XyPair }
---@type table<string, Team> ---@type table<string, Team>
local teams <const> = { local teams <const> = {
@ -144,14 +144,14 @@ local function playerIsOn(side)
return ret, not ret return ret, not ret
end end
--- "Throws" the ball from its current position to the given destination. --- Launches the ball from its current position to the given destination.
---@param destX number ---@param destX number
---@param destY number ---@param destY number
---@param easingFunc EasingFunc ---@param easingFunc EasingFunc
---@param flyTimeMs number | nil ---@param flyTimeMs number | nil
---@param floaty boolean | nil ---@param floaty boolean | nil
---@param customBallScaler pd_animator | nil ---@param customBallScaler pd_animator | nil
local function throwBall(destX, destY, easingFunc, flyTimeMs, floaty, customBallScaler) local function launchBall(destX, destY, easingFunc, flyTimeMs, floaty, customBallScaler)
ball.heldBy = nil ball.heldBy = nil
throwMeter = 0 throwMeter = 0
@ -182,7 +182,7 @@ local function pitch(pitchFlyTimeMs, pitchTypeIndex)
ball.xAnimator = current.x ball.xAnimator = current.x
ball.yAnimator = current.y or Pitches[1].y ball.yAnimator = current.y or Pitches[1].y
-- TODO: This would need to be sanely replaced in throwBall() etc. -- TODO: This would need to be sanely replaced in launchBall() etc.
-- if current.z then -- if current.z then
-- ball.floatAnimator = current.z -- ball.floatAnimator = current.z
-- ball.floatAnimator:reset() -- ball.floatAnimator:reset()
@ -263,7 +263,7 @@ local function buttonControlledThrow(throwFlyMs, forbidThrowHome)
-- Power for this throw has already been determined -- Power for this throw has already been determined
throwMeter = 0 throwMeter = 0
fielding:playerThrowTo(targetBase, throwBall, throwFlyMs) fielding:playerThrowTo(targetBase, launchBall, throwFlyMs)
secondsSinceLastRunnerMove = 0 secondsSinceLastRunnerMove = 0
offenseState = C.Offense.running offenseState = C.Offense.running
@ -326,7 +326,7 @@ local function updateBatting(batDeg, batSpeed)
local ballDestY = ball.y + (ballVelY * C.BattingPower) local ballDestY = ball.y + (ballVelY * C.BattingPower)
-- Hit! -- Hit!
local hitBallScaler = gfx.animator.new(2000, 9 + (mult * mult * 0.5), C.SmallestBallRadius, utils.easingHill) local hitBallScaler = gfx.animator.new(2000, 9 + (mult * mult * 0.5), C.SmallestBallRadius, utils.easingHill)
throwBall(ballDestX, ballDestY, playdate.easingFunctions.outQuint, 2000, nil, hitBallScaler) launchBall(ballDestX, ballDestY, playdate.easingFunctions.outQuint, 2000, nil, hitBallScaler)
baserunning.batter.nextBase = C.Bases[C.First] baserunning.batter.nextBase = C.Bases[C.First]
baserunning.batter.prevBase = C.Bases[C.Home] baserunning.batter.prevBase = C.Bases[C.Home]
@ -408,7 +408,7 @@ local function updateGameState()
elseif outcome == PitchOutcomes.Walk then elseif outcome == PitchOutcomes.Walk then
walk() walk()
end end
throwBall(C.PitchStartX, C.PitchStartY, playdate.easingFunctions.linear, nil, true) launchBall(C.PitchStartX, C.PitchStartY, playdate.easingFunctions.linear, nil, true)
catcherThrownBall = true catcherThrownBall = true
end end
@ -444,7 +444,7 @@ local function updateGameState()
else else
secondsSinceLastRunnerMove = secondsSinceLastRunnerMove + deltaSeconds secondsSinceLastRunnerMove = secondsSinceLastRunnerMove + deltaSeconds
if secondsSinceLastRunnerMove > C.ResetFieldersAfterSeconds then if secondsSinceLastRunnerMove > C.ResetFieldersAfterSeconds then
throwBall(C.PitchStartX, C.PitchStartY, playdate.easingFunctions.linear, nil, true) launchBall(C.PitchStartX, C.PitchStartY, playdate.easingFunctions.linear, nil, true)
fielding:resetFielderPositions() fielding:resetFielderPositions()
offenseState = C.Offense.batting offenseState = C.Offense.batting
if not baserunning.batter then if not baserunning.batter then
@ -469,7 +469,7 @@ local function updateGameState()
if fielderHoldingBall then if fielderHoldingBall then
local outedSomeRunner = baserunning:outEligibleRunners(fielderHoldingBall) local outedSomeRunner = baserunning:outEligibleRunners(fielderHoldingBall)
if playerOnOffense then if playerOnOffense then
npc.fielderAction(fielding, baserunning, offenseState, fielderHoldingBall, outedSomeRunner, ball, throwBall) npc.fielderAction(fielding, baserunning, offenseState, fielderHoldingBall, outedSomeRunner, ball, launchBall)
end end
end end
@ -550,7 +550,7 @@ local function init()
playdate.getSystemMenu():addMenuItem("Restart game", function() end) -- TODO? playdate.getSystemMenu():addMenuItem("Restart game", function() end) -- TODO?
playdate.timer.new(2000, function() playdate.timer.new(2000, function()
throwBall(C.PitchStartX, C.PitchStartY, playdate.easingFunctions.linear, nil, false) launchBall(C.PitchStartX, C.PitchStartY, playdate.easingFunctions.linear, nil, false)
end) end)
BootTune:play() BootTune:play()
BootTune:setFinishCallback(function() BootTune:setFinishCallback(function()

View File

@ -5,7 +5,7 @@ local npcBatSpeed = 1500
-- selene: allow(unscoped_variables) -- selene: allow(unscoped_variables)
npc = {} npc = {}
---@param ball XYPair ---@param ball XyPair
---@param catcherThrownBall boolean ---@param catcherThrownBall boolean
---@param deltaSec number ---@param deltaSec number
---@return number ---@return number
@ -88,8 +88,8 @@ end
---@param fielding Fielding ---@param fielding Fielding
---@param fielder Fielder ---@param fielder Fielder
---@param runners Runner[] ---@param runners Runner[]
---@param throwBall ThrowBall ---@param launchBall LaunchBall
function npc.tryToMakeAPlay(fielding, fielder, runners, ball, throwBall) function npc.tryToMakeAPlay(fielding, fielder, runners, ball, launchBall)
local targetX, targetY = npc.getNextOutTarget(runners) local targetX, targetY = npc.getNextOutTarget(runners)
if targetX ~= nil and targetY ~= nil then if targetX ~= nil and targetY ~= nil then
local nearestFielder = utils.getNearestOf(fielding.fielders, targetX, targetY) local nearestFielder = utils.getNearestOf(fielding.fielders, targetX, targetY)
@ -97,7 +97,7 @@ function npc.tryToMakeAPlay(fielding, fielder, runners, ball, throwBall)
if nearestFielder == fielder then if nearestFielder == fielder then
ball.heldBy = fielder ball.heldBy = fielder
else else
throwBall(targetX, targetY, playdate.easingFunctions.linear, nil, true) launchBall(targetX, targetY, playdate.easingFunctions.linear, nil, true)
end end
end end
end end
@ -108,18 +108,18 @@ end
---@param fielder Fielder ---@param fielder Fielder
---@param outedSomeRunner boolean ---@param outedSomeRunner boolean
---@param ball { x: number, y: number, heldBy: Fielder | nil } ---@param ball { x: number, y: number, heldBy: Fielder | nil }
---@param throwBall ThrowBall ---@param launchBall LaunchBall
function npc.fielderAction(fielding, baserunning, offenseState, fielder, outedSomeRunner, ball, throwBall) function npc.fielderAction(fielding, baserunning, offenseState, fielder, outedSomeRunner, ball, launchBall)
if offenseState ~= C.Offense.running then if offenseState ~= C.Offense.running then
return return
end end
if outedSomeRunner then if outedSomeRunner then
-- Delay a little before the next play -- Delay a little before the next play
playdate.timer.new(750, function() playdate.timer.new(750, function()
npc.tryToMakeAPlay(fielding, fielder, baserunning.runners, ball, throwBall) npc.tryToMakeAPlay(fielding, fielder, baserunning.runners, ball, launchBall)
end) end)
else else
npc.tryToMakeAPlay(fielding, fielder, baserunning.runners, ball, throwBall) npc.tryToMakeAPlay(fielding, fielder, baserunning.runners, ball, launchBall)
end end
end end

View File

@ -1,11 +1,17 @@
-- selene: allow(unscoped_variables) -- selene: allow(unscoped_variables)
utils = {} utils = {}
--- @alias XYPair { --- @alias XyPair {
--- x: number, --- x: number,
--- y: number, --- y: number,
--- } --- }
--- @alias Point3d {
--- x: number,
--- y: number,
--- z: number,
--- }
local sqrt <const> = math.sqrt local sqrt <const> = math.sqrt
function utils.easingHill(t, b, c, d) function utils.easingHill(t, b, c, d)
@ -31,7 +37,7 @@ end
---@param x number ---@param x number
---@param y number ---@param y number
---@return XYPair ---@return XyPair
function utils.xy(x, y) function utils.xy(x, y)
return { return {
x = x, x = x,
@ -102,8 +108,8 @@ function utils.distanceBetween(x1, y1, x2, y2)
return sqrt((x * x) + (y * y)), x, y return sqrt((x * x) + (y * y)), x, y
end end
---@param point1 XYPair ---@param point1 XyPair
---@param point2 XYPair ---@param point2 XyPair
---@return number distance, number x, number y ---@return number distance, number x, number y
function utils.distanceBetweenPoints(point1, point2) function utils.distanceBetweenPoints(point1, point2)
local x = point1.x - point2.x local x = point1.x - point2.x