BreakOut游戏中砖碰撞检测的问题

时间:2013-05-18 13:19:41

标签: java collision-detection acm breakout

我完成了我的第一个BreakOut游戏,同时完成了斯坦福大学CS在线课程的java任务。

然而我注意到在比赛测试期间,当球在对角线行进时有时碰到一块砖时,最终会以不自然的方式连续击中几块砖。

我猜我必须改进一下我的碰撞检测代码,我已经尝试了几件事但无济于事。

我正在使用ACM库来执行此程序。假想的矩形环绕着我的球,我使用该矩形的4个角来检测碰撞。

在游戏过程中,由于我添加了几个插件(掉落并给你奖励的物品),游戏中有很多速度变化 - vx变量变化很大。

我认为这与我的问题有关,因为我注意到,当球的行进速度超过连续破坏的几块砖的速度时,它就会出现。

我会在这里添加相关代码。但是,您可以在此处查看所有代码:https://gist.github.com/frodosda/5604272

// Defines the initial Direction of the Ball - inside the "MoveBall" Method
    vx = rGen.nextDouble(1.0, 3.0); // Random Horizontal Direction
    if (rGen.nextBoolean(0.5)) vx = -vx;
    vy = 2.0; // Vertical Direction

/** Checks if the ball collided or not with an object */

private void verificarColisaoBola () {

    GObject objColisao = getObjColisao(); // The object with wich the ball colided

    if (objColisao == raquete) { // If colidded with paddle
        vy = -vy; // Change vertical tranjectory of ball
        // prevents that the ball get "glued" to the paddle
        bola.setLocation(bola.getX(),bola.getY() - PADDLE_HEIGHT / 2);

        // Changes the direction of the ball when it hits the borders of the paddle - provides the player more control
        if ((bola.getX() < raquete.getX() + 0.20 * raquete.getWidth() && vx > 0)
            || (bola.getX() > raquete.getX() + 0.80 * raquete.getWidth() && vx < 0)) {
            vx = -vx;
        }

    } else if (objColisao != null) { // Colision with a brick
        remove (objColisao); // remove the brick
        nTijolos--; // counts one less brick
        vy = -vy; // Changes vertical direction
}

/** Finds if the limits of the ball - 4 corners - hits an object  
 * @return The object that collided with the ball - or null */

private GObject getObjColisao () {
    if (getElementAt (bola.getX(), bola.getY()) != null) { // Top left corner
        return getElementAt (bola.getX(), bola.getY());
    } else if (getElementAt (bola.getX() + bola.getWidth(), bola.getY()) != null) { // Top Right corner
        return getElementAt (bola.getX() + bola.getWidth(), bola.getY());
    } else if (getElementAt (bola.getX(), bola.getY() + bola.getWidth()) != null) { // Bottom Left corner
        return getElementAt (bola.getX(), bola.getY() + bola.getWidth());
    } else if (getElementAt (bola.getX() + bola.getWidth(), bola.getY() + bola.getWidth()) != null) { // Bottom Right corner
        return getElementAt (bola.getX() + bola.getWidth(), bola.getY() + bola.getWidth());
    } else {
        return null;
    }
}

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

你需要检查你的时间步。具有大时间步长的速度通常会导致对象在下一个时间步骤中击中多个项目。因此,让您的时间步长更小,以便更频繁地进行碰撞检测。

您还应该做一些更聪明的分析并检查您将要击中的第一块砖(具有最大/最小x或y值的砖),然后停在那里。然后你需要计算这次碰撞后球的最终位置,这样即使有很长的时间步,球的行为也应该如此。