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 GloveOffX, GloveOffY <const> = GloveSizeX / 2, GloveSizeY / 2
---@param ball Point3d
---@param fielderX number
---@param fielderY number
---@return boolean isHoldingBall

View File

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

View File

@ -11,13 +11,13 @@ import 'CoreLibs/ui.lua'
--- @alias Fielder {
--- x: number,
--- y: number,
--- target: XYPair | nil,
--- target: XyPair | nil,
--- speed: 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
import 'utils.lua'
@ -63,7 +63,7 @@ local ball <const> = {
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>
local teams <const> = {
@ -144,14 +144,14 @@ local function playerIsOn(side)
return ret, not ret
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 destY number
---@param easingFunc EasingFunc
---@param flyTimeMs number | nil
---@param floaty boolean | 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
throwMeter = 0
@ -182,7 +182,7 @@ local function pitch(pitchFlyTimeMs, pitchTypeIndex)
ball.xAnimator = current.x
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
-- ball.floatAnimator = current.z
-- ball.floatAnimator:reset()
@ -263,7 +263,7 @@ local function buttonControlledThrow(throwFlyMs, forbidThrowHome)
-- Power for this throw has already been determined
throwMeter = 0
fielding:playerThrowTo(targetBase, throwBall, throwFlyMs)
fielding:playerThrowTo(targetBase, launchBall, throwFlyMs)
secondsSinceLastRunnerMove = 0
offenseState = C.Offense.running
@ -326,7 +326,7 @@ local function updateBatting(batDeg, batSpeed)
local ballDestY = ball.y + (ballVelY * C.BattingPower)
-- Hit!
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.prevBase = C.Bases[C.Home]
@ -408,7 +408,7 @@ local function updateGameState()
elseif outcome == PitchOutcomes.Walk then
walk()
end
throwBall(C.PitchStartX, C.PitchStartY, playdate.easingFunctions.linear, nil, true)
launchBall(C.PitchStartX, C.PitchStartY, playdate.easingFunctions.linear, nil, true)
catcherThrownBall = true
end
@ -444,7 +444,7 @@ local function updateGameState()
else
secondsSinceLastRunnerMove = secondsSinceLastRunnerMove + deltaSeconds
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()
offenseState = C.Offense.batting
if not baserunning.batter then
@ -469,7 +469,7 @@ local function updateGameState()
if fielderHoldingBall then
local outedSomeRunner = baserunning:outEligibleRunners(fielderHoldingBall)
if playerOnOffense then
npc.fielderAction(fielding, baserunning, offenseState, fielderHoldingBall, outedSomeRunner, ball, throwBall)
npc.fielderAction(fielding, baserunning, offenseState, fielderHoldingBall, outedSomeRunner, ball, launchBall)
end
end
@ -550,7 +550,7 @@ local function init()
playdate.getSystemMenu():addMenuItem("Restart game", function() end) -- TODO?
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)
BootTune:play()
BootTune:setFinishCallback(function()

View File

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

View File

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