2014-10-03 151 views
1

我一直在环顾论坛,我一直无法找到足够的东西来解决我遇到的问题。我试图在2D平台游戏中做一个碰撞检测的功能,起初我可以使它明确命名每个顶点,然后玩家在碰撞后移动到哪里,但这样做效率并不高,有很多重新键入的东西。它会在第一时间工作,但随着时间的推移,它会变得更加麻烦,而不是值得。我正在尝试制作一个碰撞检测功能,它能够告诉我玩家碰撞的哪一侧,并且能够将角色移动到适当的位置。我使用的快板5和C++,这是我的功能迄今:2D碰撞反应

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; 
} 

我怎么能使其以使得在碰撞我的对象将停止,并通过对象不会继续?但也知道它已经落在了某物之上,或者击中了它的一侧或底部,因为它们每个都会有不同的反应。

+3

你的问题是什么? – 2014-10-03 21:13:11

+0

如何使它在碰撞后停止,并且不会继续通过对象 – 2014-10-03 21:18:19

+1

@ Dr.President if(碰撞(x1,y1,h1,w1,x2,y2,h2,w2))StopAndNotContinueThroughTheObject(); '? – Marlon 2014-10-03 21:19:48

回答

1

EDITED AGAIN 如果你希望对象停止之前实际碰撞而不共享相同的实际边缘像素,试试这个:

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; 
} 

OR

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; 
} 

这个答案假定您想知道,当他们两个Object完好占据相同的坐标边缘(即小于/大于或等于没有等于)

这个答案不返回那边是交互边缘。如果你想这样做,那么你可以按照这些方法做更多的事情。

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

+0

好的,谢谢你生病会尝试,我没有想过尝试像那样 – 2014-10-03 21:26:36

+0

但不,这只是告诉我,X值正在交叉?不是实际的碰撞,因为它不需要在界限内,它可以在上面或旁边? – 2014-10-03 21:29:04

+0

我认为你必须更好地定义你真正想要碰撞的是你的应用程序。你可以通过在第二个对象的位置添加一个+ -1修饰符来修改上面的代码以停止JUST。 – trumpetlicks 2014-10-03 21:36:45

0

如果你只是试图阻止玩家在一些成熟的块里面去。你可以在接近球员运动的地方进行碰撞检查。在那里您可以检查每个运动轴,然后在发生碰撞的情况下重做该运动。这样就可以在对象上滑动,并防止在特定轴上的块内进入。 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 
} 

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