Hallo! I am new to lua,
I am trying to make the breakout game using a state machine as described by CS50 lecture
following is my PlayState:
---------------------------------------------------code starts here -------------------------------------------
PlayState = Class{__includes = BaseState}
function PlayState:change(params)
self.paddle = params.paddle
self.bricks = params.bricks
self.score = params.score
self.health = params.health
self.ball = params.ball
self.ball.dx = math.random(-200,200)
self.ball.dy = math.random(-70,100)
self.paused = false
params = nil
end
function PlayState:update(dt)
if self.paused then
if love.keyboard.wasPressed('space') then
self.paused = false
gSounds['pause']:play()
else
return -- to make the game remain in paused state
end
elseif love.keyboard.wasPressed('space') then
self.paused = true
gSounds['pause']:play()
return
end
self.paddle:update(dt)
self.ball:update(dt)
if self.ball:collides(self.paddle) then
self.ball.y = self.paddle.y - 8
self.ball.dy = -self.ball.dy
if self.ball.x < self.paddle.x + (self.paddle.width/2) and self.paddle.dx<0 then
self.ball.dx = -50 + - ((self.paddle.x + self.paddle.width/2 - self.ball.x) * 8)
elseif self.ball.x > self.paddle.x + (self.paddle.width/2) and self.paddle.dx > 0 then
self.ball.dx = 50 + math.abs((self.paddle.x + self.paddle.width/2 - self.ball.x) * 8)
end
gSounds['paddle-hit']:play()
end
for k,brick in pairs(self.bricks) do
if brick.inPlay and self.ball:collides(brick) then
brick:hit()
if self.ball.x + 2 < brick.x and self.ball.dx > 0 then
self.ball.dx = -self.ball.dx
self.ball.x = brick.x - 8
elseif self.ball.x + 6 > brick.x + brick.width and self.ball.dx < 0 then
self.ball.dx = - self.ball.dx
self.ball.x = brick.x + 32
elseif self.ball.y < brick.y then
self.ball.dy = -self.ball.dy
self.ball.y = brick.y - 8
else
self.ball.dy = - self.ball.dy
self.ball.y = brick.y + 16
end
end
end
if self.ball.y >= VIRTUAL_HEIGHT then
gSounds['hurt']:play()
self.health = self.health - 1
if self.health == 0 then
gStateMachine:change('gameover',{score = self.score})
else
gStateMachine:change('serve',{
paddle = self.paddle,
bricks = self.bricks,
score = self.score,
health = self.health,
})
end
end
if love.keyboard.wasPressed('escape') then
love.event.quit()
end
end
function PlayState:render()
self.paddle:render()
self.ball:render()
for k,brick in pairs(self.bricks) do
brick:render()
end
if self.paused then
love.graphics.setFont(gFonts['large'])
love.graphics.printf('PAUSED',0,VIRTUAL_HEIGHT/2,VIRTUAL_WIDTH,'center')
end
end
function PlayState:exit()
self = nil
collectgarbage("collect")
end
---------------------------------------------------code ends here -------------------------------------------
it's previous state is serveState and it is working fine. but while I am changing to PlayState (the state shown above) the following error occurs:
Error
Src/States/PlayState.lua:83: attempt to index field 'paddle' (a nil value)
Traceback
Src/States/PlayState.lua:83: in function 'render'
Src/StateMachine.lua:27: in function 'render'
main.lua:89: in function 'draw'
[C]: in function 'xpcall'
I thought it may be a problem of memory hence I assign and 'nil' value to the parameter passed to every state after its values are used, but still the above error persists. I am stuck here, help me lease
ERROR Error Src/States/PlayState.lua:83: attempt to index field 'paddle' (a nil value)
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
-
- Prole
- Posts: 17
- Joined: Fri Nov 26, 2021 5:15 am
-
- Party member
- Posts: 516
- Joined: Wed Oct 05, 2016 11:53 am
Re: ERROR Error Src/States/PlayState.lua:83: attempt to index field 'paddle' (a nil value)
Please use [code]...[/code] tags when posting code. It's nigh unreadable otherwise. As for your actual problem, I see you have this line of code in your change() function:
I'm not sure how the CS50 teaches you to deal with state machines, or how your serveState looks, but the likely culprit is simply not passing an appropriately structured table (ie. the 'params' table lacks the 'paddle' field, maybe serveState doesn't have self.paddle defined at all?) or some mixup between period/colon syntax (ie. you have a '.change()' somewhere where you meant to write ':change()' when changing states). That of course presumes that the state switching otherwise works. Another guess could be that render() gets called before the state switch has been properly processed, but I wouldn't count on that.
If none of the above works, then you'll have to provide additional context, I'm afraid.
Code: Select all
function PlayState:change(params)
self.paddle = params.paddle -- assign the paddle
-- ...rest of the code
end
If none of the above works, then you'll have to provide additional context, I'm afraid.
That "params = nil" line is fine, but not necessary either. It basically just says "we are done with whatever the variable 'params' held here", and won't immediately affect any tables it might have contained, if they've been assigned to other places like you do in your code (self.paddle = params.paddle, etc). Because you do it at the end of the function, it'd do that automatically under the hood anyway. Of course, I'm only simplifying things here.I thought it may be a problem of memory hence I assign and 'nil' value to the parameter passed to every state after its values are used
-
- Prole
- Posts: 17
- Joined: Fri Nov 26, 2021 5:15 am
Re: ERROR Error Src/States/PlayState.lua:83: attempt to index field 'paddle' (a nil value)
Many thanks MrFariator for your response, your observations are really helpful and it solved my problem. Thank you once again, looking forward to more such valuable inputs in future.
Who is online
Users browsing this forum: Bing [Bot] and 5 guests