parent
b003c148a4
commit
699dab8c7d
15
src/ball.lua
15
src/ball.lua
|
@ -4,12 +4,12 @@
|
|||
---@field z number
|
||||
---@field size number
|
||||
---@field heldBy Fielder | nil
|
||||
---@field catchable boolean
|
||||
---@field xAnimator SimpleAnimator
|
||||
---@field yAnimator SimpleAnimator
|
||||
---@field sizeAnimator SimpleAnimator
|
||||
---@field floatAnimator SimpleAnimator
|
||||
---@field private animatorLib pd_animator_lib
|
||||
---@field private flyTimeMs number
|
||||
Ball = {}
|
||||
|
||||
---@param animatorLib pd_animator_lib
|
||||
|
@ -20,6 +20,7 @@ function Ball.new(animatorLib)
|
|||
x = C.Center.x --[[@as number]],
|
||||
y = C.Center.y --[[@as number]],
|
||||
z = 0,
|
||||
catchable = true,
|
||||
size = C.SmallestBallRadius,
|
||||
heldBy = nil --[[@type Runner | nil]],
|
||||
|
||||
|
@ -49,6 +50,13 @@ function Ball:updatePosition()
|
|||
end
|
||||
end
|
||||
|
||||
function Ball:markUncatchable()
|
||||
self.catchable = false
|
||||
playdate.timer.new(200, function()
|
||||
self.catchable = true
|
||||
end)
|
||||
end
|
||||
|
||||
--- Launches the ball from its current position to the given destination.
|
||||
---@param destX number
|
||||
---@param destY number
|
||||
|
@ -60,12 +68,13 @@ function Ball:launch(destX, destY, easingFunc, flyTimeMs, floaty, customBallScal
|
|||
throwMeter:reset()
|
||||
self.heldBy = nil
|
||||
|
||||
-- Prevent silly insta-catches
|
||||
self:markUncatchable()
|
||||
|
||||
if not flyTimeMs then
|
||||
flyTimeMs = utils.distanceBetween(self.x, self.y, destX, destY) * C.DefaultLaunchPower
|
||||
end
|
||||
|
||||
self.flyTimeMs = flyTimeMs
|
||||
|
||||
if customBallScaler then
|
||||
self.sizeAnimator = customBallScaler
|
||||
else
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
--- @class Fielder {
|
||||
--- @field catchEligible boolean
|
||||
--- @field x number
|
||||
--- @field y number
|
||||
--- @field target XyPair | nil
|
||||
|
@ -21,7 +20,6 @@ local function newFielder(name, speed)
|
|||
return {
|
||||
name = name,
|
||||
speed = speed * C.FielderRunMult,
|
||||
catchEligible = true,
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -77,9 +75,9 @@ end
|
|||
|
||||
---@param deltaSeconds number
|
||||
---@param fielder Fielder
|
||||
---@param ballPos XyPair
|
||||
---@return boolean inCatchingRange
|
||||
local function updateFielderPosition(deltaSeconds, fielder, ballPos)
|
||||
---@param ball Ball
|
||||
---@return boolean canCatch
|
||||
local function updateFielderPosition(deltaSeconds, fielder, ball)
|
||||
if fielder.target ~= nil then
|
||||
if
|
||||
utils.pointIsSquarelyAboveLine(fielder, C.BottomOfOutfieldWall)
|
||||
|
@ -89,7 +87,7 @@ local function updateFielderPosition(deltaSeconds, fielder, ballPos)
|
|||
end
|
||||
end
|
||||
|
||||
return utils.distanceBetweenPoints(fielder, ballPos) < C.BallCatchHitbox
|
||||
return ball.catchable and utils.distanceBetweenPoints(fielder, ball) < C.BallCatchHitbox
|
||||
end
|
||||
|
||||
-- TODO: Prevent multiple fielders covering the same base.
|
||||
|
@ -115,16 +113,16 @@ function Fielding:haveSomeoneChase(ballDestX, ballDestY)
|
|||
end
|
||||
end
|
||||
|
||||
--- # Also updates `ball.heldby`
|
||||
--- **Also updates `ball.heldby`**
|
||||
---@param ball Ball
|
||||
---@param deltaSeconds number
|
||||
---@return Fielder | nil fielderHoldingBall nil if no fielder is currently touching the ball
|
||||
function Fielding:updateFielderPositions(ball, deltaSeconds)
|
||||
local fielderHoldingBall
|
||||
for _, fielder in pairs(self.fielders) do
|
||||
local inCatchingRange = updateFielderPosition(deltaSeconds, fielder, ball)
|
||||
if inCatchingRange and fielder.catchEligible then
|
||||
-- TODO: Base this catch on fielder skill?
|
||||
-- TODO: Base this catch on fielder skill?
|
||||
local canCatch = updateFielderPosition(deltaSeconds, fielder, ball)
|
||||
if canCatch then
|
||||
fielderHoldingBall = fielder
|
||||
ball.heldBy = fielder -- How much havoc will this wreak?
|
||||
end
|
||||
|
@ -136,29 +134,6 @@ function Fielding:updateFielderPositions(ball, deltaSeconds)
|
|||
return fielderHoldingBall
|
||||
end
|
||||
|
||||
---@param fielder Fielder
|
||||
function Fielding.markIneligible(fielder)
|
||||
fielder.catchEligible = false
|
||||
playdate.timer.new(500, function()
|
||||
fielder.catchEligible = true
|
||||
end)
|
||||
end
|
||||
|
||||
function Fielding:markAllEligible(eligible)
|
||||
for _, fielder in pairs(self.fielders) do
|
||||
fielder.catchEligible = eligible
|
||||
end
|
||||
end
|
||||
|
||||
function Fielding:resetEligibility()
|
||||
self:markAllEligible(false)
|
||||
playdate.timer.new(750, function()
|
||||
for _, fielder in pairs(self.fielders) do
|
||||
fielder.catchEligible = true
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- TODO? Start moving target fielders close sooner?
|
||||
---@param field Fielding
|
||||
---@param targetBase Base
|
||||
|
@ -175,7 +150,6 @@ local function userThrowToCoroutine(field, targetBase, ball, throwFlyMs)
|
|||
|
||||
closestFielder.target = targetBase
|
||||
ball:launch(targetBase.x, targetBase.y, playdate.easingFunctions.linear, throwFlyMs)
|
||||
Fielding.markIneligible(field.fielderHoldingBall)
|
||||
|
||||
return
|
||||
end
|
||||
|
|
|
@ -197,7 +197,7 @@ end
|
|||
---@param pitchFlyTimeMs number | nil
|
||||
---@param pitchTypeIndex number | nil
|
||||
function Game:pitch(pitchFlyTimeMs, pitchTypeIndex)
|
||||
Fielding.markIneligible(self.fielding.fielders.pitcher)
|
||||
self.state.ball:markUncatchable()
|
||||
self.state.ball.heldBy = nil
|
||||
self.state.pitchIsOver = false
|
||||
self.state.offenseState = C.Offense.batting
|
||||
|
@ -445,8 +445,6 @@ function Game:returnToPitcher()
|
|||
if not self.baserunning.batter then
|
||||
self.baserunning:pushNewBatter()
|
||||
end
|
||||
self.fielding:resetEligibility()
|
||||
self.fielding.fielders.pitcher.catchEligible = true
|
||||
self.state.ball:launch(C.PitchStart.x, C.PitchStart.y, playdate.easingFunctions.linear, nil, true)
|
||||
end)
|
||||
end
|
||||
|
@ -572,7 +570,6 @@ function Game:updateGameState()
|
|||
while not self:pitcherIsReady() do
|
||||
coroutine.yield()
|
||||
end
|
||||
self.fielding:markAllEligible(true)
|
||||
self.state.offenseState = C.Offense.batting
|
||||
end)
|
||||
end
|
||||
|
|
|
@ -124,15 +124,12 @@ end
|
|||
local function tryToMakeAPlay(fielders, fielder, runners, ball)
|
||||
local targetX, targetY = getNextOutTarget(runners)
|
||||
if targetX ~= nil and targetY ~= nil then
|
||||
local nearestFielder = utils.getNearestOf(fielders, targetX, targetY, function(grabCandidate)
|
||||
return grabCandidate.catchEligible
|
||||
end)
|
||||
local nearestFielder = utils.getNearestOf(fielders, targetX, targetY)
|
||||
nearestFielder.target = utils.xy(targetX, targetY)
|
||||
if nearestFielder == fielder then
|
||||
ball.heldBy = fielder
|
||||
else
|
||||
ball:launch(targetX, targetY, playdate.easingFunctions.linear, nil, true)
|
||||
Fielding.markIneligible(nearestFielder)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue