diff --git a/src/main.lua b/src/main.lua index 1e356dc..4150541 100644 --- a/src/main.lua +++ b/src/main.lua @@ -94,16 +94,16 @@ local Pitches = { x = gfx.animator.new(0, PitchStartX, PitchStartX, playdate.easingFunctions.linear), y = gfx.animator.new(PitchFlyMs / 1.3, PitchStartY, PitchEndY, playdate.easingFunctions.linear), }, - -- Slider - { - x = gfx.animator.new(PitchFlyMs, PitchStartX - 20, PitchStartX, utils.easingHill), - y = gfx.animator.new(PitchFlyMs, PitchStartY, PitchEndY, playdate.easingFunctions.linear), - }, -- Curve ball { x = gfx.animator.new(PitchFlyMs, PitchStartX + 20, PitchStartX, utils.easingHill), y = gfx.animator.new(PitchFlyMs, PitchStartY, PitchEndY, playdate.easingFunctions.linear), }, + -- Slider + { + x = gfx.animator.new(PitchFlyMs, PitchStartX - 20, PitchStartX, utils.easingHill), + y = gfx.animator.new(PitchFlyMs, PitchStartY, PitchEndY, playdate.easingFunctions.linear), + }, -- Wobbbleball { x = { @@ -322,11 +322,12 @@ local secondsSincePitchAllowed = -5 local catcherThrownBall = false ---@param pitchFlyTimeMs number | nil -function pitch(pitchFlyTimeMs) +---@param pitchTypeIndex number | nil +function pitch(pitchFlyTimeMs, pitchTypeIndex) catcherThrownBall = false offenseMode = Offense.batting - local current = Pitches[math.random(#Pitches)] + local current = Pitches[pitchTypeIndex or math.random(#Pitches)] ballAnimatorX = current.x ballAnimatorY = current.y or Pitches[1].y @@ -467,10 +468,12 @@ end function getBaseOfStrandedRunner() local farRunnersBase, farDistance for _, runner in pairs(runners) do - local nearestBase, distance = utils.getNearestOf(Bases, runner.x, runner.y) - if farRunnersBase == nil or farDistance < distance then - farRunnersBase = nearestBase - farDistance = distance + if runner ~= batter then + local nearestBase, distance = utils.getNearestOf(Bases, runner.x, runner.y) + if farRunnersBase == nil or farDistance < distance then + farRunnersBase = nearestBase + farDistance = distance + end end end @@ -721,10 +724,10 @@ function walkAwayOutRunners() end local npcBatDeg = 0 -local NpcBatSpeed = 1200 +local NpcBatSpeed = 1500 function npcBatAngle() - if not catcherThrownBall and ball.y > 190 and ball.y < 230 and (ball.x < Center.x + 15) then + if not catcherThrownBall and ball.y > 200 and ball.y < 230 and (ball.x < Center.x + 15) then npcBatDeg = npcBatDeg + (deltaSeconds * NpcBatSpeed) else npcBatDeg = 200 @@ -742,21 +745,51 @@ function npcRunningSpeed() end local touchedBase = isTouchingBase(runners[1].x, runners[1].y) if not touchedBase or touchedBase == Bases[Home] then - return 35 + return 25 end return 0 end -local pitchMeter = 0 +local throwMeter = 0 local PitchMeterLimit = 25 -function readPitch() - if pitchMeter > PitchMeterLimit then - return (PitchFlyMs / (pitchMeter / PitchMeterLimit)) +function readThrow() + if throwMeter > PitchMeterLimit then + return (PitchFlyMs / (throwMeter / PitchMeterLimit)) end return nil end +---@param thrower Fielder +---@param throwFlyMs number +---@return boolean didThrow +function buttonControlledThrow(thrower, throwFlyMs, forbidThrowHome) + local targetBase + if playdate.buttonIsPressed(playdate.kButtonLeft) then + throwBall(Bases[Third].x, Bases[Third].y, playdate.easingFunctions.linear, throwFlyMs) + targetBase = Bases[Third] + elseif playdate.buttonIsPressed(playdate.kButtonUp) then + throwBall(Bases[Second].x, Bases[Second].y, playdate.easingFunctions.linear, throwFlyMs) + targetBase = Bases[Second] -- TODO - or shortstop - whoever's closer + elseif playdate.buttonIsPressed(playdate.kButtonRight) then + throwBall(Bases[First].x, Bases[First].y, playdate.easingFunctions.linear, throwFlyMs) + targetBase = Bases[First] + elseif not forbidThrowHome and playdate.buttonIsPressed(playdate.kButtonDown) then + throwBall(Bases[Home].x, Bases[Home].y, playdate.easingFunctions.linear, throwFlyMs) + targetBase = Bases[Home] + else + return false + end + + local closestFielder = utils.getNearestOf(fielders, targetBase.x, targetBase.y, function(fielder) + return fielder ~= thrower + end) + closestFielder.target = targetBase + secondsSinceLastRunnerMove = 0 + offenseMode = Offense.running + return true +end + function updateGameState() deltaSeconds = playdate.getElapsedTime() or 0 playdate.resetElapsedTime() @@ -778,24 +811,31 @@ function updateGameState() throwBall(PitchStartX, PitchStartY, playdate.easingFunctions.linear, nil, true) catcherThrownBall = true else - pitchMeter = 0 + throwMeter = 0 end if not playerOnOffense then - pitchMeter = math.max(0, pitchMeter - (deltaSeconds * 150)) - pitchMeter = pitchMeter + crankChange - if pitchMeter > PitchMeterLimit then - printTable({ pitchMeter = pitchMeter }) - end + throwMeter = math.max(0, throwMeter - (deltaSeconds * 150)) + throwMeter = throwMeter + crankChange end if secondsSincePitchAllowed > PitchAfterSeconds then if playerOnOffense then pitch(PitchFlyMs) else - local pitchFly = readPitch() - if pitchFly then - pitch(pitchFly) + local throwFly = readThrow() + if throwFly and not buttonControlledThrow(fielders.pitcher, throwFly, true) then + local aButton = playdate.buttonIsPressed(playdate.kButtonA) + local bButton = playdate.buttonIsPressed(playdate.kButtonB) + if not aButton and not bButton then + pitch(throwFly, 1) + elseif aButton and not bButton then + pitch(throwFly, 2) + elseif not aButton and bButton then + pitch(throwFly, 3) + elseif aButton and bButton then + pitch(throwFly, 4) + end end end end @@ -814,7 +854,9 @@ function updateGameState() throwBall(PitchStartX, PitchStartY, playdate.easingFunctions.linear, nil, true) resetFielderPositions() offenseMode = Offense.batting - batter = newRunner() + if not batter then + batter = newRunner() + end end end end @@ -829,11 +871,10 @@ function drawMinimap() end ---@param fielder Fielder ---@return boolean isHoldingBall function drawFielderGlove(fielder) - printTable({ ballFloatValue = ballFloatAnimator:currentValue() }) local distanceFromBall = utils.distanceBetweenZ(fielder.x, fielder.y, 0, ball.x, ball.y, ballFloatAnimator:currentValue()) local shoulderX, shoulderY = fielder.x + 10, fielder.y + FielderDanceAnimator:currentValue() + 5 - if distanceFromBall > 30 then + if distanceFromBall > 20 then Glove:draw(shoulderX, shoulderY) return false else diff --git a/src/utils.lua b/src/utils.lua index 0f72f17..3de3407 100644 --- a/src/utils.lua +++ b/src/utils.lua @@ -43,8 +43,8 @@ end ---@param y2 number ---@return number x, number y, number distance function utils.normalizeVector(x1, y1, x2, y2) - local distance, a, b = utils.distanceBetween(x1, y1, x2, y2) - return a / distance, b / distance, distance + local distance, x, y = utils.distanceBetween(x1, y1, x2, y2) + return x / distance, y / distance, distance end ---@generic T @@ -63,17 +63,17 @@ end ---@return number distance, number x, number y function utils.distanceBetween(x1, y1, x2, y2) - local a = x1 - x2 - local b = y1 - y2 - return math.sqrt((a * a) + (b * b)), a, b + local x = x1 - x2 + local y = y1 - y2 + return math.sqrt((x * x) + (y * y)), x, y end ----@return number distance, number x, number y +---@return number distance, number x, number y, number z function utils.distanceBetweenZ(x1, y1, z1, x2, y2, z2) - local a = x1 - x2 - local b = y1 - y2 - local c = z1 - z2 - return math.sqrt((a * a) + (b * b) + (c * c)), a, b + local x = x1 - x2 + local y = y1 - y2 + local z = z1 - z2 + return math.sqrt((x * x) + (y * y) + (z * z)), x, y, z end --- Returns true only if the point is below the given line, within the x bounds of said line, and above the bottomBound