Search code examples
luapong

Keep getting nil value in LUA for PONG on self.dx and self.dy for ball (PONG 5)


I cannot for the life of me figure out what I am going wrong here, I have done the code over and over, I have checked for errors, spelling etc. Maybe it's something I don't understand, or something my eyes are correcting, but every time I run the program and try to move the ball it gives me the error in the image attached.

1

Any help would be greatly appreciated. Thanks.

Ball = Class{}

function Ball:init(x, y, width, height)
    self.x = x
    self.y = y
    self.width = width
    self.height = height
    self.dx = math.random(2)  == 1 and 100 or -100
    self.dy = math.random(-50,50)
end

function Ball:reset()
     --ball start location--
    self.x = VIRTUAL_WIDTH/2-2.5
    self.y = VIRTUAL_HEIGHT/2-2.5
 
     --random ball movement--
     self.dx = math.random(2)  == 1 and -100 or 100
     self.dy = math.random(-50,50) 
end

function Ball:update(dt)
    self.x = self.x + self.dx * dt
    self.y = self.y + self.dy * dt

end

function Ball:render()
    love.graphics.rectangle('fill', self.x, self.y, 5, 5)
end

MAIN FUNCTION CODE:

WINDOW_WIDTH = 1280
WINDOW_HEIGHT = 720

--16:9 resolution--
VIRTUAL_WIDTH = 432
VIRTUAL_HEIGHT = 243

--import push library--
Class = require 'class'
push = require 'push'

require 'Ball'
require 'Paddle'



--runs the game--
function love.load()

    math.randomseed(os.time())

    --sets the filter--
    love.graphics.setDefaultFilter('nearest','nearest')

    --create smaller font--
    smallFont = love.graphics.newFont('font.TTF', 8)

    --create larger font--
    scoreFont = love.graphics.newFont('font.TTF', 32)
   
    --set player scores to 0--
    player1score = 0
    player2score = 0

    gameState = 'start'

    --set starting place of paddles--
    paddle1 = Paddle(5,20, 5, 20)
    paddle2 = Paddle(VIRTUAL_WIDTH-10, VIRTUAL_HEIGHT-30, 5, 20)
    
    --set ball starting place--
    ball = Ball(VIRTUAL_WIDTH/2-2.5, VIRTUAL_HEIGHT/2-2.5, 5, 5)

    --set paddle speed--
    PADDLE_SPEED = 200

    --sets up screen size--
    push:setupScreen(VIRTUAL_WIDTH, VIRTUAL_HEIGHT, WINDOW_WIDTH, WINDOW_HEIGHT,{
        --does not allow fullscreen--
        fullscreen = false,
        --vertical sync--
        vsync = true,
        --does not allow resizing--
        resizable = false,
    })
end
--move paddles--
function love.update(dt)

    paddle1:update(dt)
    paddle2:update(dt)

    if love.keyboard.isDown('w') then
        paddle1.dy = -PADDLE_SPEED
    elseif love.keyboard.isDown('s') then
        paddle1.dy = PADDLE_SPEED
    else
        paddle1.dy = 0
    end  
    
    if love.keyboard.isDown('up') then
        paddle2.dy = -PADDLE_SPEED
    elseif love.keyboard.isDown('down') then
        paddle2.dy = PADDLE_SPEED
    else
        paddle2.dy = 0
    end  
    
    if gameState == 'play' then
        Ball:update(dt)
    end

end


--ends the game if the escape key is pressed--
function love.keypressed(key)
    if key == 'escape' then
        love.event.quit()

    elseif key == 'enter' or key == 'return' then
        if gameState == 'start' then
            gameState = 'play'
        else if gameState == 'play' then
            gameState = 'start'
             Ball:reset(dt)
        

        end
    end
end
end


--prints "Hello Pong!"--
--window height/2 to center from top to bottom, less 6 (half the height of the text)--
--from left to right is 'center' of windown width--
function love.draw()
    push:apply('start') --start drawing using push--

    --changes background--
    --changes ENTIRE SCREEN--
    --done before draw functions--
    love.graphics.clear(40/255, 45/255, 52/255, 255/255)

    --render paddles--
    paddle1:render()
    paddle2:render()

    --render ball--
    ball:render()

    --print Hello Pong--
    love.graphics.setFont(smallFont)
    if gameState == 'start' then
        love.graphics.printf("Hello, Start State!", 0, 20, VIRTUAL_WIDTH, 'center')
    elseif gameState == 'play' then
        love.graphics.printf("Hello, Play State!", 0, 20, VIRTUAL_WIDTH, 'center')
    end
 
    --display scores--
    love.graphics.setFont(scoreFont)
    love.graphics.print(player1score, VIRTUAL_WIDTH/2-50, VIRTUAL_HEIGHT / 3)
    love.graphics.print(player2score, VIRTUAL_WIDTH/2+30, VIRTUAL_HEIGHT / 3)

    push:apply('end') -- stop drawing using push
end

Solution

  • You are calling Ball:update(dt), which is subtly different from what you really mean to call, which is ball:update(dt). See the difference?

    In the first one, you are writing valid code, because Ball is a class definition that you've created. You are allowed to call methods on class definitions themselves, but only if they're 'static' methods - that is, methods which don't touch any members of the class (such as self.dx). If they try to, it won't work because those members haven't been initialized - it's a class definition, it can't have members with values.

    ball, on the other hand, is an instance of Ball, which means it has members with values, and can have non-static methods (such as update) called on it.

    (Also, you're doing the same thing for Ball:reset, although you've done it right with ball:render.)