Add some images!

Also, patch up hit-detection logic!
Switch from D-Pad controlling hitMult to controlling player position.

This commit keeps a bunch of cruft, in case I messed something up.
The next commit will remove it.
This commit is contained in:
Sage Vaillancourt 2025-01-26 16:12:58 -05:00
parent af7f719a2c
commit e81c27f00e
4 changed files with 166 additions and 31 deletions

BIN
src/images/game/grass.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,42 +1,53 @@
import 'CoreLibs/graphics.lua'
import 'CoreLibs/animator.lua' import 'CoreLibs/animator.lua'
import 'CoreLibs/easing.lua' import 'CoreLibs/easing.lua'
import 'CoreLibs/graphics.lua'
import 'CoreLibs/object.lua'
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)
lastPosition = playdate.getCrankPosition() local grassBackground = gfx.image.new("images/game/grass.png")
-- text = "Oop" local pitchFlyTimeMs = 2500
local ballStartY, endY = 90, 250
timeSinceLastSwing = 999999
local ball = gfx.image.new(10, 10, gfx.kColorBlack)
local animationDuration = 2000
local ballStartY, endY = -20, 250
local easingFunction = playdate.easingFunctions.outQuint local easingFunction = playdate.easingFunctions.outQuint
local ballAnimator = gfx.animator.new(animationDuration, ballStartY, endY, easingFunction) local pitchAnimator = gfx.animator.new(pitchFlyTimeMs, ballStartY, endY, easingFunction)
local ballSizeMs = 2000
local ballSizeAnimator = gfx.animator.new(ballSizeMs, 9, 6, playdate.easingFunctions.outBounce)
local screenW, screenH = 400, 240 local screenW, screenH = 400, 240
local centerX, centerY = screenW / 2, screenH / 2 local centerX, centerY = screenW / 2, screenH / 2
local batBaseX, batBaseY = centerX - 34, 200 local batBaseX, batBaseY = centerX - 34, 220
local circleR = 45 local batLength = 45
local ballY = ballStartY local ballY = ballStartY
local lastBallY = ballY local lastBallY = ballY
local ballX = 200 local ballX = 200
local ballVelX, ballVelY = 0, 0 local ballVelX, ballVelY = 0, 0
local ballSize = 6
local batTipX = 0 local batTipX = 0
local batTipY = 0 local batTipY = 0
local hit = false local hit = false
local hitAnimatorY
local hitAnimatorX
local hitMult = 10
function hitBall(destX, destY, hitFlyTime)
ballSizeAnimator:reset()
hitAnimatorY = gfx.animator.new(hitFlyTime, ballY, destY, playdate.easingFunctions.outQuint)
hitAnimatorX = gfx.animator.new(hitFlyTime, ballX, destX, playdate.easingFunctions.outQuint)
end
function pitch() function pitch()
ballAnimator:reset() pitchAnimator:reset()
ballVelX = 0 ballVelX = 0
ballVelY = 0 ballVelY = 0
ballX = 200 ballX = 200
@ -47,10 +58,111 @@ function playdate.AButtonDown()
pitch() pitch()
end end
function playdate.upButtonDown()
-- hitMult += 1
batBaseY -= 1
end
function playdate.downButtonDown()
-- hitMult -= 1
batBaseY += 1
end
function playdate.rightButtonDown()
batBaseX += 1
end
function playdate.leftButtonDown()
batBaseX -= 1
end
local pitchClockSec = 5 local pitchClockSec = 5
local elapsedTime = 0 local elapsedTime = 0
function playdate.update() -- No-abs failure
-- Hit early!
-- {
-- [b] = 220,
-- [ballX] = 200,
-- [ballY] = 138.2103,
-- [batBaseX] = 166.0,
-- [batBaseY] = 220,
-- [batTipX] = 207.4227,
-- [batTipY] = 202.4171,
-- [m] = -0.4244749,
-- [mx] = -84.89497,
-- [mxPlusB] = 135.105,
-- [x] = 200,
-- [y] = 135.105,
-- }
-- With-abs failure
-- Did not hit!
-- {
-- [b] = 220,
-- [ballY] = 234.121,
-- [m] = 0.4244749,
-- [mx] = 84.89497,
-- [mxPlusB] = 304.895,
-- [x] = 200,
-- [y] = 304.895,
-- }
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
-- printTable({
-- m = m,
-- mx = m * ballX,
-- mxPlusB = y,
-- y = y,
-- x = ballX,
-- b = batBaseY,
-- ballY = ballY,
-- ballX = ballX,
-- batTipY = batTipY,
-- batBaseY = batBaseY,
-- batTipX = batTipX,
-- batBaseX = batBaseX
-- })
printTable({
b = batBaseY,
m = m,
yOnLine = yOnLine,
yP = yP,
yDelta = yDelta,
batTipY = batTipY,
batBaseY = batBaseY,
batTipX = batTipX,
batBaseX = batBaseX
})
return yDelta <= 0
-- return ballY > y
-- -- return (lastBallY - 2) < batTipY and ballY >= batTipY and batTipX > ballX
-- -- return math.abs(batTipX - ballX) < 10
-- return (math.abs(ballY - batTipY) < 10) and (batTipX > ballX)
end
function updateGameState()
local deltaTime = playdate.getElapsedTime() local deltaTime = playdate.getElapsedTime()
playdate.resetElapsedTime() playdate.resetElapsedTime()
elapsedTime = elapsedTime + deltaTime elapsedTime = elapsedTime + deltaTime
@ -60,41 +172,57 @@ function playdate.update()
pitch() pitch()
end end
gfx.clear()
crankChange, acceleratedChange = playdate.getCrankChange()
if hit then if hit then
ballX = ballX + ballVelX -- ballX = ballX + ballVelX
ballY = ballY + ballVelY -- ballY = ballY + ballVelY
ballX = hitAnimatorX:currentValue()
ballY = hitAnimatorY:currentValue()
ballSize = ballSizeAnimator:currentValue()
else else
ballY = ballAnimator:currentValue() ballY = pitchAnimator:currentValue()
ballSize = 6
end end
batAngle = math.rad(playdate.getCrankPosition() + 180) batAngle = math.rad(playdate.getCrankPosition() + 90)
batTipX = batBaseX + (circleR * math.sin(batAngle)) batTipX = batBaseX + (batLength * math.sin(batAngle))
batTipY = batBaseY + (circleR * math.cos(batAngle)) batTipY = batBaseY + (batLength * math.cos(batAngle))
if hit == false and if hit == false and ballPassedThruBat(ballX, ballY, batBaseX, batBaseY, batTipX, batTipY) then
--(lastBallY - 2) < batTipY and ballY >= batTipY and batTipX > ballX then
math.abs(ballY - batTipY) < 10 and batTipX > ballX then -- math.abs(batTipX - ballX) < 10 then
ballAngle = batAngle + math.rad(90) ballAngle = batAngle + math.rad(90)
crankChange, acceleratedChange = playdate.getCrankChange()
mult = math.abs(acceleratedChange / 15) mult = math.abs(acceleratedChange / 15)
ballVelX = mult * -15 * math.sin(ballAngle) ballVelX = mult * 10 * math.sin(ballAngle)
ballVelY = mult * 5 * math.cos(ballAngle) ballVelY = mult * 5 * math.cos(ballAngle)
if ballVelY > 0 then if ballVelY > 0 then
ballVelX = ballVelX * -1 ballVelX = ballVelX * -1
ballVelY = ballVelY * -1 ballVelY = ballVelY * -1
end end
ballDestX = ballX + (ballVelX * hitMult)
ballDestY = ballY + (ballVelY * hitMult)
hitBall(ballDestX, ballDestY, 2000)
hit = true hit = true
end end
lastBallY = ballY lastBallY = ballY
end
function playdate.update()
updateGameState()
-- gfx.clear()
grassBackground:draw(0, 0)
gfx.setColor(gfx.kColorBlack) gfx.setColor(gfx.kColorBlack)
-- ball:draw(ballX, ballY)
gfx.setLineWidth(2) gfx.setLineWidth(2)
gfx.drawCircleAtPoint(ballX, ballY, 8) gfx.drawCircleAtPoint(ballX, ballY, ballSize)
gfx.setLineWidth(5) gfx.setLineWidth(5)
gfx.drawLine(batBaseX, batBaseY, batTipX, batTipY) gfx.drawLine(batBaseX, batBaseY, batTipX, batTipY)
end
-- gfx.drawText("Hit Mult:", 3, screenH - 15)
-- gfx.drawText(hitMult, 65, screenH - 15)
if playdate.isCrankDocked() then
playdate.ui.crankIndicator:draw()
end
end

7
src/pdxinfo Normal file
View File

@ -0,0 +1,7 @@
name=Batter Up!
author=Sage Vaillancourt
description=Crush dingers and hustle around the bases!
bundleID=space.sagev.batterup
imagePath=images/launcher
version=0.1
buildNumber=1