Как я могу изменить цвет мяча в pong, когда он сталкивается с ракеткой в ​​Lua, используя Love2D - PullRequest
0 голосов
/ 10 июля 2020

Итак, я пытаюсь создать игру, которая имитирует понг, и в настоящее время я застрял на одном предмете. Я хочу, чтобы когда мяч сталкивался с любой ракеткой, он менял цвет. Вот только это не так, как я говорю. Был бы очень признателен, если бы кто-нибудь мог дать совет относительно решения этой проблемы, которая у меня сейчас возникла, в любом случае вот код. Я даю только основной файл и класс мяча, так как это единственный важный элемент, который, как мне кажется, вам понадобится. Это написано в Lua с помощью Love2D. Это старая версия Love2D, а точнее 0.10.2

main. lua:

push = require 'push'

Class = require 'class'

require 'Paddle'
require 'Ball'

windowWidth = 1280
windowHeight = 720

virtualWidth = 432
virtualHeight = 243

paddleSpeed = 200

-- Boolean values that can be changed if we want a paddle to become an AI
AIMode = false     -- left paddle AI
AIMode_2 = false   -- right paddle AI

AISpeed = 0


function love.load()
    love.graphics.setDefaultFilter('nearest', 'nearest')

    love.window.setTitle('Pong')

    math.randomseed(os.time())

    smallFont = love.graphics.newFont('font.ttf', 8)
    largeFont = love.graphics.newFont('font.ttf', 16)
    scoreFont = love.graphics.newFont('font.ttf', 32)
    
    sounds = {
        ['paddle_hit'] = love.audio.newSource('sounds/paddle_hit.wav', 'static'),
        ['score'] = love.audio.newSource('sounds/score.wav', 'static'),
        ['wall_hit'] = love.audio.newSource('sounds/wall_hit.wav', 'static')
    }

    love.graphics.setFont(smallFont)

    push:setupScreen(virtualWidth, virtualHeight, windowWidth, windowHeight, {
        fullscreen = false,
        resizable = false,
        vsync = true
    })

    p1_score = 0
    p2_score = 0

    servingPlayer = 1
    
    winningPlayer = 0

    player_1 = Paddle(10, 30, 5, 20)
    player_2 = Paddle(virtualWidth - 10, virtualHeight - 30, 5, 20)
    ball = Ball(virtualWidth / 2 - 2, virtualHeight / 2 - 2, 4, 4)

    gameState = 'start'
end

function love.update(dt)
    if gameState == 'serve' then

        ball.dy = math.random(-50, 50)
        if servingPlayer == 1 then
            ball.dx = math.random(140, 200)
        else
            ball.dx = -math.random(140, 200)
        end
    elseif gameState == 'play' then
        if ball:collides(player_1) then
            ball.dx = -ball.dx * 1.03
            ball.x = player_1.x + 5

            if ball.dy < 0 then
                ball.dy = -math.random(10, 150)
            else
                ball.dy = math.random(10, 150)
            end
            
            sounds['paddle_hit']:play()
        end
        if ball:collides(player_2) then
            ball.dx = -ball.dx * 1.03
            ball.x = player_2.x - 4

            if ball.dy < 0 then
                ball.dy = -math.random(10, 150)
            else
                ball.dy = math.random(10, 150)
            end
            
            sounds['paddle_hit']:play()
        end

        if ball.y <= 0 then
            ball.y = 0
            ball.dy = -ball.dy
            sounds['wall_hit']:play()
        end

        if ball.y >= virtualHeight - 4 then
            ball.y = virtualHeight - 4
            ball.dy = -ball.dy
            sounds['wall_hit']:play()
        end
    end

    if ball.x < 0 then
        ball:reset()
        gameState = 'serve'
        servingPlayer = 1
        p2_score = p2_score + 1
        sounds['score']:play()
    end
    
    if p2_score == 10 then
        winningPlayer = 2
        gameState = 'done'
    end

    if ball.x > virtualWidth then
        ball:reset()
        gameState = 'serve'
        servingPlayer = 2
        p1_score = p1_score + 1
        sounds['score']:play()
    end 
    
    if p1_score == 10 then 
        winningPlayer = 1
        gameState = 'done'
    end
    
    if AIMode == true and AIMode_2 == true then
        if p1_score == 3 then
            winningPlayer = 1
            gameState = 'done'
        elseif p2_score == 3 then
            winningPlayer = 2
            gameState = 'done'
        end
    end
    
    -- For Single Player Mode
    -- If only the left paddle is AI, then left paddle's Y position will be the same as the ball's Y position. Only the right will be controlled by the player by pressing keys 'up', and 'down'
    if AIMode == true and AIMode_2 == false then
        player_1.y = ball.y
        if love.keyboard.isDown('up') then
            player_2.dy = -paddleSpeed
        elseif love.keyboard.isDown('down') then
            player_2.dy = paddleSpeed
        else
            player_2.dy = 0
        end 
    end
    
    -- For Auto Mode
    -- If both paddles are AI, then both paddle's y position will be the same as the ball's y postion
    if AIMode == true and AIMode_2 == true then
        player_1.y = ball.y
        player_2.y = ball.y
    end
    
    -- For 2 Player Mode
    -- If no paddles are AI, then left paddle will be controlled by pressing 'w' and 's', and the right paddle will be controlled by pressing 'up' and 'down'
    if AIMode == false and AIMode_2 == false then
        if love.keyboard.isDown('w') then
            player_1.dy = -paddleSpeed
        elseif love.keyboard.isDown('s')then
            player_1.dy = paddleSpeed
        else 
            player_1.dy = 0
        end
        
        if love.keyboard.isDown('up') then
            player_2.dy = -paddleSpeed
        elseif love.keyboard.isDown('down') then
            player_2.dy = paddleSpeed
        else
            player_2.dy = 0
        end
    end

    if gameState == 'play' then
        ball:update(dt)
    end

    player_1:update(dt)
    player_2:update(dt)
end

function love.keypressed(key)

    -- if key '1' is pressed in start screen, then left paddle will become AI
    -- Single Player Mode
    if key == '1' and gameState == 'start' then
        AIMode = true
        AIMode_2 = false
    
    -- if key '2' is pressed in start screen, then both paddles will become AI
    -- Auto Mode
    elseif key == '2' and gameState == 'start' then
        AIMode_2 = true
        AIMode = true
    
    -- if key '3' is pressed, then no paddles will become AI
    -- 2 Player Mode
    elseif key == '3' and gameState == 'start' then
        AIMode = false 
        AIMode_2 = false
    end

    if key == 'escape' then
        love.event.quit()
    elseif key == 'enter' or key == 'return' then
        if gameState == 'start' then
            gameState = 'serve'
        elseif gameState == 'serve' then
            gameState = 'play'
        elseif gameState == 'done' then
            ball:reset()
            p1_score = 0
            p2_score = 0
            if winningPlayer == 1 then  
                servingPlayer = 2
            else
                servingPlayer = 1
            end
            if key == 'enter' or key == 'return' then
                gameState = 'serve'
            end
            
        -- if playing and enter is pressed, then ball will reset, and player will be brought back to the start screen
        -- soft reset
        elseif gameState == 'play' then
            gameState = 'start'
            ball:reset()
        end
    end
        
    -- if 'r' is pressed in any state, then all score will reset, as well as the entire game, and player will be brought back to the start screen
    -- hard reset
    if key == 'r' then
        if gameState == 'start' or gameState == 'serve' or gameState == 'play' or gameState == 'done' then
            gameState = 'start'
            p1_score = 0
            p2_score = 0
            ball:reset()
        
        end
    end
end

function love.draw()

    push:apply('start')

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

    love.graphics.setFont(smallFont)

    displayScore()

    if gameState == 'start' then
        love.graphics.setFont(smallFont)
        if AIMode == true and AIMode_2 == false then
            love.graphics.printf('AI Mode ON! Computer vs. Player!', 0, 30, virtualWidth, 'center')
        elseif AIMode_2 == true and AIMode == true then 
            love.graphics.printf('AI Mode ON! Computer vs. Computer!', 0, 30, virtualWidth, 'center')
        elseif AIMode == false and AIMode_2 == false then
            love.graphics.printf('AI Mode OFF! 2 Player Mode!', 0, 30, virtualWidth, 'center')
        end
        love.graphics.printf('Welcome to Pong', 0, 10, virtualWidth, 'center') 
        love.graphics.printf('Press Enter to Begin! Press 1 for Single Player Mode, 2 for Automatic Mode, 3 for 2 Player Mode!', 0, 20, virtualWidth, 'center')
    elseif gameState == 'serve' then
        if AIMode == false and AIMode_2 == false then
            love.graphics.setFont(smallFont)
            love.graphics.printf('Player ' .. tostring(servingPlayer) .. "'s serve!", 0, 10, virtualWidth, 'center')
            love.graphics.printf('Press Enter to Serve!', 0, 20, virtualWidth, 'center')
        
        elseif AIMode == true and AIMode_2 == false then
            if servingPlayer == 1 then
                love.graphics.setFont(smallFont)
                love.graphics.printf('Computer Serve!', 0, 10, virtualWidth, 'center')
                love.graphics.printf('Press Enter to Serve!', 0, 20, virtualWidth, 'center')
            else
                love.graphics.setFont(smallFont)
                love.graphics.printf('Player Serve!', 0, 10, virtualWidth, 'center')
                love.graphics.printf('Press Enter to Serve!', 0, 20, virtualWidth, 'center')
            end
        
        elseif AIMode == true and AIMode_2 == true then
            love.graphics.setFont(smallFont)
            love.graphics.printf('Computer ' .. tostring(servingPlayer) .. "'s serve!", 0, 10, virtualWidth, 'center')
            love.graphics.printf('Press Enter to Serve!', 0, 20, virtualWidth, 'center')
        end
        
    elseif gameState == 'play' then
        
    elseif gameState == 'done' then
        if AIMode == false and AIMode_2 == false then
            love.graphics.setFont(largeFont)
            love.graphics.printf('Player ' .. tostring(winningPlayer) .. ' wins!', 0, 10, virtualWidth, 'center')
            love.graphics.setFont(smallFont)
            love.graphics.printf('Press Enter to Restart!', 0, 30, virtualWidth, 'center')
        
        elseif AIMode == true and AIMode_2 == false then
            if winningPlayer == 1 then
                love.graphics.setFont(largeFont)
                love.graphics.printf('Computer Wins!', 0, 10, virtualWidth, 'center')
                love.graphics.setFont(smallFont)
                love.graphics.printf('Press Enter to Restart!', 0, 30, virtualWidth, 'center')
            else
                love.graphics.setFont(largeFont)
                love.graphics.printf('Player Wins!', 0, 10, virtualWidth, 'center')
                love.graphics.setFont(smallFont)
                love.graphics.printf('Press Enter to Restart!', 0, 30, virtualWidth, 'center')
            end
        
        elseif AIMode == true and AIMode_2 == true then
            love.graphics.setFont(largeFont)
            love.graphics.printf('Computer ' .. tostring(winningPlayer) .. ' wins!', 0, 10, virtualWidth, 'center')
            love.graphics.setFont(smallFont)
            love.graphics.printf('Press Enter to Restart!', 0, 30, virtualWidth, 'center')
        end
    end 
    
    love.graphics.setColor(255, 0, 0, 255)
    player_1:render()
    love.graphics.setColor(255, 255, 0, 255)
    player_2:render()
    love.graphics.setColor(255, 255, 255, 255)
    
    -- this is where I am having the issue
    if ball:collides(player_1) then
        love.graphics.setColor(255, 0, 0, 255)
    elseif ball:collides(player_2) then
        love.graphics.setColor(255, 255, 0, 255)
    end
    
    ball:render()

    displayFPS()

    push:apply('end')
end

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

function displayScore()
    love.graphics.setFont(scoreFont)
    love.graphics.setColor(255, 0, 0, 255)
    love.graphics.print(tostring(p1_score), virtualWidth / 2 - 50, 
        virtualHeight / 3)
    love.graphics.setColor(255, 255, 0, 255)
    love.graphics.print(tostring(p2_score), virtualWidth / 2 + 30,
        virtualHeight / 3)
    love.graphics.setColor(255, 255, 255, 255)
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.dy = math.random(2) == 1 and -100 or 100
    self.dx = math.random(2) == 1 and math.random(-80, -100) or math.random(80, 100)
end

function Ball:collides(paddle)
    if self.x > paddle.x + paddle.width or paddle.x > self.x + self.width then
        return false
    end

    if self.y > paddle.y + paddle.height or paddle.y > self.y + self.height then
        return false
    end 

    love.graphics.setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255), 255)
    
    return true
end

function Ball:reset()
    self.x = virtualWidth / 2 - 2
    self.y = virtualHeight / 2 - 2
    self.dy = math.random(2) == 1 and -100 or 100
    self.dx = 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

Весло. lua

Paddle = Class{}

function Paddle:init(x, y, width, height)
    self.x = x
    self.y = y
    self.width = width
    self.height = height
    self.dy = 0
end

function Paddle:update(dt)
    if self.dy < 0 then
        self.y = math.max(0, self.y + self.dy * dt)
    else
        self.y = math.min(virtualHeight - self.height, self.y + self.dy * dt)
    end
end

function Paddle:render()
    love.graphics.rectangle('fill', self.x, self.y, self.width, self.height)
end

1 Ответ

0 голосов
/ 10 июля 2020

nevermind Я сделал кое-что и создал новую переменную с именем ballCollDetect, где значение по умолчанию равно 0. Если он попадает в левую ракетку, она превращается в 1, а если она попадает в правую ракетку, она превращается в 2. Итак, если он = 1, тогда цвет шара будет красным, а если он = 2, тогда цвет шара будет желтым, а значение по умолчанию просто сделает цвет шара белым. На самом деле довольно просто.

...