Start up some simple baserunning.
This commit is contained in:
parent
5fc72c46fe
commit
5493f350df
|
@ -1 +1,2 @@
|
||||||
*.pdx
|
*.pdx
|
||||||
|
.idea
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
Binary file not shown.
After Width: | Height: | Size: 711 B |
125
src/main.lua
125
src/main.lua
|
@ -7,9 +7,16 @@ import 'CoreLibs/ui.lua'
|
||||||
local gfx = playdate.graphics
|
local gfx = playdate.graphics
|
||||||
playdate.display.setRefreshRate(50)
|
playdate.display.setRefreshRate(50)
|
||||||
gfx.setBackgroundColor(gfx.kColorWhite)
|
gfx.setBackgroundColor(gfx.kColorWhite)
|
||||||
|
playdate.setMenuImage(gfx.image.new("images/game/menu-image.png"))
|
||||||
|
|
||||||
local grassBackground = gfx.image.new("images/game/grass.png")
|
local grassBackground = gfx.image.new("images/game/grass.png")
|
||||||
local playerImage = gfx.image.new("images/game/player.png")
|
local playerHighHat = gfx.image.new("images/game/player.png")
|
||||||
|
local playerLowHat = gfx.image.new("images/game/player-lowhat.png")
|
||||||
|
local playerImage = playerHighHat
|
||||||
|
local secPerFrame = 0.1
|
||||||
|
local playerFrameElapsed = 0
|
||||||
|
|
||||||
|
local backgroundPan = -240
|
||||||
|
|
||||||
local pitchFlyTimeMs = 2500
|
local pitchFlyTimeMs = 2500
|
||||||
local ballStartY, endY = 90, 250
|
local ballStartY, endY = 90, 250
|
||||||
|
@ -26,7 +33,6 @@ local batBaseX, batBaseY = centerX - 34, 215
|
||||||
local batLength = 45
|
local batLength = 45
|
||||||
|
|
||||||
local ballY = ballStartY
|
local ballY = ballStartY
|
||||||
local lastBallY = ballY
|
|
||||||
local ballX = 200
|
local ballX = 200
|
||||||
local ballVelX, ballVelY = 0, 0
|
local ballVelX, ballVelY = 0, 0
|
||||||
local ballSize = 6
|
local ballSize = 6
|
||||||
|
@ -34,7 +40,6 @@ local ballSize = 6
|
||||||
local batTipX = 0
|
local batTipX = 0
|
||||||
local batTipY = 0
|
local batTipY = 0
|
||||||
|
|
||||||
local hit = false
|
|
||||||
local MODES = {
|
local MODES = {
|
||||||
batting = 0,
|
batting = 0,
|
||||||
running = 1
|
running = 1
|
||||||
|
@ -80,13 +85,17 @@ function resetFielderPositions()
|
||||||
end
|
end
|
||||||
resetFielderPositions()
|
resetFielderPositions()
|
||||||
|
|
||||||
|
local playerStartingX = basePositions.home.x - 40
|
||||||
|
local playerStartingY = basePositions.home.y - 3
|
||||||
local player = {
|
local player = {
|
||||||
x = basePositions.home.x - 40,
|
x = playerStartingX,
|
||||||
y = basePositions.home.y - 3,
|
y = playerStartingY,
|
||||||
nextBase = nil,
|
nextBase = nil,
|
||||||
prevBase = nil,
|
prevBase = nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local runners = { }
|
||||||
|
|
||||||
function hitBall(destX, destY, hitFlyTime)
|
function hitBall(destX, destY, hitFlyTime)
|
||||||
ballSizeAnimator:reset(ballSizeMs)
|
ballSizeAnimator:reset(ballSizeMs)
|
||||||
hitAnimatorY = gfx.animator.new(hitFlyTime, ballY, destY, playdate.easingFunctions.outQuint)
|
hitAnimatorY = gfx.animator.new(hitFlyTime, ballY, destY, playdate.easingFunctions.outQuint)
|
||||||
|
@ -100,13 +109,22 @@ function throwBall(destX, destY)
|
||||||
hitAnimatorX = gfx.animator.new(throwFlyTime, ballX, destX, playdate.easingFunctions.linear)
|
hitAnimatorX = gfx.animator.new(throwFlyTime, ballX, destX, playdate.easingFunctions.linear)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function getNextThrowTarget()
|
||||||
|
return basePositions.first.x, basePositions.first.y
|
||||||
|
end
|
||||||
|
|
||||||
function pitch()
|
function pitch()
|
||||||
pitchAnimator:reset()
|
pitchAnimator:reset()
|
||||||
resetFielderPositions()
|
resetFielderPositions()
|
||||||
ballVelX = 0
|
ballVelX = 0
|
||||||
ballVelY = 0
|
ballVelY = 0
|
||||||
ballX = 200
|
ballX = 200
|
||||||
hit = false
|
currentMode = MODES.batting
|
||||||
|
|
||||||
|
-- TODO: Add new runners, instead
|
||||||
|
runners = {}
|
||||||
|
player.x = playerStartingX
|
||||||
|
player.y = playerStartingY
|
||||||
end
|
end
|
||||||
|
|
||||||
function playdate.AButtonDown()
|
function playdate.AButtonDown()
|
||||||
|
@ -131,6 +149,7 @@ end
|
||||||
|
|
||||||
local pitchClockSec = 99
|
local pitchClockSec = 99
|
||||||
local elapsedTime = 0
|
local elapsedTime = 0
|
||||||
|
local crankChange
|
||||||
|
|
||||||
function ballPassedThruBat(ballX, ballY, batBaseX, batBaseY, batTipX, batTipY)
|
function ballPassedThruBat(ballX, ballY, batBaseX, batBaseY, batTipX, batTipY)
|
||||||
-- This check currently assumes right-handedness.
|
-- This check currently assumes right-handedness.
|
||||||
|
@ -152,22 +171,21 @@ function ballPassedThruBat(ballX, ballY, batBaseX, batBaseY, batTipX, batTipY)
|
||||||
end
|
end
|
||||||
|
|
||||||
function updateInfield()
|
function updateInfield()
|
||||||
if not hit or ballDestX == nil or ballDestY == nil then
|
if ballDestX == nil or ballDestY == nil then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local fielderSpeed = 50
|
local fielderSpeed = 40
|
||||||
for title,fielder in pairs(fielders) do
|
for title,fielder in pairs(fielders) do
|
||||||
if fielder.targetX ~= nil and fielder.targetY ~= nil then
|
if fielder.targetX ~= nil and fielder.targetY ~= nil then
|
||||||
local distance, a, b = distanceBetween(fielder.x, fielder.y, fielder.targetX, fielder.targetY)
|
local x, y, distance = normalizeVector(fielder.x, fielder.y, fielder.targetX, fielder.targetY)
|
||||||
local normalizer = fielderSpeed / distance
|
|
||||||
|
|
||||||
if distance > 1 then
|
if distance > 1 then
|
||||||
fielder.x -= a * normalizer * deltaTime
|
fielder.x -= x * fielderSpeed * deltaTime
|
||||||
fielder.y -= b * normalizer * deltaTime
|
fielder.y -= y * fielderSpeed * deltaTime
|
||||||
else
|
else
|
||||||
if fielder.onArrive then
|
if fielder.onArrive then
|
||||||
fielder.onArrive(fielder.targetX, fielder.targetY)
|
fielder.onArrive()
|
||||||
end
|
end
|
||||||
fielder.targetX = nil
|
fielder.targetX = nil
|
||||||
fielder.targetY = nil
|
fielder.targetY = nil
|
||||||
|
@ -176,6 +194,36 @@ function updateInfield()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function updateRunners()
|
||||||
|
local runnerSpeed = 20
|
||||||
|
for i,runner in pairs(runners) do
|
||||||
|
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
|
||||||
|
local mult = 1
|
||||||
|
if crankChange < 0 then
|
||||||
|
mult = -1
|
||||||
|
end
|
||||||
|
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)
|
function distanceBetween(x1, y1, x2, y2)
|
||||||
local a = x1 - x2
|
local a = x1 - x2
|
||||||
local b = y1 - y2
|
local b = y1 - y2
|
||||||
|
@ -200,6 +248,14 @@ function getNearestFielder(x, y)
|
||||||
return nearestFielder
|
return nearestFielder
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function ballIsBeingThrown()
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function throwArrivedBeforeRunner()
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
function updateGameState()
|
function updateGameState()
|
||||||
deltaTime = playdate.getElapsedTime()
|
deltaTime = playdate.getElapsedTime()
|
||||||
playdate.resetElapsedTime()
|
playdate.resetElapsedTime()
|
||||||
|
@ -210,7 +266,7 @@ function updateGameState()
|
||||||
pitch()
|
pitch()
|
||||||
end
|
end
|
||||||
|
|
||||||
if hit then
|
if currentMode == MODES.running then
|
||||||
ballX = hitAnimatorX:currentValue()
|
ballX = hitAnimatorX:currentValue()
|
||||||
ballY = hitAnimatorY:currentValue()
|
ballY = hitAnimatorY:currentValue()
|
||||||
ballSize = ballSizeAnimator:currentValue()
|
ballSize = ballSizeAnimator:currentValue()
|
||||||
|
@ -224,7 +280,7 @@ function updateGameState()
|
||||||
batTipY = batBaseY + (batLength * math.cos(batAngle))
|
batTipY = batBaseY + (batLength * math.cos(batAngle))
|
||||||
|
|
||||||
crankChange, acceleratedChange = playdate.getCrankChange()
|
crankChange, acceleratedChange = playdate.getCrankChange()
|
||||||
if hit == false and acceleratedChange >= 0 and
|
if currentMode == MODES.batting and acceleratedChange >= 0 and
|
||||||
ballPassedThruBat(ballX, ballY, batBaseX, batBaseY, batTipX, batTipY) then
|
ballPassedThruBat(ballX, ballY, batBaseX, batBaseY, batTipX, batTipY) then
|
||||||
ballAngle = batAngle + math.rad(90)
|
ballAngle = batAngle + math.rad(90)
|
||||||
|
|
||||||
|
@ -242,22 +298,26 @@ function updateGameState()
|
||||||
chasingFielder.targetX = ballDestX
|
chasingFielder.targetX = ballDestX
|
||||||
chasingFielder.targetY = ballDestY
|
chasingFielder.targetY = ballDestY
|
||||||
chasingFielder.onArrive = function()
|
chasingFielder.onArrive = function()
|
||||||
throwBall(basePositions.first.x, basePositions.first.y)
|
throwBall(getNextThrowTarget())
|
||||||
|
chasingFielder.onArrive = nil
|
||||||
end
|
end
|
||||||
fielders.first.targetX = basePositions.first.x
|
fielders.first.targetX = basePositions.first.x
|
||||||
fielders.first.targetY = basePositions.first.y
|
fielders.first.targetY = basePositions.first.y
|
||||||
hit = true
|
currentMode = MODES.running
|
||||||
|
player.nextBase = basePositions.first
|
||||||
|
runners[#runners+1] = player
|
||||||
end
|
end
|
||||||
lastBallY = ballY
|
|
||||||
|
|
||||||
updateInfield()
|
if currentMode == MODES.running then
|
||||||
|
updateRunners()
|
||||||
|
updateInfield()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function playdate.update()
|
function playdate.update()
|
||||||
updateGameState()
|
updateGameState()
|
||||||
|
|
||||||
grassBackground:draw(0, 0)
|
grassBackground:draw(0, backgroundPan)
|
||||||
playerImage:draw(player.x, player.y)
|
|
||||||
|
|
||||||
gfx.setColor(gfx.kColorBlack)
|
gfx.setColor(gfx.kColorBlack)
|
||||||
gfx.setLineWidth(2)
|
gfx.setLineWidth(2)
|
||||||
|
@ -268,9 +328,30 @@ function playdate.update()
|
||||||
end
|
end
|
||||||
|
|
||||||
gfx.setLineWidth(5)
|
gfx.setLineWidth(5)
|
||||||
gfx.drawLine(batBaseX, batBaseY, batTipX, batTipY)
|
|
||||||
|
if currentMode == MODES.batting then
|
||||||
|
gfx.drawLine(batBaseX, batBaseY, batTipX, batTipY)
|
||||||
|
end
|
||||||
|
|
||||||
if playdate.isCrankDocked() then
|
if playdate.isCrankDocked() then
|
||||||
playdate.ui.crankIndicator:draw()
|
playdate.ui.crankIndicator:draw()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
playerImage:draw(player.x, player.y)
|
||||||
|
|
||||||
|
-- TODO: Use gfx.animation.blinker instead
|
||||||
|
if currentMode == MODES.running and playerFrameElapsed > secPerFrame then
|
||||||
|
playerFrameElapsed = 0
|
||||||
|
if playerImage == playerHighHat then
|
||||||
|
playerImage = playerLowHat
|
||||||
|
else
|
||||||
|
playerImage = playerHighHat
|
||||||
|
end
|
||||||
|
else
|
||||||
|
playerFrameElapsed += deltaTime
|
||||||
|
end
|
||||||
|
|
||||||
|
-- for i,runner in pairs(runners) do
|
||||||
|
-- playerImage:draw(runner.x, runner.y)
|
||||||
|
-- end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue