From 5493f350df59de3ed572ecb1685a2892831fca3a Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt <sage@sagev.space> Date: Sun, 26 Jan 2025 21:34:19 -0500 Subject: [PATCH] Start up some simple baserunning. --- .gitignore | 1 + src/images/game/grass.png | Bin 2241 -> 2915 bytes src/images/game/menu-image.png | Bin 0 -> 11102 bytes src/images/game/player-lowhat.png | Bin 0 -> 711 bytes src/main.lua | 125 ++++++++++++++++++++++++------ 5 files changed, 104 insertions(+), 22 deletions(-) create mode 100644 src/images/game/menu-image.png create mode 100644 src/images/game/player-lowhat.png diff --git a/.gitignore b/.gitignore index e00b594..66f1578 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.pdx +.idea diff --git a/src/images/game/grass.png b/src/images/game/grass.png index 4da3e6e1eb5618a0d93e26823e39d68bc5b3b354..ab545fbe3f36daa1efc78d0baa7a15106255f4b1 100644 GIT binary patch delta 460 zcmX>o_*iU$7&qes4mJh`hVHr6yc-o~G8zKe3=BV=ch>_c&H|6fVg?31We{epSZZGe z6l5>)^mS!_$tcYv$5f{?IdbxAMs+4m>&YTa4=3+s(yC`*Vrpn$P*7mt-~ckI&jT9^ zw*iCagk(L2Byn<+3z-}z$1!P5zQZI5^pXV-%Oq3ZBWQv1NNDl}CRM0?e8L#^9Z28& cooO4ZNaKCeBN4g^0ibyDboFyt=akR{04cIdMgRZ+ delta 112 zcmaDXc2IDF7&pTQ4mJh`20a@irHzU+84dq40O5kY%O?W`ISV`@i-B^=Ak0{?)V>TT z$X?><>&pI;QA$`w=*w6CxszWrsxz_8oGilhkm*3(=9#S9SViU+8b8^&Q=|o`oWax8 K&t;ucLK6UPLnAi; diff --git a/src/images/game/menu-image.png b/src/images/game/menu-image.png new file mode 100644 index 0000000000000000000000000000000000000000..baa6ddb1fc45d28669133aee5d4797bda87784ea GIT binary patch literal 11102 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 literal 0 HcmV?d00001 diff --git a/src/images/game/player-lowhat.png b/src/images/game/player-lowhat.png new file mode 100644 index 0000000000000000000000000000000000000000..985867e065b135650bc751e00729dced5d051e81 GIT binary patch literal 711 zcmV;&0yzDNP)<h;3K|Lk000e1NJLTq000&M001Zm1^@s6`os$60004mX+uL$Nkc;* zaB^>EX>4Tx04R}tkv&MmP!xqvQ$>-Af*n*GGPF*1Q4z;lg(6f4wL+^7CNKSiCJjl7 zi=*ILaPVib>fqw6tAnc`2>yV$3r>nIQsR9{p+$@r9`ED4dk*j22MCP{)2yyIpy{@m zPA0@`ZdL4gMF1lhL=*v;S;m|srQlm%_tZ^w7vov}eScQJnztAb5Q*c=Fm2)u;+aj` z;Ji;9W+hoAJ|~_q>4L<MTvt4P<6LxE;F)1Flb$CI6N|+TRyvrKOpSP&IHGDg<qKJl zRnA+SwMvb(?#W*m%Iho3T&FdLBo?s*2_h8KP(}qdVzld|SV+@(!pA@A`XzEH<SK)a zV*yoYkX=9cAN-!JRhXLel0pff`^9lSqCn3s(5ySo_p#$NPk`VvaHY5X)dn#8NqW7l zMUH@hZQ$a%ttorJ<qk0XWXPuMN<msep#Z#}(KqFQp<AGD&6`{69H$RJhGvzz0S*p< z@gilf`@Flib8i3kwC48%XlinzGWX+!00006VoOIv0RI600RN!9r;`8x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru=>Z!7Gcn_k7Wn`G02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{005s!L_t(Y$L&^I4!|G?vu5|dGW&8d3LE%fbCFMlN-GdT zSj}MYB}*(C096?A4JoJx3!Px1xkzzkOJqwNKz*bEOo93R-Pu$rVk>>Nj53V*8IQKZ zN>MAFf5uF0s@eSP^Abf#lJ9+9Z%1O}4EB{mLzx?ulFxc|yn#1xUCus3h#Qel9Vv}f tb`z2w$XmK>?=oiUQb<OB)w;W09iOgYLp}J!*|`7!002ovPDHLkV1lX@FAM+x literal 0 HcmV?d00001 diff --git a/src/main.lua b/src/main.lua index 6cd6b2b..996fe1d 100644 --- a/src/main.lua +++ b/src/main.lua @@ -7,9 +7,16 @@ import 'CoreLibs/ui.lua' local gfx = playdate.graphics playdate.display.setRefreshRate(50) gfx.setBackgroundColor(gfx.kColorWhite) +playdate.setMenuImage(gfx.image.new("images/game/menu-image.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 ballStartY, endY = 90, 250 @@ -26,7 +33,6 @@ local batBaseX, batBaseY = centerX - 34, 215 local batLength = 45 local ballY = ballStartY -local lastBallY = ballY local ballX = 200 local ballVelX, ballVelY = 0, 0 local ballSize = 6 @@ -34,7 +40,6 @@ local ballSize = 6 local batTipX = 0 local batTipY = 0 -local hit = false local MODES = { batting = 0, running = 1 @@ -80,13 +85,17 @@ function resetFielderPositions() end resetFielderPositions() +local playerStartingX = basePositions.home.x - 40 +local playerStartingY = basePositions.home.y - 3 local player = { - x = basePositions.home.x - 40, - y = basePositions.home.y - 3, + x = playerStartingX, + y = playerStartingY, nextBase = nil, prevBase = nil, } +local runners = { } + function hitBall(destX, destY, hitFlyTime) ballSizeAnimator:reset(ballSizeMs) 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) end +function getNextThrowTarget() + return basePositions.first.x, basePositions.first.y +end + function pitch() pitchAnimator:reset() resetFielderPositions() ballVelX = 0 ballVelY = 0 ballX = 200 - hit = false + currentMode = MODES.batting + + -- TODO: Add new runners, instead + runners = {} + player.x = playerStartingX + player.y = playerStartingY end function playdate.AButtonDown() @@ -131,6 +149,7 @@ end local pitchClockSec = 99 local elapsedTime = 0 +local crankChange function ballPassedThruBat(ballX, ballY, batBaseX, batBaseY, batTipX, batTipY) -- This check currently assumes right-handedness. @@ -152,22 +171,21 @@ function ballPassedThruBat(ballX, ballY, batBaseX, batBaseY, batTipX, batTipY) end function updateInfield() - if not hit or ballDestX == nil or ballDestY == nil then + if ballDestX == nil or ballDestY == nil then return end - local fielderSpeed = 50 + local fielderSpeed = 40 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 + local x, y, distance = normalizeVector(fielder.x, fielder.y, fielder.targetX, fielder.targetY) if distance > 1 then - fielder.x -= a * normalizer * deltaTime - fielder.y -= b * normalizer * deltaTime + fielder.x -= x * fielderSpeed * deltaTime + fielder.y -= y * fielderSpeed * deltaTime else if fielder.onArrive then - fielder.onArrive(fielder.targetX, fielder.targetY) + fielder.onArrive() end fielder.targetX = nil fielder.targetY = nil @@ -176,6 +194,36 @@ function updateInfield() 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) local a = x1 - x2 local b = y1 - y2 @@ -200,6 +248,14 @@ function getNearestFielder(x, y) return nearestFielder end +function ballIsBeingThrown() + return false +end + +function throwArrivedBeforeRunner() + return false +end + function updateGameState() deltaTime = playdate.getElapsedTime() playdate.resetElapsedTime() @@ -210,7 +266,7 @@ function updateGameState() pitch() end - if hit then + if currentMode == MODES.running then ballX = hitAnimatorX:currentValue() ballY = hitAnimatorY:currentValue() ballSize = ballSizeAnimator:currentValue() @@ -224,7 +280,7 @@ function updateGameState() batTipY = batBaseY + (batLength * math.cos(batAngle)) 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 ballAngle = batAngle + math.rad(90) @@ -242,22 +298,26 @@ function updateGameState() chasingFielder.targetX = ballDestX chasingFielder.targetY = ballDestY chasingFielder.onArrive = function() - throwBall(basePositions.first.x, basePositions.first.y) + throwBall(getNextThrowTarget()) + chasingFielder.onArrive = nil end fielders.first.targetX = basePositions.first.x fielders.first.targetY = basePositions.first.y - hit = true + currentMode = MODES.running + player.nextBase = basePositions.first + runners[#runners+1] = player end - lastBallY = ballY - updateInfield() + if currentMode == MODES.running then + updateRunners() + updateInfield() + end end function playdate.update() updateGameState() - grassBackground:draw(0, 0) - playerImage:draw(player.x, player.y) + grassBackground:draw(0, backgroundPan) gfx.setColor(gfx.kColorBlack) gfx.setLineWidth(2) @@ -268,9 +328,30 @@ function playdate.update() end 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 playdate.ui.crankIndicator:draw() 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