When I change my Paddle class to extend playdate.graphics.sprite
instead of nothing (and then change all the sprite references to self
), it breaks my whole game.
Paddle class:
import "CoreLibs/sprites"
import "CoreLibs/graphics"
local gfx <const> = playdate.graphics
class("Paddle").extends(gfx.sprite)
function Paddle:init()
Paddle.super.init(self)
self.transform = {
x = 200,
y = 220,
width = 32,
height = 8,
speed = 0
}
self.type = "paddle"
self:setImage(gfx.image.new("images/paddle"))
self:moveTo(self.transform.x, self.transform.y)
self:setCollideRect(0, 0, self:getSize())
self:add()
end
function Paddle:update()
Paddle.super.update(self)
local transform = self.transform
local change = playdate.getCrankChange()
if (transform.x - transform.width / 2 + change < 0) then
transform.speed = 0
transform.x = transform.width / 2
elseif (transform.x + transform.width / 2 + change > 400) then
transform.speed = 0
transform.x = 400 - transform.width / 2
else
transform.speed = change / 2;
end
transform.x += transform.speed
self:moveTo(transform.x, transform.y)
end
The console shows the following error:
Update error: ball.lua:42: attempt to perform arithmetic on a nil value (local '(temp)')
stack traceback:
ball.lua:42: in function <ball.lua:27>
[C]: in field 'update'
paddle.lua:27: in method 'update'
main.lua:26: in upvalue 'updateGame'
main.lua:37: in function <main.lua:36>
and ball.lua:42
is transform.x += transform.xspeed
which works perfectly fine if Paddle is not a sprite
This bug is driving me crazy. I need Paddle to be a sprite so I can access its type
and transform
easier when I'm doing collision checking.
Just for posterity, here's the full ball.lua file:
import "CoreLibs/sprites"
import "CoreLibs/graphics"
local gfx <const> = playdate.graphics
class("Ball").extends(gfx.sprite)
function Ball:init()
Ball.super.init(self)
self.transform = {
x = 155,
y = 110,
xspeed = 2,
yspeed = 2,
width = 8,
height = 8
}
self.type = "ball"
self:setImage(gfx.image.new("images/ball"))
self:moveTo(self.transform.x, self.transform.y)
self:setCollideRect(0, 0, self:getSize())
self:add()
end
function Ball:update()
Ball.super.update(self)
local transform = self.transform
-- bounce the ball if it hits the left or right sides
if (transform.x + transform.width / 2 >= 400 or transform.x - transform.width / 2 <= 0) then
transform.xspeed = -transform.xspeed
end
-- bounce the ball if it hits the top or bottom sides
if (transform.y + transform.height / 2 >= 240 or transform.y - transform.height / 2 <= 0) then
transform.yspeed = -transform.yspeed
end
transform.x += transform.xspeed
transform.y += transform.yspeed
local _, _, collisions, collisionsLen = self:moveWithCollisions(transform.x + transform.xspeed,
transform.y + transform.yspeed)
-- check if there are any collisions
if (collisionsLen > 0) then
-- flip the direction depending on where the ball hit the other thing
if (collisions[1].normal.x > 0 or collisions[1].normal.x < 0) then
transform.xspeed = -transform.xspeed
end
if (collisions[1].normal.y > 0 or collisions[1].normal.y < 0) then
transform.yspeed = -transform.yspeed
end
for i = 1, collisionsLen do
if collisions[i].other.type == "brick" then
collisions[i].other:remove()
score += 1
elseif collisions[i].other.type == "paddle" then
print("xspeed: " .. transform.xspeed)
print("yspeed: " .. transform.yspeed)
local oldSpeed = math.sqrt(transform.xspeed * transform.xspeed + transform.yspeed *
transform.yspeed)
local newXSpeed = collisions[i].other.transform.speed * 0.1
local newSpeed = math.sqrt(newXSpeed * newXSpeed + transform.yspeed *
transform.yspeed)
transform.xspeed = newXSpeed * (oldSpeed / newSpeed)
transform.yspeed = transform.yspeed * (oldSpeed / newSpeed)
end
end
end
end
function Ball:collisionResponse(other)
return gfx.sprite.kCollisionTypeBounce
end
Am I doing something wrong??