为什么我的上电没有显示在我的LOVE2D游戏中?

问题描述

我目前正在做一个名为PlayBall的Pong Remake,这是一个彩色版本,具有通电,模式和新功能。我现在使用的是Alpha 2.0(Powerup概念),我想将我的第一个Powerup称为AddBall。

功能的作用是当球与球碰撞时,会产生一个新球。

我在AddBall.lua中设置了代码

AddBall = Class{}

local spawner = math.random(10,20)

function AddBall:init(x,y)
    self.x = x
    self.y = y
    self.width = 8
    self.height = 8
    
    self.timer = 0
    
    self.inPlay = false
end

function AddBall:collides(ball)
    -- first,check to see if the left edge of either is farther to the right
    -- than the right edge of the other
    if self.x > ball.x + ball.width or ball.x > self.x + self.width then
        return false
    end

    -- then check to see if the bottom edge of either is higher than the top
    -- edge of the other
    if self.y > ball.y + ball.height or ball.y > self.y + self.height then
        return false
    end 

    -- if the above aren't true,they're overlapping
    return true
end

function AddBall:update(dt)
    self.timer = self.timer + dt
    
    if self.timer > spawner then
        self.inPlay = true
    end
    
    if self.inPlay then
        self:render()
    end
end

function AddBall:render()
    love.graphics.draw(textures['powerups'],frames['powerups'][1],self.x,self.y)
end

function AddBall:reset()
    self.timer = 0
    self.inPlay = false
    spawner = math.random(10,20)
end

这是我做的最好的。然后,我在main.lua中分配了一大堆东西来加载道具和第二球:

--[[
    Called just once at the beginning of the game; used to set up
    game objects,variables,etc. and prepare the game world.
]]
function love.load()
    -- set love's default filter to "nearest-neighbor",which essentially
    -- means there will be no filtering of pixels (blurriness),which is
    -- important for a nice crisp,2D look
    love.graphics.setDefaultFilter('nearest','nearest')

    -- set the title of our application window
    love.window.setTitle('PlayBall')

    -- seed the RNG so that calls to random are always random
    math.randomseed(os.time())

    -- initialize our nice-looking retro text fonts
    smallFont = love.graphics.newFont('font.ttf',8)
    largeFont = love.graphics.newFont('font.ttf',16)
    scoreFont = love.graphics.newFont('font.ttf',32)
    love.graphics.setFont(smallFont)

    -- set up our sound effects; later,we can just index this table and
    -- call each entry's `play` method
    sounds = {
        ['paddle_hit'] = love.audio.newSource('sounds/paddle_hit.wav','static'),['score'] = love.audio.newSource('sounds/score.wav',['wall_hit'] = love.audio.newSource('sounds/wall_hit.wav','static')
    }
    
    textures = {
        ['powerups'] = love.graphics.newImage('graphics/powerups.png')
    }
    
    frames = {
        ['powerups'] = GenerateQuadsPowerups(textures['powerups'])
    }
    
    -- initialize our virtual resolution,which will be rendered within our
    -- actual window no matter its dimensions
    push:setupScreen(VIRTUAL_WIDTH,VIRTUAL_HEIGHT,WINDOW_WIDTH,WINDOW_HEIGHT,{
        fullscreen = false,resizable = true,vsync = true
    })

    -- initialize our player paddles; make them global so that they can be
    -- detected by other functions and modules
    player1 = Paddle(10,30,5,20)
    player2 = Paddle(VIRTUAL_WIDTH - 10,VIRTUAL_HEIGHT - 30,20)

    -- place a ball in the middle of the screen
    ball1 = Ball(VIRTUAL_WIDTH / 2 - 2,VIRTUAL_HEIGHT / 2 - 2,4,1)
    ball2 = Ball(ball1.x,ball1.y,2)
    
    powerup1 = AddBall(math.random(20,VIRTUAL_WIDTH - 20),math.random(0,VIRTUAL_HEIGHT - 8))

    -- set up in play to ensure it is in game
    ball1.inPlay = true

    -- initialize score variables
    player1score = 0
    player2score = 0

    -- either going to be 1 or 2; whomever is scored on gets to serve the
    -- following turn
    servingPlayer = 1

    -- player who won the game; not set to a proper value until we reach
    -- that state in the game
    winningPlayer = 0

    -- the state of our game; can be any of the following:
    -- 1. 'start' (the beginning of the game,before first serve)
    -- 2. 'serve' (waiting on a key press to serve the ball)
    -- 3. 'play' (the ball is in play,bouncing between paddles)
    -- 4. 'done' (the game is over,with a victor,ready for restart)
    gameState = 'start'
end

然后游戏更新:

--[[
    Called every frame,passing in `dt` since the last frame. `dt`
    is short for `deltaTime` and is measured in seconds. Multiplying
    this by any changes we wish to make in our game will allow our
    game to perform consistently across all hardware; otherwise,any
    changes we make will be applied as fast as possible and will vary
    across system hardware.
]]
function love.update(dt)
    if gameState == 'serve' then
        -- before switching to play,initialize ball's veLocity based
        -- on player who last scored
        ball1.dy = math.random(-50,50)
        if servingPlayer == 1 then
            ball1.dx = math.random(140,200)
        else
            ball1.dx = -math.random(140,200)
        end
    elseif gameState == 'play' then
        -- detect ball collision with paddles,reversing dx if true and
        -- slightly increasing it,then altering the dy based on the position
        -- at which it collided,then playing a sound effect
        if ball1:collides(player1) then
            ball1.dx = -ball1.dx * 1.03
            ball1.x = player1.x + 5

            -- keep veLocity going in the same direction,but randomize it
            if ball1.dy < 0 then
                ball1.dy = -math.random(10,150)
            else
                ball1.dy = math.random(10,150)
            end

            sounds['paddle_hit']:play()
        end
        if ball1:collides(player2) then
            ball1.dx = -ball1.dx * 1.03
            ball1.x = player2.x - 4

            -- keep veLocity going in the same direction,150)
            end

            sounds['paddle_hit']:play()
        end
        if ball2:collides(player1) then
            ball2.dx = -ball2.dx * 1.03
            ball2.x = player1.x + 5

            -- keep veLocity going in the same direction,but randomize it
            if ball2.dy < 0 then
                ball2.dy = -math.random(10,150)
            else
                ball2.dy = math.random(10,150)
            end

            sounds['paddle_hit']:play()
        end
        if ball2:collides(player2) then
            ball2.dx = -ball2.dx * 1.03
            ball2.x = player2.x - 4

            -- keep veLocity going in the same direction,150)
            end

            sounds['paddle_hit']:play()
        end

        -- detect upper and lower screen boundary collision,playing a sound
        -- effect and reversing dy if true
        if ball1.y <= 0 then
            ball1.y = 0
            ball1.dy = -ball1.dy
            sounds['wall_hit']:play()
        end

        -- -4 to account for the ball's size
        if ball1.y >= VIRTUAL_HEIGHT - 4 then
            ball1.y = VIRTUAL_HEIGHT - 4
            ball1.dy = -ball1.dy
            sounds['wall_hit']:play()
        end
        
        -- detect upper and lower screen boundary collision,playing a sound
        -- effect and reversing dy if true
        if ball2.y <= 0 then
            ball2.y = 0
            ball2.dy = -ball2.dy
            sounds['wall_hit']:play()
        end

        -- -4 to account for the ball's size
        if ball2.y >= VIRTUAL_HEIGHT - 4 then
            ball2.y = VIRTUAL_HEIGHT - 4
            ball2.dy = -ball2.dy
            sounds['wall_hit']:play()
        end

        -- if we reach the left edge of the screen,go back to serve
        -- and update the score and serving player
        if ball1.x < 0 then
            servingPlayer = 1
            player2score = player2score + 1
            sounds['score']:play()

            -- if we've reached a score of 10,the game is over; set the
            -- state to done so we can show the victory message
            if player2score == 10 then
                winningPlayer = 2
                gameState = 'done'
            else
                gameState = 'serve'
                -- places the ball in the middle of the screen,no veLocity
                ball1:reset()
            end
        end

        -- if we reach the right edge of the screen,go back to serve
        -- and update the score and serving player
        if ball1.x > VIRTUAL_WIDTH then
            servingPlayer = 2
            player1score = player1score + 1
            sounds['score']:play()

            -- if we've reached a score of 10,the game is over; set the
            -- state to done so we can show the victory message
            if player1score == 10 then
                winningPlayer = 1
                gameState = 'done'
            else
                gameState = 'serve'
                -- places the ball in the middle of the screen,no veLocity
                ball1:reset()
            end
        end
        
        -- check if ball powerup is added
        if powerup1:collides(ball1) then
            ball2.inPlay = true
            ball2:update(dt)
            powerup1:reset()
        end
        
        -- ball 2 is resetted when it hits the edge
        if ball2.x < 0 or ball2.x > VIRTUAL_WIDTH then
            ball2.inPlay = false
        end
    end

    --
    -- paddles can move no matter what state we're in
    --
    -- player 1
    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

    -- player 2
    if aimode == true then
        player2.y = ball1.y
    elseif aimode == false then
        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

    -- update our ball based on its DX and DY only if we're in play state;
    -- scale the veLocity by dt so movement is framerate-independent
    if gameState == 'play' then
        ball1:update(dt)
    end

    player1:update(dt)
    player2:update(dt)
    powerup1:update(dt)
