Add batter walk-up.
Attach bat to batter. Prevent draw-offset changes when the ball is below the screen.
This commit is contained in:
parent
f1d8c28370
commit
32f9b24d1f
|
@ -4,8 +4,11 @@ local ballBuffer = 5
|
||||||
--- XXX
|
--- XXX
|
||||||
--- XOX
|
--- XOX
|
||||||
--- Where each character is the size of the screen, and 'O' is the default view.
|
--- Where each character is the size of the screen, and 'O' is the default view.
|
||||||
function getDrawOffset(screenW, _screenH, ballX, ballY)
|
function getDrawOffset(screenW, screenH, ballX, ballY)
|
||||||
local offsetX, offsetY
|
local offsetX, offsetY
|
||||||
|
if ballY > screenH then
|
||||||
|
return 0, 0
|
||||||
|
end
|
||||||
if ballY < ballBuffer then
|
if ballY < ballBuffer then
|
||||||
offsetY = math.max(ballBuffer, -1 * (ballY - ballBuffer))
|
offsetY = math.max(ballBuffer, -1 * (ballY - ballBuffer))
|
||||||
else
|
else
|
||||||
|
|
42
src/main.lua
42
src/main.lua
|
@ -46,6 +46,7 @@ local PITCH_START_Y, PITCH_END_Y = 90, 250
|
||||||
local pitchAnimator = gfx.animator.new(pitchFlyTimeMs, PITCH_START_Y, PITCH_END_Y, playdate.easingFunctions.outQuint)
|
local pitchAnimator = gfx.animator.new(pitchFlyTimeMs, PITCH_START_Y, PITCH_END_Y, playdate.easingFunctions.outQuint)
|
||||||
|
|
||||||
local CRANK_OFFSET_DEG = 90
|
local CRANK_OFFSET_DEG = 90
|
||||||
|
local BAT_OFFSET = xy(10, 25)
|
||||||
local batBase = xy(CENTER.x - 34, 215)
|
local batBase = xy(CENTER.x - 34, 215)
|
||||||
local batTip = xy(0, 0)
|
local batTip = xy(0, 0)
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ local TAG_DISTANCE = 20
|
||||||
|
|
||||||
local ball = {
|
local ball = {
|
||||||
x = CENTER.x,
|
x = CENTER.x,
|
||||||
y = BALL_OFFSCREEN,
|
y = CENTER.y,
|
||||||
size = 6,
|
size = 6,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +89,9 @@ local bases = {
|
||||||
xy(SCREEN.W * 0.474, SCREEN.H * 0.79),
|
xy(SCREEN.W * 0.474, SCREEN.H * 0.79),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- Pseudo-base for batter to target
|
||||||
|
local rightHandedBattersBox = xy(bases[HOME].x - 35, bases[HOME].y)
|
||||||
|
|
||||||
---@type table<Base, Base>
|
---@type table<Base, Base>
|
||||||
local nextBaseMap = {
|
local nextBaseMap = {
|
||||||
[bases[FIRST]] = bases[SECOND],
|
[bases[FIRST]] = bases[SECOND],
|
||||||
|
@ -155,11 +159,12 @@ local runnerNames = { "Barbara", "Steve", "Jerry", "Beatrice" }
|
||||||
---@return Runner
|
---@return Runner
|
||||||
function newRunner()
|
function newRunner()
|
||||||
local new = {
|
local new = {
|
||||||
x = PLAYER_STARTING_X,
|
x = PLAYER_STARTING_X - 60,
|
||||||
y = PLAYER_STARTING_Y,
|
y = PLAYER_STARTING_Y + 60,
|
||||||
nextBase = nil,
|
nextBase = rightHandedBattersBox,
|
||||||
prevBase = nil,
|
prevBase = nil,
|
||||||
name = runnerNames[nameI],
|
name = runnerNames[nameI],
|
||||||
|
forcedTo = bases[FIRST]
|
||||||
}
|
}
|
||||||
nameI = nameI + 1
|
nameI = nameI + 1
|
||||||
runners[#runners + 1] = new
|
runners[#runners + 1] = new
|
||||||
|
@ -168,8 +173,6 @@ end
|
||||||
|
|
||||||
---@type Runner | nil
|
---@type Runner | nil
|
||||||
local batter = newRunner()
|
local batter = newRunner()
|
||||||
batter.nextBase = bases[FIRST]
|
|
||||||
batter.forcedTo = bases[FIRST]
|
|
||||||
|
|
||||||
--- "Throws" the ball from its current position to the given destination.
|
--- "Throws" the ball from its current position to the given destination.
|
||||||
function throwBall(destX, destY, easingFunc, flyTimeMs, floaty)
|
function throwBall(destX, destY, easingFunc, flyTimeMs, floaty)
|
||||||
|
@ -243,7 +246,6 @@ local homeScore = 0
|
||||||
local awayScore = 0
|
local awayScore = 0
|
||||||
|
|
||||||
function outRunner(runnerIndex)
|
function outRunner(runnerIndex)
|
||||||
print("You're out, runner" .. runnerIndex .. "!")
|
|
||||||
outs = math.min(3, outs + 1)
|
outs = math.min(3, outs + 1)
|
||||||
outRunners[#outRunners + 1] = runners[runnerIndex]
|
outRunners[#outRunners + 1] = runners[runnerIndex]
|
||||||
table.remove(runners, runnerIndex)
|
table.remove(runners, runnerIndex)
|
||||||
|
@ -285,14 +287,10 @@ function updateFielders()
|
||||||
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)
|
local runnerOnBase = touchingBaseCache.get(runner)
|
||||||
if touchedBase and runner.forcedTo == touchedBase and touchedBase ~= runnerOnBase then
|
if touchedBase and runner.prevBase and runner.forcedTo == touchedBase and touchedBase ~= runnerOnBase then
|
||||||
print("Force out of runner:")
|
|
||||||
printTable(runner)
|
|
||||||
outRunner(i)
|
outRunner(i)
|
||||||
elseif not runnerOnBase then
|
elseif not runnerOnBase then
|
||||||
local fielderDistance = distanceBetween(runner.x, runner.y, fielder.x, fielder.y)
|
if distanceBetween(runner.x, runner.y, fielder.x, fielder.y) < TAG_DISTANCE then
|
||||||
if fielderDistance < TAG_DISTANCE then
|
|
||||||
print("Tagged out!")
|
|
||||||
outRunner(i)
|
outRunner(i)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -306,14 +304,14 @@ end
|
||||||
function updateRunners()
|
function updateRunners()
|
||||||
local autoRunSpeed = 20
|
local autoRunSpeed = 20
|
||||||
--autoRunSpeed = 140
|
--autoRunSpeed = 140
|
||||||
local nonPlayerRunners = filter(runners, function(runner)
|
local currentRunners = currentMode == MODES.batting and {batter} or filter(runners, function(runner)
|
||||||
return runner ~= batter
|
return runner ~= batter
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local runnerMoved = false
|
local runnerMoved = false
|
||||||
for runnerIndex, runner in ipairs(nonPlayerRunners) do
|
for runnerIndex, runner in ipairs(currentRunners) do
|
||||||
local nearestBase, nearestBaseDistance = getNearestOf(bases, runner.x, runner.y)
|
local nearestBase, nearestBaseDistance = getNearestOf(bases, runner.x, runner.y)
|
||||||
if nearestBaseDistance < 5 and runner.nextBase == bases[HOME] and nearestBase == bases[HOME] then
|
if nearestBaseDistance < 5 and runner.prevBase and runner.nextBase == bases[HOME] and nearestBase == bases[HOME] then
|
||||||
score(runnerIndex)
|
score(runnerIndex)
|
||||||
end
|
end
|
||||||
if runner.nextBase then
|
if runner.nextBase then
|
||||||
|
@ -401,7 +399,7 @@ end
|
||||||
local resetFieldersAfterSeconds = 4
|
local resetFieldersAfterSeconds = 4
|
||||||
local secondsSinceLastRunnerMove = 0
|
local secondsSinceLastRunnerMove = 0
|
||||||
|
|
||||||
local pitchAfterSeconds = 4
|
local pitchAfterSeconds = 5
|
||||||
local secondsSincePitchAllowed = -5
|
local secondsSincePitchAllowed = -5
|
||||||
|
|
||||||
function init()
|
function init()
|
||||||
|
@ -418,11 +416,14 @@ function updateBatting()
|
||||||
secondsSincePitchAllowed = 0
|
secondsSincePitchAllowed = 0
|
||||||
end
|
end
|
||||||
if ball.y < BALL_OFFSCREEN then
|
if ball.y < BALL_OFFSCREEN then
|
||||||
ball.y = ballAnimatorY:currentValue()
|
ball.y = ballAnimatorY:currentValue() + ballFloatAnimator:currentValue()
|
||||||
ball.size = 6
|
ball.size = 6
|
||||||
end
|
end
|
||||||
|
|
||||||
local batAngle = math.rad(playdate.getCrankPosition() + CRANK_OFFSET_DEG)
|
local batAngle = math.rad(playdate.getCrankPosition() + CRANK_OFFSET_DEG)
|
||||||
|
-- TODO: animate bat-flip or something
|
||||||
|
batBase.x = batter and (batter.x + BAT_OFFSET.x) or 0
|
||||||
|
batBase.y = batter and (batter.y + BAT_OFFSET.y) or 0
|
||||||
batTip.x = batBase.x + (BAT_LENGTH * math.sin(batAngle))
|
batTip.x = batBase.x + (BAT_LENGTH * math.sin(batAngle))
|
||||||
batTip.y = batBase.y + (BAT_LENGTH * math.cos(batAngle))
|
batTip.y = batBase.y + (BAT_LENGTH * math.cos(batAngle))
|
||||||
|
|
||||||
|
@ -443,10 +444,12 @@ function updateBatting()
|
||||||
end
|
end
|
||||||
local ballDestX = ball.x + (ballVelX * HIT_MULT)
|
local ballDestX = ball.x + (ballVelX * HIT_MULT)
|
||||||
local ballDestY = ball.y + (ballVelY * HIT_MULT)
|
local ballDestY = ball.y + (ballVelY * HIT_MULT)
|
||||||
|
-- Hit!
|
||||||
throwBall(ballDestX, ballDestY, playdate.easingFunctions.outQuint, 2000)
|
throwBall(ballDestX, ballDestY, playdate.easingFunctions.outQuint, 2000)
|
||||||
|
|
||||||
fielders.first.target = bases[FIRST]
|
fielders.first.target = bases[FIRST]
|
||||||
batter.nextBase = bases[FIRST]
|
batter.nextBase = bases[FIRST]
|
||||||
|
batter.prevBase = bases[HOME]
|
||||||
batter.forcedTo = bases[FIRST]
|
batter.forcedTo = bases[FIRST]
|
||||||
batter = nil -- Demote batter to a mere runner
|
batter = nil -- Demote batter to a mere runner
|
||||||
|
|
||||||
|
@ -474,8 +477,6 @@ function updateRunning()
|
||||||
resetFielderPositions(false)
|
resetFielderPositions(false)
|
||||||
currentMode = MODES.batting
|
currentMode = MODES.batting
|
||||||
batter = newRunner()
|
batter = newRunner()
|
||||||
batter.nextBase = bases[FIRST]
|
|
||||||
batter.forcedTo = bases[FIRST]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -502,6 +503,7 @@ function updateGameState()
|
||||||
|
|
||||||
if currentMode == MODES.batting then
|
if currentMode == MODES.batting then
|
||||||
updateBatting()
|
updateBatting()
|
||||||
|
updateRunners()
|
||||||
elseif currentMode == MODES.running then
|
elseif currentMode == MODES.running then
|
||||||
updateRunning()
|
updateRunning()
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue