Pool Game物理速度计算问题

时间:2017-04-04 15:41:35

标签: c++ game-physics velocity

您好我正在制作一个3D池游戏,我目前处于应用碰撞的状态,我正在使用openGL和C ++。我已经写了碰撞并且它正常工作。我所遇到的问题只与球类的速度有关,并且在碰撞时将力传递给其他球。

我有一个球类,用于包括母球在内的所有球。我有一个drawBall()函数:

void drawBall(Shader ourShader) {
    extern GLfloat deltaTime;
    a = F / radius;
    v = v + (a * deltaTime);
    ballPos = ballPos + (v*deltaTime) + (0.5f*a*deltaTime*deltaTime);
    collision();

    //F = glm::vec3(0.0f, 0.0f, 0.0f);
//ACTUAL DRAWING
    glBindVertexArray(VAO);
        glm::mat4 model;

        model = glm::translate(model, ballPos);
        model = glm::rotate(model, glm::radians(40.0f), glm::vec3(1.0f, 0.0f, 0.0f));
        glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
        glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);

碰撞功能:

void collision()  {
    extern vector <Ball> ballCollection;
    for (int i = 0; i < ballCollection.size(); i++) {
        if (glm::distance(ballCollection.at(i).ballPos, ballPos) <= (2 * radius)) {
            if (!glm::distance(ballCollection.at(i).ballPos, ballPos) == 0) {
                extern GLfloat forceAmount;
                if (isColliding == 0) {
                    glm::vec3 collPoint = glm::vec3((ballPos.x + ballCollection.at(i).ballPos.x) / 2, 0.0f, (ballPos.z + ballCollection.at(i).ballPos.z) / 2);
                    glm::vec3 collPointPerp = collPoint - ballPos;

                    glm::vec3 otherNew = collPointPerp;
                    glm::vec3 thisNew = glm::cross(collPointPerp, glm::vec3(0.0, 1.0, 0.0));

                    F = thisNew;
                    ballCollection.at(i).F = otherNew;

                    glm::vec3 newV;
                    glm::vec3 otherNewV;

                    newV.x = (v.x * (2 * ballCollection.at(i).radius * ballCollection.at(i).v.x)) / (radius + ballCollection.at(i).radius);
                    newV.z = (v.z * (2 * ballCollection.at(i).radius * ballCollection.at(i).v.z)) / (radius + ballCollection.at(i).radius);
                    newV.y = 0.0f;

                    otherNewV.x = (ballCollection.at(i).v.x * (2 * radius * v.x)) / (radius + ballCollection.at(i).radius);
                    otherNewV.z = (ballCollection.at(i).v.z * (2 * radius * v.z)) / (radius + ballCollection.at(i).radius);
                    otherNewV.y = 0.0f;



                    v.x = newV.x;
                    v.z = newV.z;

                    ballCollection.at(i).v.x = otherNewV.x;
                    ballCollection.at(i).v.z = otherNewV.z;



                }
                isColliding = 1;
                ballCollection.at(i).isColliding = 1;
            }
        }
    }
    isColliding = 0;

这个calss在我的主要cpp中的一个单独的文件中。这有一个key_kallback函数:

void do_movement()
{
glm::vec3  cameraRight = glm::normalize(glm::cross(cameraFront, cameraUp));
GLfloat cameraSpeed = 50.0f;

glm::vec3 aboveBall = glm::vec3(ballCollection.at(15).ballPos.x, ballCollection.at(15).ballPos.y + 20.0f, ballCollection.at(15).ballPos.z);
glm::vec3 cameraFwd = aboveBall - cameraPos;

//cout << cameraFwd.x << "," << cameraFwd.y << "," << cameraFwd.z << endl;
if (keys[GLFW_KEY_W])
    ballCollection.at(15).ballPos = ballCollection.at(15).ballPos + glm::vec3(0.0f, 0.0f, -0.1f);
if (keys[GLFW_KEY_S])
    ballCollection.at(15).ballPos = ballCollection.at(15).ballPos + glm::vec3(0.0f, 0.0f, 0.1f);
if (keys[GLFW_KEY_A])
    ballCollection.at(15).ballPos = ballCollection.at(15).ballPos + glm::vec3(-0.1f, 0.0f, 0.0f);
if (keys[GLFW_KEY_D])
    ballCollection.at(15).ballPos = ballCollection.at(15).ballPos + glm::vec3(0.1f, 0.0f, 0.0f);
if (keys[GLFW_KEY_SPACE]) {
    ballCollection.at(15).F = 10.0f*glm::normalize(cameraFwd);
}
if (keys[GLFW_KEY_E]) {
    ballCollection.at(15).F = -10.0f * glm::normalize(cameraFwd);
}

}

然后在游戏循环中:

        for (int i = 0; i < 16; i++) {

            ballCollection.at(i).drawBall(ourShader);
        }
        cameraPos = ballCollection.at(15).ballPos + glm::vec3(0.0f, 20.0f, 20.0f);
        do_movement();

我的问题是,当我用空间向主球施加力时,由于F值不断加到v,我的主球速度每帧增加。如果我在施加力后将F重新置于0,我就不能将力传递给其他球,因此它们的v为0并且在碰撞后它们不会移动。

非常感谢任何帮助,如果我需要额外的信息,请发表评论。

修改

我意识到碰撞计算中有错误,应该是:

newV.x = (v.x + (2 * ballCollection.at(i).radius * ballCollection.at(i).v.x)) / (radius + ballCollection.at(i).radius);
newV.z = (v.z + (2 * ballCollection.at(i).radius * ballCollection.at(i).v.z)) / (radius + ballCollection.at(i).radius);
newV.y = 0.0f;

otherNewV.x = (ballCollection.at(i).v.x + (2 * radius * v.x)) / (radius + ballCollection.at(i).radius);
otherNewV.z = (ballCollection.at(i).v.z + (2 * radius * v.z)) / (radius + ballCollection.at(i).radius);
otherNewV.y = 0.0f;

现在,如果我在计算后让F中的F回到零,那么球会以恒定的速度移动,现在这很好。我现在的问题是,有时候碰撞会起作用,有时候球会飞走,有时击中第一个球很好,但如果第二个球击中另一个球则再次出现错误。我认为这是因为他们不断碰撞并计算他们的速度错误,但我无法弄清楚如何设置一个布尔只能碰撞一次,任何人都有任何想法?

修改的 我现在设法正确设置了布尔值。

1 个答案:

答案 0 :(得分:0)

碰撞时,应施加到另一个球的力是速度矢量的大小。因此,如果你传递sqrt(v.x*v.x+v.y*v.y+v.z*v.z)作为碰撞的初始力量,并在施加了你所说的力之后将F设置为零,那么你应该得到你想要的结果。