166 lines
3.9 KiB
Lua
166 lines
3.9 KiB
Lua
|
import "CoreLibs/object"
|
||
|
import "CoreLibs/graphics"
|
||
|
import "CoreLibs/sprites"
|
||
|
import "CoreLibs/timer"
|
||
|
import "CoreLibs/crank"
|
||
|
|
||
|
local gfx <const> = playdate.graphics
|
||
|
|
||
|
local paddleSprite = nil
|
||
|
local boundarySprite = nil
|
||
|
local ballSprite = nil
|
||
|
|
||
|
local ballVector = {}
|
||
|
local ballSize <const> = 6
|
||
|
local ballSpeed = 3
|
||
|
|
||
|
local paddleLength <const> = 80
|
||
|
local paddleWidth <const> = 6
|
||
|
|
||
|
local gameOver = false
|
||
|
local gameOverText <const> = "Game Over!\nPress 'A' to play again."
|
||
|
|
||
|
function setup()
|
||
|
levelTimer()
|
||
|
|
||
|
paddleSprite = gfx.sprite.new(gfx.image.new(paddleWidth, paddleLength, gfx.kColorWhite))
|
||
|
paddleSprite:setCollideRect(0, 0, paddleSprite:getSize())
|
||
|
paddleSprite:moveTo(5, 100)
|
||
|
paddleSprite:add()
|
||
|
|
||
|
boundarySprite = gfx.sprite.new(gfx.image.new(2, 240, gfx.kColorClear))
|
||
|
boundarySprite:setCollideRect(0, 0, boundarySprite:getSize())
|
||
|
boundarySprite:moveTo(0, 120)
|
||
|
boundarySprite:add()
|
||
|
|
||
|
ballSprite = gfx.sprite.new(gfx.image.new(ballSize, ballSize, gfx.kColorWhite))
|
||
|
ballSprite:setCollideRect(0, 0, ballSprite:getSize())
|
||
|
ballSprite:moveTo(200,120)
|
||
|
ballSprite:add()
|
||
|
|
||
|
ballVector[1] = -1
|
||
|
ballVector[2] = 1
|
||
|
|
||
|
local backgroundImage = gfx.image.new(400, 240, gfx.kColorBlack)
|
||
|
gfx.sprite.setBackgroundDrawingCallback(
|
||
|
function(x, y, width, height)
|
||
|
backgroundImage:draw(0, 0)
|
||
|
if gameOver then
|
||
|
gfx.setColor(gfx.kColorWhite)
|
||
|
gfx.fillRect(0, 80, 400, 80)
|
||
|
local level = ballSpeed - 2
|
||
|
playdate.graphics.drawTextAligned("Game Over!\nYou reached level " ..
|
||
|
level ..
|
||
|
"\nPress 'A' to play again.", 200, 90, kTextAlignment.center)
|
||
|
end
|
||
|
end
|
||
|
)
|
||
|
end
|
||
|
|
||
|
function levelTimer()
|
||
|
playdate.timer.new(10000,
|
||
|
function()
|
||
|
ballSpeed += 1
|
||
|
levelTimer()
|
||
|
end
|
||
|
)
|
||
|
|
||
|
end
|
||
|
|
||
|
function playdate.update()
|
||
|
gfx.clear(gfx.kColorBlack)
|
||
|
|
||
|
if gameOver then
|
||
|
if playdate.buttonJustPressed(playdate.kButtonA) then
|
||
|
paddleSprite:remove()
|
||
|
boundarySprite:remove()
|
||
|
ballSprite:remove()
|
||
|
playdate.file.run("main.pdz")
|
||
|
end
|
||
|
else
|
||
|
-- Check collisions
|
||
|
local collisions = ballSprite:overlappingSprites()
|
||
|
for i = 1, #collisions do
|
||
|
local collision = collisions[i]
|
||
|
if collision == paddleSprite then
|
||
|
redirectBall()
|
||
|
end
|
||
|
if collision == boundarySprite then
|
||
|
gameOver = true
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- Handle movement
|
||
|
movePaddle(playdate.getCrankTicks(80))
|
||
|
moveBall()
|
||
|
|
||
|
playdate.timer.updateTimers()
|
||
|
end
|
||
|
gfx.sprite.update()
|
||
|
end
|
||
|
|
||
|
function redirectBall()
|
||
|
ballVector[1] = 1
|
||
|
end
|
||
|
|
||
|
function moveBall()
|
||
|
ballSprite:moveTo(ballSprite.x + (ballVector[1] * ballSpeed),
|
||
|
ballSprite.y + (ballVector[2] * ballSpeed))
|
||
|
|
||
|
local changeVector = normalizePosition(ballSprite)
|
||
|
if changeVector[1] ~= 0 then
|
||
|
ballVector[1] = changeVector[1]
|
||
|
end
|
||
|
if changeVector[2] ~= 0 then
|
||
|
ballVector[2] = changeVector[2]
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function movePaddle(ticks)
|
||
|
if ticks == 0 then return end
|
||
|
paddleSprite:moveBy(0, ticks*-5)
|
||
|
normalizePosition(paddleSprite)
|
||
|
end
|
||
|
|
||
|
|
||
|
-- Keep sprite inside screen bounds
|
||
|
function normalizePosition(sprite)
|
||
|
local limitTop = sprite.height / 2
|
||
|
local limitBottom = 240 - limitTop
|
||
|
local limitLeft = sprite.width / 2
|
||
|
local limitRight = 400 - limitLeft
|
||
|
|
||
|
local changedX = 0
|
||
|
local changedY = 0
|
||
|
local newX = sprite.x
|
||
|
local newY = sprite.y
|
||
|
|
||
|
if sprite.y < limitTop then
|
||
|
newY = limitTop
|
||
|
changedY = 1
|
||
|
end
|
||
|
|
||
|
if sprite.y > limitBottom then
|
||
|
newY = limitBottom
|
||
|
changedY = -1
|
||
|
end
|
||
|
|
||
|
if sprite.x < limitLeft then
|
||
|
newX = limitLeft
|
||
|
changedX = 1
|
||
|
end
|
||
|
|
||
|
if sprite.x > limitRight then
|
||
|
newX = limitRight
|
||
|
changedX = -1
|
||
|
end
|
||
|
|
||
|
if changedX ~= 0 or changedY ~= 0 then
|
||
|
sprite:moveTo(newX, newY)
|
||
|
end
|
||
|
|
||
|
return {changedX, changedY}
|
||
|
end
|
||
|
|
||
|
setup()
|