Add some object-oriented sensibilities into this mess.

This commit is contained in:
Anna Rose 2023-09-27 02:24:22 -04:00
parent 2d0736fcd0
commit 27dd26bb32
3 changed files with 141 additions and 95 deletions

44
ball.lua Normal file
View File

@ -0,0 +1,44 @@
import "pixie"
class("Ball").extends(Pixie)
function Ball:init(width, height, color, x, y)
Ball.super.init(self, width, height, color, x, y)
self.dirX = -1
self.dirY = 1
self.vector = {}
self.vector.x = -1
self.vector.y = 1
self.speed = 3
return self
end
function Ball:levelUp()
self.speed += 1
end
function Ball:move()
-- self:moveBy(self.vector.x * self.speed,
-- self.vector.y * self.speed)
self:moveBy(self.dirX * self.speed,
self.dirY * self.speed)
end
function Ball:setDirection(x, y)
x = x or self.dirX
y = y or self.dirY
self.dirX = x
self.dirY = y
end
function Ball:_normalizePosition()
local changeVector = Ball.super._normalizePosition(self)
if changeVector[1] ~= 0 then
-- self.vector.x = changeVector[1]
self.dirX = changeVector[1]
end
if changeVector[2] ~= 0 then
-- self.vector.y = changeVector[2]
self.dirY = changeVector[2]
end
end

121
main.lua
View File

@ -4,43 +4,31 @@ import "CoreLibs/sprites"
import "CoreLibs/timer" import "CoreLibs/timer"
import "CoreLibs/crank" import "CoreLibs/crank"
import "pixie"
import "ball"
local gfx <const> = playdate.graphics local gfx <const> = playdate.graphics
local paddleSprite = nil local paddle = nil
local boundarySprite = nil local boundary = nil
local ballSprite = nil local ball = nil
local ballVector = {} local ballVector = {}
local ballSize <const> = 6
local ballSpeed = 3 local ballSpeed = 3
local paddleLength <const> = 80
local paddleWidth <const> = 6
local gameOver = false local gameOver = false
local gameOverText <const> = "Game Over!\nPress 'A' to play again." local gameOverText <const> = "Game Over!\nPress 'A' to play again."
function setup() function setup()
levelTimer() levelTimer()
paddleSprite = gfx.sprite.new(gfx.image.new(paddleWidth, paddleLength, gfx.kColorWhite)) paddle = Pixie(6, 80, gfx.kColorWhite, 5, 120)
paddleSprite:setCollideRect(0, 0, paddleSprite:getSize()) paddle:add()
paddleSprite:moveTo(5, 100) boundary = Pixie(2, 240, gfx.kColorClear)
paddleSprite:add() boundary:add()
ball = Ball(6, 6, gfx.kColorWhite, 200, 120)
boundarySprite = gfx.sprite.new(gfx.image.new(2, 240, gfx.kColorClear)) ball:add()
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) local backgroundImage = gfx.image.new(400, 240, gfx.kColorBlack)
gfx.sprite.setBackgroundDrawingCallback( gfx.sprite.setBackgroundDrawingCallback(
function(x, y, width, height) function(x, y, width, height)
@ -48,7 +36,7 @@ function setup()
if gameOver then if gameOver then
gfx.setColor(gfx.kColorWhite) gfx.setColor(gfx.kColorWhite)
gfx.fillRect(0, 80, 400, 80) gfx.fillRect(0, 80, 400, 80)
local level = ballSpeed - 2 local level = ball.speed - 2
playdate.graphics.drawTextAligned("Game Over!\nYou reached level " .. playdate.graphics.drawTextAligned("Game Over!\nYou reached level " ..
level .. level ..
"\nPress 'A' to play again.", 200, 90, kTextAlignment.center) "\nPress 'A' to play again.", 200, 90, kTextAlignment.center)
@ -60,106 +48,49 @@ end
function levelTimer() function levelTimer()
playdate.timer.new(10000, playdate.timer.new(10000,
function() function()
ballSpeed += 1 ball:levelUp()
levelTimer() levelTimer()
end end
) )
end
end
function playdate.update() function playdate.update()
gfx.clear(gfx.kColorBlack) gfx.clear()
if gameOver then if gameOver then
if playdate.buttonJustPressed(playdate.kButtonA) then if playdate.buttonJustPressed(playdate.kButtonA) then
paddleSprite:remove() paddle:remove()
boundarySprite:remove() boundary:remove()
ballSprite:remove() ball:remove()
playdate.file.run("main.pdz") playdate.file.run("main.pdz")
end end
else else
-- Check collisions -- Check collisions
local collisions = ballSprite:overlappingSprites() local collisions = ball:overlappingSprites()
for i = 1, #collisions do for i = 1, #collisions do
local collision = collisions[i] local collision = collisions[i]
if collision == paddleSprite then if collision == paddle then
redirectBall() redirectBall()
end end
if collision == boundarySprite then if collision == boundary then
gameOver = true gameOver = true
end end
end end
-- Handle movement -- Handle movement
movePaddle(playdate.getCrankTicks(80)) movePaddle(playdate.getCrankTicks(80))
moveBall() ball:move()
playdate.timer.updateTimers() playdate.timer.updateTimers()
end end
gfx.sprite.update() gfx.sprite.update()
end end
function redirectBall() function redirectBall()
ballVector[1] = 1 ball:setDirection(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 end
function movePaddle(ticks) function movePaddle(ticks)
if ticks == 0 then return end if ticks == 0 then return end
paddleSprite:moveBy(0, ticks*-5) paddle: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 end
setup() setup()

71
pixie.lua Normal file
View File

@ -0,0 +1,71 @@
-- A pixie is like a sprite, but better
import "CoreLibs/object"
import "CoreLibs/graphics"
import "CoreLibs/sprites"
local gfx <const> = playdate.graphics
class("Pixie").extends(gfx.sprite)
-- Crong pixies are simple rectangles, so they take an initial position, width, height, and color
-- They are also collidable
function Pixie:init(width, height, color, x, y)
x = x or 0
y = y or 0
Pixie.super.init(self, gfx.image.new(width, height, color))
self:setCollideRect(0, 0, self:getSize())
self:moveTo(x, y)
return self
end
function Pixie:moveTo(x, y)
Pixie.super.moveTo(self, x, y)
self:_normalizePosition()
end
function Pixie:moveBy(x, y)
Pixie.super.moveBy(self, x, y)
self:_normalizePosition()
end
function Pixie:_normalizePosition()
local limitTop = self.height / 2
local limitBottom = 240 - limitTop
local limitLeft = self.width / 2
local limitRight = 400 - limitLeft
local changedX = 0
local changedY = 0
local newX = self.x
local newY = self.y
if self.y < limitTop then
newY = limitTop
changedY = 1
end
if self.y > limitBottom then
newY = limitBottom
changedY = -1
end
if self.x < limitLeft then
newX = limitLeft
changedX = 1
end
if self.x > limitRight then
newX = limitRight
changedX = -1
end
if changedX ~= 0 or changedY ~= 0 then
-- call super to avoid the odd possibility that we recurse back into
-- this function
Pixie.super.moveTo(self, newX, newY)
end
return {changedX, changedY}
end