From 32f9b24d1fad6fe1e81043581e5538dc85f53f95 Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt Date: Sat, 1 Feb 2025 16:26:44 -0500 Subject: [PATCH] Add batter walk-up. Attach bat to batter. Prevent draw-offset changes when the ball is below the screen. --- src/graphics.lua | 5 ++++- src/main.lua | 42 ++++++++++++++++++++++-------------------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/graphics.lua b/src/graphics.lua index 81e0c77..e07f182 100644 --- a/src/graphics.lua +++ b/src/graphics.lua @@ -4,8 +4,11 @@ local ballBuffer = 5 --- XXX --- XOX --- 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 + if ballY > screenH then + return 0, 0 + end if ballY < ballBuffer then offsetY = math.max(ballBuffer, -1 * (ballY - ballBuffer)) else diff --git a/src/main.lua b/src/main.lua index 2013aa9..64c340c 100644 --- a/src/main.lua +++ b/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 CRANK_OFFSET_DEG = 90 +local BAT_OFFSET = xy(10, 25) local batBase = xy(CENTER.x - 34, 215) local batTip = xy(0, 0) @@ -53,7 +54,7 @@ local TAG_DISTANCE = 20 local ball = { x = CENTER.x, - y = BALL_OFFSCREEN, + y = CENTER.y, size = 6, } @@ -88,6 +89,9 @@ local bases = { 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 local nextBaseMap = { [bases[FIRST]] = bases[SECOND], @@ -155,11 +159,12 @@ local runnerNames = { "Barbara", "Steve", "Jerry", "Beatrice" } ---@return Runner function newRunner() local new = { - x = PLAYER_STARTING_X, - y = PLAYER_STARTING_Y, - nextBase = nil, + x = PLAYER_STARTING_X - 60, + y = PLAYER_STARTING_Y + 60, + nextBase = rightHandedBattersBox, prevBase = nil, name = runnerNames[nameI], + forcedTo = bases[FIRST] } nameI = nameI + 1 runners[#runners + 1] = new @@ -168,8 +173,6 @@ end ---@type Runner | nil local batter = newRunner() -batter.nextBase = bases[FIRST] -batter.forcedTo = bases[FIRST] --- "Throws" the ball from its current position to the given destination. function throwBall(destX, destY, easingFunc, flyTimeMs, floaty) @@ -243,7 +246,6 @@ local homeScore = 0 local awayScore = 0 function outRunner(runnerIndex) - print("You're out, runner" .. runnerIndex .. "!") outs = math.min(3, outs + 1) outRunners[#outRunners + 1] = runners[runnerIndex] table.remove(runners, runnerIndex) @@ -285,14 +287,10 @@ function updateFielders() local touchedBase = isTouchingBase(fielder.x, fielder.y) for i, runner in pairs(runners) do local runnerOnBase = touchingBaseCache.get(runner) - if touchedBase and runner.forcedTo == touchedBase and touchedBase ~= runnerOnBase then - print("Force out of runner:") - printTable(runner) + if touchedBase and runner.prevBase and runner.forcedTo == touchedBase and touchedBase ~= runnerOnBase then outRunner(i) elseif not runnerOnBase then - local fielderDistance = distanceBetween(runner.x, runner.y, fielder.x, fielder.y) - if fielderDistance < TAG_DISTANCE then - print("Tagged out!") + if distanceBetween(runner.x, runner.y, fielder.x, fielder.y) < TAG_DISTANCE then outRunner(i) end end @@ -306,14 +304,14 @@ end function updateRunners() local autoRunSpeed = 20 --autoRunSpeed = 140 - local nonPlayerRunners = filter(runners, function(runner) + local currentRunners = currentMode == MODES.batting and {batter} or filter(runners, function(runner) return runner ~= batter end) 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) - 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) end if runner.nextBase then @@ -401,7 +399,7 @@ end local resetFieldersAfterSeconds = 4 local secondsSinceLastRunnerMove = 0 -local pitchAfterSeconds = 4 +local pitchAfterSeconds = 5 local secondsSincePitchAllowed = -5 function init() @@ -418,11 +416,14 @@ function updateBatting() secondsSincePitchAllowed = 0 end if ball.y < BALL_OFFSCREEN then - ball.y = ballAnimatorY:currentValue() + ball.y = ballAnimatorY:currentValue() + ballFloatAnimator:currentValue() ball.size = 6 end 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.y = batBase.y + (BAT_LENGTH * math.cos(batAngle)) @@ -443,10 +444,12 @@ function updateBatting() end local ballDestX = ball.x + (ballVelX * HIT_MULT) local ballDestY = ball.y + (ballVelY * HIT_MULT) + -- Hit! throwBall(ballDestX, ballDestY, playdate.easingFunctions.outQuint, 2000) fielders.first.target = bases[FIRST] batter.nextBase = bases[FIRST] + batter.prevBase = bases[HOME] batter.forcedTo = bases[FIRST] batter = nil -- Demote batter to a mere runner @@ -474,8 +477,6 @@ function updateRunning() resetFielderPositions(false) currentMode = MODES.batting batter = newRunner() - batter.nextBase = bases[FIRST] - batter.forcedTo = bases[FIRST] end end end @@ -502,6 +503,7 @@ function updateGameState() if currentMode == MODES.batting then updateBatting() + updateRunners() elseif currentMode == MODES.running then updateRunning() end