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,
|
x = Center.x,
|
||||||
y = Center.y,
|
y = Center.y,
|
||||||
size = 6,
|
size = 6,
|
||||||
|
heldBy = nil --[[@type Runner | nil]],
|
||||||
}
|
}
|
||||||
|
|
||||||
local BatLength <const> = 45
|
local BatLength <const> = 50 --45
|
||||||
|
|
||||||
local Modes <const> = {
|
local Modes <const> = {
|
||||||
batting = {},
|
batting = {},
|
||||||
|
@ -146,7 +147,7 @@ function resetFielderPositions(fromOffTheField)
|
||||||
fielders.catcher.target = xy(Screen.W * 0.475, Screen.H * 0.92)
|
fielders.catcher.target = xy(Screen.W * 0.475, Screen.H * 0.92)
|
||||||
fielders.left.target = xy(Screen.W * -1, Screen.H * -0.2)
|
fielders.left.target = xy(Screen.W * -1, Screen.H * -0.2)
|
||||||
fielders.center.target = xy(Center.x, Screen.H * -0.4)
|
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
|
end
|
||||||
|
|
||||||
local BatterStartingX <const> = Bases[Home].x - 40
|
local BatterStartingX <const> = Bases[Home].x - 40
|
||||||
|
@ -179,6 +180,7 @@ function throwBall(destX, destY, easingFunc, flyTimeMs, floaty)
|
||||||
if not flyTimeMs then
|
if not flyTimeMs then
|
||||||
flyTimeMs = distanceBetween(ball.x, ball.y, destX, destY) * 5
|
flyTimeMs = distanceBetween(ball.x, ball.y, destX, destY) * 5
|
||||||
end
|
end
|
||||||
|
ball.heldBy = nil
|
||||||
ballSizeAnimator:reset(flyTimeMs)
|
ballSizeAnimator:reset(flyTimeMs)
|
||||||
ballAnimatorY = gfx.animator.new(flyTimeMs, ball.y, destY, easingFunc)
|
ballAnimatorY = gfx.animator.new(flyTimeMs, ball.y, destY, easingFunc)
|
||||||
ballAnimatorX = gfx.animator.new(flyTimeMs, ball.x, destX, 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.x = fielder.x - (x * fielder.speed * deltaSeconds)
|
||||||
fielder.y = fielder.y - (y * fielder.speed * deltaSeconds)
|
fielder.y = fielder.y - (y * fielder.speed * deltaSeconds)
|
||||||
else
|
else
|
||||||
|
fielder.target = nil
|
||||||
if fielder.onArrive then
|
if fielder.onArrive then
|
||||||
fielder.onArrive()
|
fielder.onArrive()
|
||||||
end
|
end
|
||||||
fielder.target = nil
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if currentMode == Modes.running and isTouchingBall(fielder.x, fielder.y) then
|
if currentMode == Modes.running and isTouchingBall(fielder.x, fielder.y) then
|
||||||
local touchedBase = isTouchingBase(fielder.x, fielder.y)
|
local touchedBase = isTouchingBase(fielder.x, fielder.y)
|
||||||
for i, runner in pairs(runners) do
|
for i, runner in pairs(runners) do
|
||||||
local runnerOnBase = touchingBaseCache.get(runner)
|
|
||||||
if
|
if
|
||||||
touchedBase
|
touchedBase
|
||||||
and runner.prevBase
|
and runner.prevBase -- Check if the runner is standing at home
|
||||||
and runner.forcedTo == touchedBase
|
and runner.forcedTo == touchedBase
|
||||||
and touchedBase ~= runnerOnBase
|
and touchedBase ~= touchingBaseCache.get(runner)
|
||||||
then
|
then
|
||||||
outRunner(i)
|
outRunner(i)
|
||||||
elseif not runnerOnBase then
|
elseif not touchingBaseCache.get(runner) then
|
||||||
if distanceBetween(runner.x, runner.y, fielder.x, fielder.y) < TagDistance then
|
if distanceBetween(runner.x, runner.y, fielder.x, fielder.y) < TagDistance then
|
||||||
outRunner(i)
|
outRunner(i)
|
||||||
end
|
end
|
||||||
|
@ -468,10 +469,16 @@ function updateBatting()
|
||||||
local chasingFielder = getNearestOf(fielders, ballDestX, ballDestY)
|
local chasingFielder = getNearestOf(fielders, ballDestX, ballDestY)
|
||||||
chasingFielder.target = { x = ballDestX, y = ballDestY }
|
chasingFielder.target = { x = ballDestX, y = ballDestY }
|
||||||
chasingFielder.onArrive = function()
|
chasingFielder.onArrive = function()
|
||||||
local targetX, targetY = getNextThrowTarget()
|
|
||||||
if targetX ~= nil then
|
|
||||||
throwBall(targetX, targetY, playdate.easingFunctions.linear, nil, true)
|
|
||||||
chasingFielder.onArrive = nil
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -510,8 +517,13 @@ function updateGameState()
|
||||||
elapsedSec = elapsedSec + deltaSeconds
|
elapsedSec = elapsedSec + deltaSeconds
|
||||||
crankChange, acceleratedChange = playdate.getCrankChange() --[[@as number, number]]
|
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.x = ballAnimatorX:currentValue()
|
||||||
ball.y = ballAnimatorY:currentValue() + ballFloatAnimator:currentValue()
|
ball.y = ballAnimatorY:currentValue() + ballFloatAnimator:currentValue()
|
||||||
|
end
|
||||||
|
|
||||||
if currentMode == Modes.batting then
|
if currentMode == Modes.batting then
|
||||||
updateBatting()
|
updateBatting()
|
||||||
|
|
|
@ -3,12 +3,6 @@ import 'CoreLibs/animation.lua'
|
||||||
import 'CoreLibs/graphics.lua'
|
import 'CoreLibs/graphics.lua'
|
||||||
-- stylua: ignore end
|
-- 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)
|
function easingHill(t, b, c, d)
|
||||||
c = c + 0.0 -- convert to float to prevent integer overflow
|
c = c + 0.0 -- convert to float to prevent integer overflow
|
||||||
t = t / d
|
t = t / d
|
||||||
|
@ -109,12 +103,22 @@ function getNearestOf(array, x, y, extraCondition)
|
||||||
return nearest, nearestDistance
|
return nearest, nearestDistance
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Marker used by buildCache to indicate a cached `nil` value.
|
||||||
local NoValue <const> = {}
|
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)
|
function buildCache(fetcher)
|
||||||
local cacheData = {}
|
local cacheData = {}
|
||||||
return {
|
return {
|
||||||
cacheDate = cacheData,
|
|
||||||
get = function(key)
|
get = function(key)
|
||||||
if cacheData[key] == NoValue then
|
if cacheData[key] == NoValue then
|
||||||
return nil
|
return nil
|
||||||
|
@ -122,7 +126,8 @@ function buildCache(fetcher)
|
||||||
if cacheData[key] ~= nil then
|
if cacheData[key] ~= nil then
|
||||||
return cacheData[key]
|
return cacheData[key]
|
||||||
end
|
end
|
||||||
cacheData[key] = fetcher(key) or NoValue
|
local fetched = fetcher(key)
|
||||||
|
cacheData[key] = fetched ~= nil and fetched or NoValue
|
||||||
return cacheData[key]
|
return cacheData[key]
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue