Add simple fielder chasing and throwing mechanics.

This commit is contained in:
Sage Vaillancourt 2025-01-26 17:24:32 -05:00
parent 5df107f767
commit 42a537dae0
1 changed files with 99 additions and 5 deletions

View File

@ -40,14 +40,44 @@ local hitAnimatorX
local hitMult = 10
local deltaTime = 0
local basePositions = {
first = { x = screenW * 0.93, y = screenH * 0.52 },
second = { x = screenW * 0.47, y = screenH * 0.19 },
third = { x = screenW * 0.03, y = screenH * 0.52 },
home = { x = screenW * 0.474, y = screenH * 0.79 }
}
local fielders
function resetFielders()
fielders = {
first = { x = screenW - 65, y = screenH * 0.48 },
second = { x = screenW * 0.70, y = screenH * 0.30 },
shortstop = { x = screenW * 0.30, y = screenH * 0.30 },
third = { x = screenW * 0.1, y = screenH * 0.48 },
pitcher = { x = screenW * 0.48, y = screenH * 0.40 }
}
end
resetFielders()
function hitBall(destX, destY, hitFlyTime)
ballSizeAnimator:reset()
ballSizeAnimator:reset(ballSizeMs)
hitAnimatorY = gfx.animator.new(hitFlyTime, ballY, destY, playdate.easingFunctions.outQuint)
hitAnimatorX = gfx.animator.new(hitFlyTime, ballX, destX, playdate.easingFunctions.outQuint)
end
function throwBall(destX, destY)
local throwFlyTime = distanceBetween(ballX, ballY, destX, destY) * 5
ballSizeAnimator:reset(throwFlyTime)
hitAnimatorY = gfx.animator.new(throwFlyTime, ballY, destY, playdate.easingFunctions.linear)
hitAnimatorX = gfx.animator.new(throwFlyTime, ballX, destX, playdate.easingFunctions.linear)
end
function pitch()
pitchAnimator:reset()
resetFielders()
ballVelX = 0
ballVelY = 0
ballX = 200
@ -74,7 +104,7 @@ function playdate.leftButtonDown()
batBaseX -= 1
end
local pitchClockSec = 5
local pitchClockSec = 99
local elapsedTime = 0
function ballPassedThruBat(ballX, ballY, batBaseX, batBaseY, batTipX, batTipY)
@ -96,8 +126,57 @@ function ballPassedThruBat(ballX, ballY, batBaseX, batBaseY, batTipX, batTipY)
return yDelta <= 0
end
function updateInfield()
if not hit or ballDestX == nil or ballDestY == nil then
return
end
local fielderSpeed = 50
for title,fielder in pairs(fielders) do
if fielder.targetX ~= nil and fielder.targetY ~= nil then
local distance, a, b = distanceBetween(fielder.x, fielder.y, fielder.targetX, fielder.targetY)
local normalizer = fielderSpeed / distance
if distance > 1 then
fielder.x -= a * normalizer * deltaTime
fielder.y -= b * normalizer * deltaTime
else
if fielder.onArrive then
fielder.onArrive(fielder.targetX, fielder.targetY)
end
fielder.targetX = nil
fielder.targetY = nil
end
end
end
end
function distanceBetween(x1, y1, x2, y2)
local a = x1 - x2
local b = y1 - y2
return math.sqrt((a*a) + (b*b)), a, b
end
function getNearestFielder(x, y)
local nearestFielder, nearestDistance = nil, nil
for title,fielder in pairs(fielders) do
if nearestFielder == nil then
nearestFielder = fielder
nearestDistance = distanceBetween(fielder.x, fielder.y, x, y)
else
local distance = distanceBetween(fielder.x, fielder.y, x, y)
if distance < nearestDistance then
nearestFielder = fielder
nearestDistance = distance
end
end
end
return nearestFielder
end
function updateGameState()
local deltaTime = playdate.getElapsedTime()
deltaTime = playdate.getElapsedTime()
playdate.resetElapsedTime()
elapsedTime = elapsedTime + deltaTime
@ -119,10 +198,11 @@ function updateGameState()
batTipX = batBaseX + (batLength * math.sin(batAngle))
batTipY = batBaseY + (batLength * math.cos(batAngle))
if hit == false and ballPassedThruBat(ballX, ballY, batBaseX, batBaseY, batTipX, batTipY) then
crankChange, acceleratedChange = playdate.getCrankChange()
if hit == false and acceleratedChange >= 0 and
ballPassedThruBat(ballX, ballY, batBaseX, batBaseY, batTipX, batTipY) then
ballAngle = batAngle + math.rad(90)
crankChange, acceleratedChange = playdate.getCrankChange()
mult = math.abs(acceleratedChange / 15)
ballVelX = mult * 10 * math.sin(ballAngle)
ballVelY = mult * 5 * math.cos(ballAngle)
@ -133,9 +213,19 @@ function updateGameState()
ballDestX = ballX + (ballVelX * hitMult)
ballDestY = ballY + (ballVelY * hitMult)
hitBall(ballDestX, ballDestY, 2000)
local chasingFielder = getNearestFielder(ballDestX, ballDestY)
chasingFielder.targetX = ballDestX
chasingFielder.targetY = ballDestY
chasingFielder.onArrive = function()
throwBall(basePositions.first.x, basePositions.first.y)
end
fielders.first.targetX = basePositions.first.x
fielders.first.targetY = basePositions.first.y
hit = true
end
lastBallY = ballY
updateInfield()
end
function playdate.update()
@ -147,6 +237,10 @@ function playdate.update()
gfx.setLineWidth(2)
gfx.drawCircleAtPoint(ballX, ballY, ballSize)
for title,fielder in pairs(fielders) do
gfx.fillRect(fielder.x, fielder.y, 14, 25)
end
gfx.setLineWidth(5)
gfx.drawLine(batBaseX, batBaseY, batTipX, batTipY)