2014-10-03 147 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 
} 

可能有一些錯誤我沒有編譯代碼。如果您的運動速度超過一個像素,則可能需要進行一些調整才能使物體真正粘在牆上。