games50 / pong

Atari's 1972 classic, implemented in Lua with LÖVE
835 stars 1.13k forks source link

Problems in Pong7 #58

Open ican002 opened 4 years ago

ican002 commented 4 years ago

Whenever I try to change the state to the play state, I get an error message saying Error main.lua:42: attempt to call method 'collides' (a nil value).

Here's my code so far:

main.lua:

WINDOW_WIDTH = 1280
WINDOW_HEIGHT = 720

VIRTUAL_WIDTH = 432
VIRTUAL_HEIGHT = 243

PADDLE_SPEED = 200

push = require 'push'
Class = require 'class'

require 'Ball'
require 'Paddle'

function love.load()
    math.randomseed(os.time())
    love.graphics.setDefaultFilter('nearest', 'nearest')

    smallFont = love.graphics.newFont('font.ttf', 8)
    scoreFont = love.graphics.newFont('font.ttf', 32)

    player1Score = 0
    player2Score = 0

    player1 = Paddle(5, 20, 5, 20)
    player2 = Paddle(VIRTUAL_WIDTH - 10, VIRTUAL_HEIGHT - 30, 5, 20)
    ball = Ball(VIRTUAL_WIDTH / 2 - 2, VIRTUAL_HEIGHT / 2 - 2, 5, 5)

    gameState = 'start'

    push:setupScreen(VIRTUAL_WIDTH, VIRTUAL_HEIGHT, WINDOW_WIDTH, WINDOW_HEIGHT, {
        fullscreen = false,
        vsync = true,
        resizable = false
    })
end

function love.update(dt)
    if gameState == 'play' then 
        ball:update(dt)

        if ball:collides(player1) then
            ball.dx = -ball.dx
        end
        if ball:collides(player2) then
            ball.dx = -ball.dx
        end
        if ball.y <= 0 then
            ball.dy = -ball.dy
            ball.y = 0
        end
        if ball.y >= VIRTUAL_HEIGHT - 5 then
            ball.dy = -ball.dy
            ball.y = VIRTUAL_HEIGHT - 4
        end
    end

    player1:update(dt)
    player2:update(dt)

    if love.keyboard.isDown('w') then
        player1.dy = -PADDLE_SPEED
    elseif love.keyboard.isDown('s') then
        player1.dy = PADDLE_SPEED
    else 
        player1.dy = 0
    end

    if love.keyboard.isDown('up') then
        player2.dy = -PADDLE_SPEED
    elseif love.keyboard.isDown('down') then
        player2.dy = PADDLE_SPEED
    else
        player2.dy = 0
    end
end    

function love.keypressed(key)
    if key == 'escape' then
        love.event.quit()

    elseif key == 'enter' or key == 'return' then
        if gameState == 'start' then
            gameState = 'play'
        elseif gameState == 'play' then
            gameState = 'start'
            ball:reset()
        end
    end   
end   

function love.draw()
    push:apply('start') 

    love.graphics.clear(40 / 255, 45 / 255, 52 / 255, 255 / 255)

    ball:render(VIRTUAL_WIDTH / 2 - 2, VIRTUAL_HEIGHT / 2 - 2, 5, 5)
    player1:render(5, 20, 5, 20)
    player2:render(VIRTUAL_WIDTH - 10, VIRTUAL_HEIGHT - 30, 5, 20)    

    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    
    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)              

    displayFPS()

    push:apply('end')
end  

function displayFPS()
    love.graphics.setColor(0, 1, 0 ,1)
    love.graphics.setFont(smallFont)
    love.graphics.print('FPS: ' .. tostring(love.timer.getFPS()), 40, 20)
    love.graphics.setColor(1, 1, 1, 1)
end

Ball.lua

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:collides(box)
    if self.x > box.x + box.width or self.x + self.width < box.x then
        return false
    end
    if self.y > box.y + box.height or self.y + self.height < box.y then
        return false
    end
    return true
end

function Ball:reset()
    self.x = VIRTUAL_WIDTH / 2 - 2
    self.y = VIRTUAL_HEIGHT / 2 -2

    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, self.width, self.height)
end```

//edited to fix formatting

Tincloudly commented 4 years ago

I think you should use the math.ramdon function for that On 14 Jul 2020 01:16, ican002 notifications@github.com wrote: Whenever I try to change the state to the play state, I get an error message saying Error main.lua:42: attempt to call method 'collides' (a nil value). Here's my code so far: main.lua: WINDOW_WIDTH = 1280 WINDOW_HEIGHT = 720 VIRTUAL_WIDTH = 432 VIRTUAL_HEIGHT = 243 PADDLE_SPEED = 200 push = require 'push' Class = require 'class' require 'Ball' require 'Paddle' function love.load() math.randomseed(os.time()) love.graphics.setDefaultFilter('nearest', 'nearest') smallFont = love.graphics.newFont('font.ttf', 8) scoreFont = love.graphics.newFont('font.ttf', 32)

player1Score = 0 player2Score = 0

player1 = Paddle(5, 20, 5, 20) player2 = Paddle(VIRTUAL_WIDTH - 10, VIRTUAL_HEIGHT - 30, 5, 20) ball = Ball(VIRTUAL_WIDTH / 2 - 2, VIRTUAL_HEIGHT / 2 - 2, 5, 5)

gameState = 'start'

push:setupScreen(VIRTUAL_WIDTH, VIRTUAL_HEIGHT, WINDOW_WIDTH, WINDOW_HEIGHT, { fullscreen = false, vsync = true, resizable = false })

end function love.update(dt) if gameState == 'play' then ball:update(dt) if ball:collides(player1) then ball.dx = -ball.dx end if ball:collides(player2) then ball.dx = -ball.dx end if ball.y <= 0 then ball.dy = -ball.dy ball.y = 0 end if ball.y >= VIRTUAL_HEIGHT - 5 then ball.dy = -ball.dy ball.y = VIRTUAL_HEIGHT - 4 end end

player1:update(dt) player2:update(dt)

if love.keyboard.isDown('w') then player1.dy = -PADDLE_SPEED elseif love.keyboard.isDown('s') then player1.dy = PADDLE_SPEED else player1.dy = 0 end

if love.keyboard.isDown('up') then player2.dy = -PADDLE_SPEED elseif love.keyboard.isDown('down') then player2.dy = PADDLE_SPEED else player2.dy = 0 end

end function love.keypressed(key) if key == 'escape' then love.event.quit() elseif key == 'enter' or key == 'return' then if gameState == 'start' then gameState = 'play' elseif gameState == 'play' then gameState = 'start' ball:reset() end end

end function love.draw() push:apply('start') love.graphics.clear(40 / 255, 45 / 255, 52 / 255, 255 / 255)

ball:render(VIRTUAL_WIDTH / 2 - 2, VIRTUAL_HEIGHT / 2 - 2, 5, 5) player1:render(5, 20, 5, 20) player2:render(VIRTUAL_WIDTH - 10, VIRTUAL_HEIGHT - 30, 5, 20)

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
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)

displayFPS()

push:apply('end')

end function displayFPS() love.graphics.setColor(0, 1, 0 ,1) love.graphics.setFont(smallFont) love.graphics.print('FPS: ' .. tostring(love.timer.getFPS()), 40, 20) love.graphics.setColor(1, 1, 1, 1) end Ball.lua 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:collides(box) if self.x > box.x + box.width or self.x + self.width < box.x then return false end if self.y > box.y + box.height or self.y + self.height < box.y then return false end return true end function Ball:reset() self.x = VIRTUAL_WIDTH / 2 - 2 self.y = VIRTUAL_HEIGHT / 2 -2 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, self.width, self.height) end

—You are receiving this because you are subscribed to this thread.Reply to this email directly, view it on GitHub, or unsubscribe.