Fielders can run the ball towards a base themselves.
Ball can be heldBy a fielder. Fix likely bug in buildCache() and document it (including contemplating future removal). Add missing Full Circle font png.
This commit is contained in:
parent
b9fc7ee09e
commit
66e3d2bb01
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
32
src/main.lua
32
src/main.lua
|
@ -60,9 +60,10 @@ local ball <const> = {
|
|||
x = Center.x,
|
||||
y = Center.y,
|
||||
size = 6,
|
||||
heldBy = nil --[[@type Runner | nil]],
|
||||
}
|
||||
|
||||
local BatLength <const> = 45
|
||||
local BatLength <const> = 50 --45
|
||||
|
||||
local Modes <const> = {
|
||||
batting = {},
|
||||
|
@ -146,7 +147,7 @@ function resetFielderPositions(fromOffTheField)
|
|||
fielders.catcher.target = xy(Screen.W * 0.475, Screen.H * 0.92)
|
||||
fielders.left.target = xy(Screen.W * -1, Screen.H * -0.2)
|
||||
fielders.center.target = xy(Center.x, Screen.H * -0.4)
|
||||
fielders.right.target = xy(Screen.W * 2, Screen.H * fielders.left.target.y)
|
||||
fielders.right.target = xy(Screen.W * 2, fielders.left.target.y)
|
||||
end
|
||||
|
||||
local BatterStartingX <const> = Bases[Home].x - 40
|
||||
|
@ -179,6 +180,7 @@ function throwBall(destX, destY, easingFunc, flyTimeMs, floaty)
|
|||
if not flyTimeMs then
|
||||
flyTimeMs = distanceBetween(ball.x, ball.y, destX, destY) * 5
|
||||
end
|
||||
ball.heldBy = nil
|
||||
ballSizeAnimator:reset(flyTimeMs)
|
||||
ballAnimatorY = gfx.animator.new(flyTimeMs, ball.y, destY, easingFunc)
|
||||
ballAnimatorX = gfx.animator.new(flyTimeMs, ball.x, destX, easingFunc)
|
||||
|
@ -264,25 +266,24 @@ function updateFielders()
|
|||
fielder.x = fielder.x - (x * fielder.speed * deltaSeconds)
|
||||
fielder.y = fielder.y - (y * fielder.speed * deltaSeconds)
|
||||
else
|
||||
fielder.target = nil
|
||||
if fielder.onArrive then
|
||||
fielder.onArrive()
|
||||
end
|
||||
fielder.target = nil
|
||||
end
|
||||
end
|
||||
|
||||
if currentMode == Modes.running and isTouchingBall(fielder.x, fielder.y) then
|
||||
local touchedBase = isTouchingBase(fielder.x, fielder.y)
|
||||
for i, runner in pairs(runners) do
|
||||
local runnerOnBase = touchingBaseCache.get(runner)
|
||||
if
|
||||
touchedBase
|
||||
and runner.prevBase
|
||||
and runner.prevBase -- Check if the runner is standing at home
|
||||
and runner.forcedTo == touchedBase
|
||||
and touchedBase ~= runnerOnBase
|
||||
and touchedBase ~= touchingBaseCache.get(runner)
|
||||
then
|
||||
outRunner(i)
|
||||
elseif not runnerOnBase then
|
||||
elseif not touchingBaseCache.get(runner) then
|
||||
if distanceBetween(runner.x, runner.y, fielder.x, fielder.y) < TagDistance then
|
||||
outRunner(i)
|
||||
end
|
||||
|
@ -468,10 +469,16 @@ function updateBatting()
|
|||
local chasingFielder = getNearestOf(fielders, ballDestX, ballDestY)
|
||||
chasingFielder.target = { x = ballDestX, y = ballDestY }
|
||||
chasingFielder.onArrive = function()
|
||||
local targetX, targetY = getNextThrowTarget()
|
||||
if targetX ~= nil then
|
||||
throwBall(targetX, targetY, playdate.easingFunctions.linear, nil, true)
|
||||
chasingFielder.onArrive = nil
|
||||
local targetX, targetY = getNextThrowTarget()
|
||||
if targetX ~= nil and targetY ~= nil then
|
||||
local nearestFielder = getNearestOf(fielders, targetX, targetY)
|
||||
nearestFielder.target = xy(targetX, targetY)
|
||||
if nearestFielder == chasingFielder then
|
||||
ball.heldBy = chasingFielder
|
||||
else
|
||||
throwBall(targetX, targetY, playdate.easingFunctions.linear, nil, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -510,8 +517,13 @@ function updateGameState()
|
|||
elapsedSec = elapsedSec + deltaSeconds
|
||||
crankChange, acceleratedChange = playdate.getCrankChange() --[[@as number, number]]
|
||||
|
||||
if ball.heldBy then
|
||||
ball.x = ball.heldBy.x
|
||||
ball.y = ball.heldBy.y
|
||||
else
|
||||
ball.x = ballAnimatorX:currentValue()
|
||||
ball.y = ballAnimatorY:currentValue() + ballFloatAnimator:currentValue()
|
||||
end
|
||||
|
||||
if currentMode == Modes.batting then
|
||||
updateBatting()
|
||||
|
|
|
@ -3,12 +3,6 @@ import 'CoreLibs/animation.lua'
|
|||
import 'CoreLibs/graphics.lua'
|
||||
-- stylua: ignore end
|
||||
|
||||
-- number = ((number * 2) - 1)
|
||||
-- return number * number
|
||||
|
||||
-- c = c + 0.0 -- convert to float to prevent integer overflow
|
||||
-- return c * t / d + b
|
||||
|
||||
function easingHill(t, b, c, d)
|
||||
c = c + 0.0 -- convert to float to prevent integer overflow
|
||||
t = t / d
|
||||
|
@ -109,12 +103,22 @@ function getNearestOf(array, x, y, extraCondition)
|
|||
return nearest, nearestDistance
|
||||
end
|
||||
|
||||
--- Marker used by buildCache to indicate a cached `nil` value.
|
||||
local NoValue <const> = {}
|
||||
|
||||
--- Build a simple fetcher cache. On calling `get()`, if no value has already
|
||||
--- been fetched, calls `fetcher(key)`, then caches and returns that value.
|
||||
---
|
||||
--- On reflection, it's probably pretty early for this optimization, and it's
|
||||
--- optimizing in favor of CPU at the expense of memory, which is probably not
|
||||
--- where the playdate's limitaitons lie. But it can stay for now.
|
||||
---
|
||||
---@generic Key
|
||||
---@generic Value
|
||||
---@return { get: fun(key: Key): Value }
|
||||
function buildCache(fetcher)
|
||||
local cacheData = {}
|
||||
return {
|
||||
cacheDate = cacheData,
|
||||
get = function(key)
|
||||
if cacheData[key] == NoValue then
|
||||
return nil
|
||||
|
@ -122,7 +126,8 @@ function buildCache(fetcher)
|
|||
if cacheData[key] ~= nil then
|
||||
return cacheData[key]
|
||||
end
|
||||
cacheData[key] = fetcher(key) or NoValue
|
||||
local fetched = fetcher(key)
|
||||
cacheData[key] = fetched ~= nil and fetched or NoValue
|
||||
return cacheData[key]
|
||||
end,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue