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