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

119
main.lua
View File

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