-- 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 = playdate.graphics local brickFreq = 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()