sinister-bricks/src/main.lua
2023-09-28 17:10:16 -04:00

182 lines
4.2 KiB
Lua

-- Collision mask reference:
import "CoreLibs/object"
import "CoreLibs/graphics"
import "CoreLibs/sprites"
import "CoreLibs/timer"
import "CoreLibs/crank"
import "pixie"
import "ball"
import "brick"
import "textbox"
local gfx <const> = playdate.graphics
local brickFreq <const> = 0.7
local paddle = nil
local deadWall = nil
local ball = nil
local startTime = nil
local endTime = nil
local timeWidget = nil
local speedWidget = nil
function setup()
playdate.resetElapsedTime()
math.randomseed(playdate.getSecondsSinceEpoch())
paddle = Pixie.new(6, 50, gfx.kColorWhite, 6, 120)
paddle:add()
ball = Ball(6, 6, gfx.kColorWhite, 12, 120)
ball:add()
addWallColliders()
setupBricks()
timeWidget = TextBox("", 100, 20, 350, 10, 5, kTextAlignment.center)
updateTimeWidget()
timeWidget:add()
speedWidget = TextBox("", 100, 20, 50, 10, 5, kTextAlignment.center)
updateSpeedWidget()
speedWidget:add()
local backgroundImage = gfx.image.new(400, 220, gfx.kColorBlack)
gfx.sprite.setBackgroundDrawingCallback(
function(x, y, width, height)
backgroundImage:draw(0, 20)
end
)
startTime = playdate.getElapsedTime()
end
function addWallColliders()
-- set up border boundaries
-- top
gfx.sprite.addEmptyCollisionSprite(constants.screenLeft, constants.screenTop,
constants.screenWidth, 1)
-- right
gfx.sprite.addEmptyCollisionSprite(constants.screenRight, constants.screenTop,
1, constants.screenHeight)
-- bottom
gfx.sprite.addEmptyCollisionSprite(constants.screenLeft, constants.screenBottom,
constants.screenWidth, 1)
-- left
deadWall = Pixie.new(1, constants.screenHeight, gfx.kColorClear,
0, constants.screenHeight / 2 + constants.screenTop)
deadWall:add()
end
function setupBricks()
for i=1,12 do
advanceBricks()
addBrickRow()
end
addBrickTimer()
end
function addBrickRow()
for i=1,10 do
if math.random() < brickFreq then
local brick = Brick(constants.screenRight - 5,
constants.screenTop + (22 * (i-1)) + 11)
brick:add()
end
end
end
function advanceBricks()
-- move all the bricks over
local sprites = gfx.sprite.getAllSprites()
for i=1, #sprites, 1 do
local brick = sprites[i]
if brick:isa(Brick) then
brick:moveBy(-10, 0)
end
end
end
function playdate.update()
gfx.clear()
if endTime then
if playdate.buttonJustPressed(playdate.kButtonA) then
gfx.sprite.removeAll()
playdate.file.run("main.pdz")
end
else
-- Handle player movement
movePaddle(playdate.getCrankTicks(80))
-- Handle ball movement + collision
moveBall()
-- UI Updates
updateTimeWidget()
updateSpeedWidget()
playdate.timer.updateTimers()
end
gfx.sprite.update()
end
function updateTimeWidget()
timeWidget:setText(string.format("time: %.2f", playdate.getElapsedTime()))
end
function updateSpeedWidget()
speedWidget:setText(string.format("speed: " .. math.abs(ball.direction.x) - 4))
end
function movePaddle(ticks)
if ticks == 0 then return end
local collisions = select(3, paddle:moveWithCollisions(paddle.x, paddle.y + ticks*-5))
for i = 1, #collisions, 1 do
local obj = collisions[i].other
if obj:isa(Brick) then
endGame()
end
end
end
function moveBall()
local collisions = ball:move()
for i = 1, #collisions, 1 do
local obj = collisions[i].other
if obj:isa(Brick) then
obj:remove()
end
if obj == deadWall then
endGame()
end
end
end
function addBrickTimer()
playdate.timer.performAfterDelay(20000,
function()
advanceBricks()
addBrickRow()
addBrickTimer()
end
)
end
function endGame()
endTime = playdate.getElapsedTime()
local t = string.format("Game Over!\nYou survived for %.2f seconds.\nPress 'A' to play again.", endTime)
local textBox = TextBox(t, 275, 40, 200, 120,
5, kTextAlignment.center)
textBox:add()
end
setup()