Bigger background for panning across.
Refactor out utils.lua
This commit is contained in:
parent
5493f350df
commit
8bbc029c42
Binary file not shown.
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 8.8 KiB |
118
src/main.lua
118
src/main.lua
|
@ -3,6 +3,7 @@ import 'CoreLibs/easing.lua'
|
|||
import 'CoreLibs/graphics.lua'
|
||||
import 'CoreLibs/object.lua'
|
||||
import 'CoreLibs/ui.lua'
|
||||
import 'utils.lua'
|
||||
|
||||
local gfx = playdate.graphics
|
||||
playdate.display.setRefreshRate(50)
|
||||
|
@ -16,7 +17,10 @@ local playerImage = playerHighHat
|
|||
local secPerFrame = 0.1
|
||||
local playerFrameElapsed = 0
|
||||
|
||||
local backgroundPan = -240
|
||||
local backgroundPan = {
|
||||
x = 0,
|
||||
y = 0,
|
||||
}
|
||||
|
||||
local pitchFlyTimeMs = 2500
|
||||
local ballStartY, endY = 90, 250
|
||||
|
@ -41,8 +45,8 @@ local batTipX = 0
|
|||
local batTipY = 0
|
||||
|
||||
local MODES = {
|
||||
batting = 0,
|
||||
running = 1
|
||||
batting = {},
|
||||
running = {}
|
||||
}
|
||||
local currentMode = MODES.batting
|
||||
|
||||
|
@ -53,7 +57,7 @@ local hitMult = 10
|
|||
|
||||
local deltaTime = 0
|
||||
|
||||
local basePositions = {
|
||||
local bases = {
|
||||
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 },
|
||||
|
@ -85,8 +89,8 @@ function resetFielderPositions()
|
|||
end
|
||||
resetFielderPositions()
|
||||
|
||||
local playerStartingX = basePositions.home.x - 40
|
||||
local playerStartingY = basePositions.home.y - 3
|
||||
local playerStartingX = bases.home.x - 40
|
||||
local playerStartingY = bases.home.y - 3
|
||||
local player = {
|
||||
x = playerStartingX,
|
||||
y = playerStartingY,
|
||||
|
@ -109,10 +113,6 @@ function throwBall(destX, destY)
|
|||
hitAnimatorX = gfx.animator.new(throwFlyTime, ballX, destX, playdate.easingFunctions.linear)
|
||||
end
|
||||
|
||||
function getNextThrowTarget()
|
||||
return basePositions.first.x, basePositions.first.y
|
||||
end
|
||||
|
||||
function pitch()
|
||||
pitchAnimator:reset()
|
||||
resetFielderPositions()
|
||||
|
@ -121,6 +121,9 @@ function pitch()
|
|||
ballX = 200
|
||||
currentMode = MODES.batting
|
||||
|
||||
backgroundPan.y = 0
|
||||
backgroundPan.x = 0
|
||||
|
||||
-- TODO: Add new runners, instead
|
||||
runners = {}
|
||||
player.x = playerStartingX
|
||||
|
@ -151,25 +154,6 @@ local pitchClockSec = 99
|
|||
local elapsedTime = 0
|
||||
local crankChange
|
||||
|
||||
function ballPassedThruBat(ballX, ballY, batBaseX, batBaseY, batTipX, batTipY)
|
||||
-- This check currently assumes right-handedness.
|
||||
-- I.e. it assumes the ball is to the right of batBaseX
|
||||
if ballX < batBaseX or ballX > batTipX or ballY > screenH then
|
||||
return false
|
||||
end
|
||||
|
||||
local m = (batTipY - batBaseY) / (batTipX - batBaseX)
|
||||
|
||||
-- y = mx + b
|
||||
-- b = y1 - (m * x1)
|
||||
local b = batBaseY - (m * batBaseX)
|
||||
local yOnLine = (m * ballX) + b
|
||||
local yP = ballY
|
||||
local yDelta = yOnLine - yP
|
||||
|
||||
return yDelta <= 0
|
||||
end
|
||||
|
||||
function updateInfield()
|
||||
if ballDestX == nil or ballDestY == nil then
|
||||
return
|
||||
|
@ -200,7 +184,15 @@ function updateRunners()
|
|||
if runner.nextBase then
|
||||
local nb = runner.nextBase
|
||||
local x, y, distance = normalizeVector(runner.x, runner.y, nb.x, nb.y)
|
||||
if distance > 1 then
|
||||
runner.hasArrived = distance <= 1
|
||||
|
||||
if runner.hasArrived then
|
||||
-- if runner.onArrive then
|
||||
-- runner.onArrive()
|
||||
-- end
|
||||
runner.targetX = nil
|
||||
runner.targetY = nil
|
||||
else
|
||||
local mult = 1
|
||||
if crankChange < 0 then
|
||||
mult = -1
|
||||
|
@ -208,31 +200,14 @@ function updateRunners()
|
|||
mult = (mult * runnerSpeed * deltaTime) + (crankChange / 20)
|
||||
runner.x -= x * mult
|
||||
runner.y -= y * mult
|
||||
else
|
||||
if runner.onArrive then
|
||||
runner.onArrive()
|
||||
end
|
||||
runner.targetX = nil
|
||||
runner.targetY = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function normalizeVector(x1, y1, x2, y2)
|
||||
local distance, a, b = distanceBetween(x1, y1, x2, y2)
|
||||
return a / distance, b / distance, distance
|
||||
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
|
||||
for _, fielder in pairs(fielders) do
|
||||
if nearestFielder == nil then
|
||||
nearestFielder = fielder
|
||||
nearestDistance = distanceBetween(fielder.x, fielder.y, x, y)
|
||||
|
@ -256,6 +231,15 @@ function throwArrivedBeforeRunner()
|
|||
return false
|
||||
end
|
||||
|
||||
function getForcedOutTargets()
|
||||
return { bases.first }
|
||||
end
|
||||
|
||||
function getNextThrowTarget()
|
||||
local targets = getForcedOutTargets()
|
||||
return targets[1].x, targets[1].y
|
||||
end
|
||||
|
||||
function updateGameState()
|
||||
deltaTime = playdate.getElapsedTime()
|
||||
playdate.resetElapsedTime()
|
||||
|
@ -281,7 +265,7 @@ function updateGameState()
|
|||
|
||||
crankChange, acceleratedChange = playdate.getCrankChange()
|
||||
if currentMode == MODES.batting and acceleratedChange >= 0 and
|
||||
ballPassedThruBat(ballX, ballY, batBaseX, batBaseY, batTipX, batTipY) then
|
||||
pointDirectlyUnderLine(ballX, ballY, batBaseX, batBaseY, batTipX, batTipY, screenH) then
|
||||
ballAngle = batAngle + math.rad(90)
|
||||
|
||||
mult = math.abs(acceleratedChange / 15)
|
||||
|
@ -301,10 +285,10 @@ function updateGameState()
|
|||
throwBall(getNextThrowTarget())
|
||||
chasingFielder.onArrive = nil
|
||||
end
|
||||
fielders.first.targetX = basePositions.first.x
|
||||
fielders.first.targetY = basePositions.first.y
|
||||
fielders.first.targetX = bases.first.x
|
||||
fielders.first.targetY = bases.first.y
|
||||
currentMode = MODES.running
|
||||
player.nextBase = basePositions.first
|
||||
player.nextBase = bases.first
|
||||
runners[#runners+1] = player
|
||||
end
|
||||
|
||||
|
@ -312,32 +296,52 @@ function updateGameState()
|
|||
updateRunners()
|
||||
updateInfield()
|
||||
end
|
||||
|
||||
-- TODO: Show baserunning minimap when panning?
|
||||
local ballBuffer = 5
|
||||
if ballY < ballBuffer then
|
||||
backgroundPan.y = math.max(ballBuffer, -1 * (ballY - ballBuffer))
|
||||
else backgroundPan.y = 0
|
||||
end
|
||||
if ballX < ballBuffer then
|
||||
backgroundPan.x = math.max(-400, -1 * (ballX - ballBuffer))
|
||||
elseif ballX > (screenW - ballBuffer) then
|
||||
backgroundPan.x = math.min(800, -1 * (ballX - ballBuffer))
|
||||
end
|
||||
|
||||
if ballX > 0 and ballX < (screenW - ballBuffer) then
|
||||
backgroundPan.x = 0
|
||||
end
|
||||
end
|
||||
|
||||
function playdate.update()
|
||||
updateGameState()
|
||||
|
||||
grassBackground:draw(0, backgroundPan)
|
||||
gfx.clear()
|
||||
grassBackground:draw(backgroundPan.x - 400, backgroundPan.y - 240)
|
||||
|
||||
gfx.setColor(gfx.kColorBlack)
|
||||
gfx.setLineWidth(2)
|
||||
gfx.drawCircleAtPoint(ballX, ballY, ballSize)
|
||||
gfx.drawCircleAtPoint(ballX + backgroundPan.x, ballY + backgroundPan.y, ballSize)
|
||||
|
||||
for title,fielder in pairs(fielders) do
|
||||
gfx.fillRect(fielder.x, fielder.y, 14, 25)
|
||||
gfx.fillRect(fielder.x + backgroundPan.x, fielder.y + backgroundPan.y, 14, 25)
|
||||
end
|
||||
|
||||
gfx.setLineWidth(5)
|
||||
|
||||
if currentMode == MODES.batting then
|
||||
gfx.drawLine(batBaseX, batBaseY, batTipX, batTipY)
|
||||
gfx.drawLine(
|
||||
batBaseX + backgroundPan.x, batBaseY + backgroundPan.y,
|
||||
batTipX + backgroundPan.x, batTipY + backgroundPan.y
|
||||
)
|
||||
end
|
||||
|
||||
if playdate.isCrankDocked() then
|
||||
playdate.ui.crankIndicator:draw()
|
||||
end
|
||||
|
||||
playerImage:draw(player.x, player.y)
|
||||
playerImage:draw(player.x + backgroundPan.x, player.y + backgroundPan.y)
|
||||
|
||||
-- TODO: Use gfx.animation.blinker instead
|
||||
if currentMode == MODES.running and playerFrameElapsed > secPerFrame then
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
--- Returns the normalized vector as two values, plus the distance between the given points.
|
||||
function normalizeVector(x1, y1, x2, y2)
|
||||
local distance, a, b = distanceBetween(x1, y1, x2, y2)
|
||||
return a / distance, b / distance, distance
|
||||
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 pointDirectlyUnderLine(pointX, pointY, lineX1, lineY1, lineX2, lineY2, bottomBound)
|
||||
-- This check currently assumes right-handedness.
|
||||
-- I.e. it assumes the ball is to the right of batBaseX
|
||||
if pointX < lineX1 or pointX > lineX2 or pointY > bottomBound then
|
||||
return false
|
||||
end
|
||||
|
||||
local m = (lineY2 - lineY1) / (lineX2 - lineX1)
|
||||
|
||||
-- y = mx + b
|
||||
-- b = y1 - (m * x1)
|
||||
local b = lineY1 - (m * lineX1)
|
||||
local yOnLine = (m * pointX) + b
|
||||
local yP = pointY
|
||||
local yDelta = yOnLine - yP
|
||||
|
||||
return yDelta <= 0
|
||||
end
|
||||
|
Loading…
Reference in New Issue