end

我的问题是通电不会产生,从而使通电概念不完整。我不确定是否导致渲染问题,或者计时不顺利。

我的猜测是我在Ball.lua上遇到了问题:

Ball = Class{}

function Ball:init(x,y,width,height,num)
    self.x = x
    self.y = y
    self.width = width
    self.height = height
    self.count = num

    -- these variables are for keeping track of our veLocity on both the
    -- X and Y axis,since the ball can move in two dimensions
    self.dy = 0
    self.dx = 0
    
    self.inPlay = false
end

--[[
    Expects a paddle as an argument and returns true or false,depending
    on whether their rectangles overlap.
]]
function Ball:collides(paddle)
    -- first,check to see if the left edge of either is farther to the right
    -- than the right edge of the other
    if self.x > paddle.x + paddle.width or paddle.x > self.x + self.width then
        return false
    end

    -- then check to see if the bottom edge of either is higher than the top
    -- edge of the other
    if self.y > paddle.y + paddle.height or paddle.y > self.y + self.height then
        return false
    end 

    -- if the above aren't true,they're overlapping
    return true
end

--[[
    Places the ball in the middle of the screen,with no movement.
]]
function Ball:reset()
    self.x = VIRTUAL_WIDTH / 2 - 2
    self.y = VIRTUAL_HEIGHT / 2 - 2
    self.dx = 0
    self.dy = 0
end

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

function Ball:render()
    if self.inPlay then
        love.graphics.setFont(smallFont)
        love.graphics.setColor(0/255,0/255,255/255)
        love.graphics.printf(tostring(self.count),2,self.y - 8,VIRTUAL_WIDTH,'center')
        love.graphics.rectangle('fill',self.x + 2,self.y + 2,self.width,self.height)
        love.graphics.setColor(255/255,255/255,self.y - 10,self.y,self.height)
    end
end

或者在AddBall.lua中,但是我的力量不会产生。你能告诉我为什么吗?

如果您想仔细看的话,我会将这些东西发布在GitHub上,我的AddBall功能是绿色的十字形。

解决方法

我认为这是因为您只有在通电与ball1冲突时才更新ball2。由于您是用update方法渲染球的,因此只有在更新时(如果没有更新),您才能看到它。

我建议您宁愿这样做:

if ball2.inPlay then
     ball2:update(dt)
end
,

您说您的加电没有显示。可能是因为您出于这种原因未在powerup1:render()中调用love.draw。尝试更新生成道具和球的概念,因为您需要以某种方式进行渲染。

尝试这样:

if powerup1.inPlay then
    powerup1:render()
end