二维碰撞反应

时间:2014-10-03 21:10:39

标签: c++ 2d collision allegro5

我一直在论坛上四处寻找,但我找不到任何具体的东西,因为我遇到了麻烦。我正在尝试在2D平台游戏中创建碰撞检测功能,并且首先我可以使其明确命名每个顶点,然后玩家将在碰撞时移动到哪里,但这根本没有效率,最终有很多重新输入的东西。它最初会起作用,但随着时间的推移,它将变得更加麻烦而不是它的价值。我正在尝试制作一个碰撞检测功能,它能够告诉我玩家正在碰撞哪一侧,并且能够将角色移动到正确的位置。我正在使用allegro 5和c ++,这是我迄今为止的功能:

bool Collision(int x1,int y1,int h1,int w1,int x2,int y2,int h2,int w2){

    if(x1 < x2 + w2 &&
       x2 < x1 + w1 &&
       y1 < y2 + h2 &&
       y2 < y1 + h1)
       {return 1;}

    return 0;
}

我怎么能这样做,以便在碰撞时我的物体会停止而不能继续通过物体?但也知道它已落在某物之上,或者撞到它的侧面或底部,因为每种都会有不同的反应。

2 个答案:

答案 0 :(得分:1)

再次编辑 如果你想让对象在实际碰撞之前停止而不共享相同的实际边缘像素,试试这个:

bool Collision(int x1,int y1,int h1,int w1,int x2,int y2,int h2,int w2){

    if((x1 + w1) >= (x2 - 1)  ||    // object 1 hitting left side of object 2
       (x1 - 1)  <= (x2 + w2) ||    // object 1 hitting right side of object 2
       (y1 - 1)  <= (y2 + h2) ||    // Object 1 hitting bottom of object 2 (assuming your y goes from top to bottom of screen)
       (y1 + h1) >= (y2 - 1))      // Object 1 hitting top of object 2
        return 1;

    return 0;
}

int Collision(int x1,int y1,int h1,int w1,int x2,int y2,int h2,int w2){

    if((x1 + w1) >= (x2 - 1))  return 1;    // object 1 hitting left side of object 2
    if((x1 - 1)  <= (x2 + w2)) return 2;    // object 1 hitting right side of object 2
    if((y1 - 1)  <= (y2 + h2)) return 3;    // Object 1 hitting bottom of object 2 (assuming your y goes from top to bottom of screen)
    if((y1 + h1) >= (y2 - 1))  return 4;    // Object 1 hitting top of object 2

    return 0;  // no collision
}

这样他们就不应该真正共享同一个像素。

<强> ORIGINAL 我认为你想要的地方更像是:

bool Collision(int x1,int y1,int h1,int w1,int x2,int y2,int h2,int w2){

    if((x1 + w1) >= x2 ||    // object 1 hitting left side of object 2
       x1 <= (x2 + w2) ||    // object 1 hitting right side of object 2
       y1 <= (y2 + h2) ||    // Object 1 hitting bottom of object 2 (assuming your y goes from top to bottom of screen)
       (y1 + h1) >= y2)      // Object 1 hitting top of object 2
        return 1;

    return 0;
}

这个答案假设您希望知道它们两个对象完整OCCUPY何时对齐相同的坐标边缘(即小于/大于或等于与不相等)

然而,这个答案不会返回WHICH EDGE是相互作用的边缘。如果你想要,那么你可以在这些方面做更多的事情。

int Collision(int x1,int y1,int h1,int w1,int x2,int y2,int h2,int w2){

    if((x1 + w1) >= x2) return 1;    // object 1 hitting left side of object 2
    if(x1 <= (x2 + w2)) return 2;    // object 1 hitting right side of object 2
    if(y1 <= (y2 + h2)) return 3;    // Object 1 hitting bottom of object 2 (assuming your y goes from top to bottom of screen)
    if((y1 + h1) >= y2) return 4;    // Object 1 hitting top of object 2

    return 0;  // no collision
}

现在在外面你只需解码1 - 4的边缘检测情况。

答案 1 :(得分:1)

如果你只是想阻止玩家进入平台游戏中。您可以在靠近您正在进行球员移动的地方进行碰撞检查。在那里你可以检查每个运动轴,然后重做那个运动,以防它发生碰撞。这样就可以在物体上滑动并防止进入特定轴上的块。 IE浏览器。 (对不起把所有东西都放到课堂上。我不知道你究竟是什么类型的系统,但我建议使用抽象类。)

bool Collision(GameObject o1, GameObject o2){
  return !(o1.x + o1.w < o2.x || o1.y + o1.h < o2.y || o1.x > o2.x + o2.w || o1.y > o2.y + o2.h);
}

void moveThisObject(GameObject &movingObject) {
    bool redoMovement;                

    // Move and test x-axis movement caused collision.
    movingObject.x += movingObject.speed.x;         
    redoMovement=false;
    for (int t=t;t<objectsInGame;t++) {
            if (Collision(movingObject,gameObj[t])
                    redoMovement=true;
    }
    if (redoMovement)
            movingObject.x -= movingObject.speed.x;

    // Move and test y-axis movement caused collision.
    movingObject.y += movingObject.speed.y;         
    redoMovement=false;
    for (int t=t;t<objectsInGame;t++) {
            if (Collision(movingObject,gameObj[t])
                    redoMovement=true;
    }
    if (redoMovement)
            movingObject.y -= movingObject.speed.y;
} 
class GameObject {
    public:
        double x,y,w,h;
        Vec2 speed;
}
class Vec2 {
    public:
        double x,y;
}

对于检查对象击中哪一侧的函数问题,可以这样做,即用这种方法替换代码中的相应部分:

// for x-axis testing
if (redoMovement) {
    if (movingObject.speed.x>0) //moving object hit object2 from left to right
        movingObject.x -= 1; // move back left
    if (movingObject.speed.x<0) //moving object hit object2 from right to left
        movingObject.x += 1; // move back right
}
// for y-axis testing
if (redoMovement) {
    if (movingObject.speed.y>0) //moving object hit object2 from up to down
        movingObject.y -= 1; // move back down
    if (movingObject.speed.y<0) //moving object hit object2 from down to up
        movingObject.y += 1; // move back   up
}

可能有些错误我没有编译代码。如果您的移动速度超过一个像素,则可能需要进行一些调整以使对象真正粘在墙壁上。