Tweak drift-toward-base behavior.

It's a little clunky for sure, but also more playable.
Added the Full Circle font for the scoreboard.
Do a *check-only* lint in 'make check'
This commit is contained in:
Sage Vaillancourt 2025-02-02 11:07:15 -05:00
parent bf4fbab40f
commit b9fc7ee09e
4 changed files with 147 additions and 19 deletions

View File

@ -4,7 +4,8 @@ all:
pdc src BatterUp.pdx
check:
stylua -c src/
cat __stub.ext.lua <(sed 's/^function/-- selene: allow(unused_variable)\nfunction/' ${PLAYDATE_SDK_PATH}/CoreLibs/__stub.lua) ${SOURCE_FILES} | grep -v '^import' | sed 's/<const>//g' | selene -
lint: check
lint:
stylua src/

View File

@ -0,0 +1,96 @@
space 4
! 3
" 8
# 8
$ 9
% 9
& 11
' 4
( 6
) 6
* 9
+ 7
, 4
- 8
. 4
/ 7
0 9
1 6
2 9
3 9
4 9
5 9
6 9
7 9
8 9
9 9
: 4
; 4
< 7
= 8
> 7
? 8
@ 13
A 9
B 9
C 9
D 9
E 9
F 9
G 9
H 9
I 3
J 7
K 9
L 8
M 11
N 11
O 9
P 9
Q 9
R 9
S 9
T 9
U 9
V 9
W 11
X 9
Y 9
Z 9
[ 6
\ 7
] 6
^ 10
_ 9
` 4
a 9
b 9
c 9
d 9
e 9
f 7
g 9
h 9
i 3
j 7
k 9
l 6
m 13
n 9
o 9
p 9
q 9
r 7
s 9
t 8
u 9
v 9
w 10
x 9
y 9
z 9
{ 6
| 3
} 6
~ 8
… 12

View File

@ -14,7 +14,7 @@ import 'utils.lua'
--- @alias Base { x: number, y: number }
--- @alias Runner { x: number, y: number, nextBase: Base, prevBase: Base, forcedTo: Base }
--- @alias Runner { x: number, y: number, nextBase: Base, prevBase: Base | nil, forcedTo: Base }
--- @alias Fielder { onArrive: fun() | nil, x: number | nil, y: number | nil, target: XYPair | nil, speed: number }
@ -31,6 +31,8 @@ local BatCrackSound <const> = playdate.sound.sampleplayer.new("sounds/bat-crack-
local GrassBackground <const> = gfx.image.new("images/game/grass.png") --[[@as PlaydateGraphicsImage]]
local PlayerFrown <const> = gfx.image.new("images/game/player-frown.png") --[[@as PlaydateGraphicsImage]]
local ScoreFont <const> = gfx.font.new("fonts/Full Circle/font-full-circle.pft")
local PlayerImageBlipper <const> = blipper.new(100, "images/game/player.png", "images/game/player-lowhat.png")
local DanceBounceMs <const> = 500
@ -78,7 +80,7 @@ local ballFloatAnimator <const> = gfx.animator.new(2000, -60, 0, easingHill)
local BallSizeMs = 2000
local ballSizeAnimator = gfx.animator.new(BallSizeMs, 9, 6, easingHill)
local HitMult = 10
local HitMult = 20
local deltaSeconds = 0
@ -293,8 +295,9 @@ end
--- Returns true if at least one runner is still moving
---@return boolean
function updateRunners()
local autoRunSpeed = 20
local autoRunSpeed = 20 * deltaSeconds
--autoRunSpeed = 140
-- TODO: Filter for the runner closest to the currently-held direction button
local currentRunners = currentMode == Modes.batting and { batter }
or filter(runners, function(runner)
return runner ~= batter
@ -302,7 +305,9 @@ function updateRunners()
local runnerMoved = false
for runnerIndex, runner in ipairs(currentRunners) do
local appliedSpeed = crankChange -- TODO: Allow for individual runner control via buttons
local nearestBase, nearestBaseDistance = getNearestOf(Bases, runner.x, runner.y)
if
nearestBaseDistance < 5
and runner.prevBase
@ -311,21 +316,31 @@ function updateRunners()
then
score(runnerIndex)
end
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
local prevX, prevY = runner.x, runner.y
-- TODO: Drift toward nearest base?
local autoRun = nearestBaseDistance > 5 and mult * autoRunSpeed * deltaSeconds or 0
mult = autoRun + (crankChange / 20)
local mult = 1
if appliedSpeed < 0 then
if runner.prevBase then
mult = -1
else
-- Don't allow running backwards when approaching the plate
appliedSpeed = 0
end
end
-- TODO: Also move if forced to 😅
local autoRun = nearestBaseDistance > 40 and mult * autoRunSpeed
or nearestBaseDistance < 5 and 0
or (nearestBase == runner.nextBase and autoRunSpeed or -1 * autoRunSpeed)
mult = autoRun + (appliedSpeed / 20)
runner.x = runner.x - (x * mult)
runner.y = runner.y - (y * mult)
runnerMoved = runnerMoved or prevX ~= runner.x or prevY ~= runner.y
else
runner.nextBase = NextBaseMap[runner.nextBase]
@ -509,29 +524,38 @@ function updateGameState()
updateOutRunners()
end
local OUT_BUBBLE_SIZE = 6
local OUT_BUBBLE_SIZE = 5
function drawScoreboard()
gfx.setFont(ScoreFont)
gfx.setDrawOffset(0, 0)
local y = Screen.H * 0.95
local x = Screen.W * 0.05
local y = Screen.H * 0.97
local x = 15
gfx.setLineWidth(1)
gfx.setColor(gfx.kColorBlack)
gfx.fillRect(x - 15, y - 44, 73, 55)
gfx.fillRect(x - 15, y - 44, 75, 55)
gfx.setColor(gfx.kColorWhite)
for i = outs, 2 do
gfx.drawCircleAtPoint(x + (i * 2.5 * OUT_BUBBLE_SIZE), y, OUT_BUBBLE_SIZE)
gfx.drawCircleAtPoint(x - 2 + (i * 2.5 * OUT_BUBBLE_SIZE), y, OUT_BUBBLE_SIZE)
end
for i = 0, (outs - 1) do
gfx.fillCircleAtPoint(x + (i * 2.5 * OUT_BUBBLE_SIZE), y, OUT_BUBBLE_SIZE)
gfx.fillCircleAtPoint(x - 2 + (i * 2.5 * OUT_BUBBLE_SIZE), y, OUT_BUBBLE_SIZE)
end
local originalDrawMode = gfx.getImageDrawMode()
gfx.setImageDrawMode(playdate.graphics.kDrawModeInverted)
gfx.drawText("Home: " .. homeScore, x - 7, y - 40, 100, 20)
gfx.drawText("Away: " .. awayScore, x - 7, y - 25, 100, 20)
local numOffsetX = gfx.getTextSize("AWAY ")
gfx.drawText("HOME ", x - 7, y - 38)
local homeScoreText = homeScore > 9 and homeScore or " " .. homeScore
gfx.drawText(homeScoreText, x - 7 + numOffsetX, y - 38)
gfx.drawText("AWAY ", x - 7, y - 22)
local awayScoreText = awayScore > 9 and awayScore or " " .. awayScore
gfx.drawText(awayScoreText, x - 7 + numOffsetX, y - 22)
gfx.setImageDrawMode(originalDrawMode)
end

View File

@ -17,6 +17,13 @@ function easingHill(t, b, c, d)
return (c * t) + b
end
-- Useful for quick print-the-value-in-place debugging.
-- selene: allow(unused_variable)
function label(value, name)
print(name .. ": " .. value)
return value
end
---@param x number
---@param y number
---@return XYPair