2010-07-28 40 views
2

我試圖做一個遊戲(使用irrlicht引擎與c + +)在哪裏你可以陷阱你的敵人使用框。但是我只是不知道如何檢測用戶和一個或多個盒子之間的碰撞時應該移動什麼。另一件事是,也會有一些叫做磚塊的物體能夠阻止運動。如何將多個矩形移動爲碰撞響應?

因爲我沒有解釋的事情非常好,我包括圖像,所以它會希望澄清我的意思:alt text http://jrahmati.info/images/collision.gif

我試着與我的代碼,但沒有成功幾件事情。所以我真的希望有人會努力回答這個問題。提前致謝。順便說一句,我不需要在C++中的答案,Java或.NET語言也可以。

任何有興趣的代碼:

布爾遊戲:: tryMove(用戶,DIR)它試圖從玩家

bool thereIsCollision = false; 
bool undoMovements = false; 
bool userCollision = false; 
do{ 
    thereIsCollision = false; 
    for (int i = 0; i < totalObjects; i++) { 
     //First check if object hits the user 
     if(gameObjects[i].hits(user)){ 
      if (gameObjects[i]->isMovable()) { 
       MovableObject* mObject = (MovableObject*) gameObjects[i]; 
       mObject->move(dir); 
       mObject->setPushVector(dir); 
       userCollision = true; 
       //thereIsCollision = true; 
      } 
      else{ 
       undoMovements = true; 
       thereIsCollision = false; //To break do-while loop 
       userCollision = true; 
       break; 
      } 
     } 
    } 
    if(undoMovements) 
     break; 
    for (int i = 0; i < totalObjects; i++) { 
     //Then check if objects hit each other 
     for (int i2 = 0; i2 < totalObjects; i2++) { 
      if(i == i2) 
       continue; 
      if (gameObjects[i2].hits(gameObjects[i])){ 
       //thereIsCollision = true; 
       if(gameObjects[i]->isMovable() && gameObjects[i2]->isMovable()){ 
        MovableObject* mObject = (MovableObject*) gameObjects[i]; 
        MovableObject* mObject2 = (MovableObject*) gameObjects[i2]; 
        if(mObject->getPushVector().X > 0 
          || mObject->getPushVector().Y > 0 
          || mObject->getPushVector().Z > 0){ 
         mObject2->move(mObject->getPushVector()); 
         mObject2->setPushVector(mObject->getPushVector()); 
         mObject->setPushVector(irr::core::vector3df(0, 0, 0)); 
        } 
        else if(mObject2->getPushVector().X > 0 
          || mObject2->getPushVector().Y > 0 
          || mObject2->getPushVector().Z > 0){ 
         mObject->move(mObject2->getPushVector()); 
         mObject->setPushVector(mObject2->getPushVector()); 
         mObject2->setPushVector(irr::core::vector3df(0, 0, 0)); 
        } 
       } 
       else{ 
        undoMovements = true; 
        thereIsCollision = false; //To break do-while loop 
        break; 
       } 
      } 
     } 
    } 
}while(thereIsCollision); 

for (int i = 0; i < totalObjects; i++) { 
    if (gameObjects[i]->isMovable()) { 
     MovableObject* mObject = (MovableObject*) gameObjects[i]; 
     if(undoMovements){ 
      // Resets position of gameObject to its previous one 
      mObject->undoMovement(); 
     } 
     else{ 
      // confirms movement(i.e. prevPosition=curPosition) 
      mObject->confirmMovement(); 
     } 
    } 
} 
return !(userCollision); 
+0

我覺得你提供了太多的代碼嚇跑了每一個人。 – Brian 2010-07-28 19:39:13

+0

我猜這個代碼甚至沒有必要,因爲我只想知道如何去做。 – 2010-07-29 05:55:02

回答

0

這是一種推箱子游戲,玩家可以在8個方向上移動,並且可以同時移動幾個盒子?從推箱子的鳥瞰視角來看比賽場地,還是他們在示例中看到的盒子(側視圖,如在俄羅斯方塊中)?盒子和玩家之間的摩擦是無限的(換句話說,玩家接觸的盒子是否會滑向玩家正在移動的方向,當它向對角線移動時)?兩個盒子之間的摩擦是無限的嗎?

我無法專注於您的代碼,但這裏是我的2cents算法。該算法意味着任何兩個物體之間的摩擦是無限的。

當玩家移動時,您需要確定哪些可移動物體可能會受到影響。將玩家在移動方向上觸摸的那些放入搜索堆棧,然後對於搜索堆棧中的每個項目,通過將更多對象放入其中來重複搜索過程。最後,你將耗盡可移動的物體。如果在任何時候你偶然發現一個不可移動的物體,那麼玩家不能移動(因爲無限的摩擦規則),所以沒有任何動作。如果沒有涉及不可移動的對象,則將堆棧中的所有對象移動一個網格單位。

+0

謝謝辯證法,我認爲搜索堆棧將解決這個問題。 – 2010-08-01 17:20:30

0

據我瞭解移開寄託都的內容,你正在使用2D或3D空間,並且你的對象不是放在某種網格上(即座標是浮動的)。在這種情況下有2個解決方案:

解決方案#1:

使用物理引擎,如PhysX物理。

溶液#2:

  1. 重複10或20次,直到沒有更多的碰撞:
    1.1找到所有的重疊的(碰撞)的對象。這包括玩家和盒子。還有箱子與其他箱子碰撞。
    1.2爲每個對象創建「移動」矢量(對象應該移動多少以響應碰撞)m並將其初始化爲全零(x:0,y:0,z:0)。
    1.3對於每對碰撞(重疊)對象A和B,計算將推動它們彼此遠離的向量(稱爲「pushAwayVector」)。將該矢量添加到A.move和B.move。請記住,物體被推向彼此,所以你應該小心的跡象和幅度。即A.move += pushAway*0.5f; B.move += -0.5f*pushAway;。不要替換。使用pushAway矢量移動,但添加pushAway移動。否則結果將不太可靠。您也可以考慮物體的質量,例如:A.move += (B.mass/(A.mass + B.mass))*pushAway; B.move += -(A.mass/(A.mass+B.mass))*pushAway;,在這種情況下,較輕的物體會推重較重的物體會更困難;
    1.4一旦所有重疊的對象進行處理,對於所有對象做obj.position += obj.move;

。注意,在每一種情況下箱不能保證維持精確的相對位置。但是當玩家移動時他們會被推開,他們會阻止玩家的移動。

請注意,使用物理引擎會產生更接近你想要的結果。

另一個解決方案是玩家觸摸一個盒子,找到一組相互碰撞的盒子和一個玩家,然後移除不受當前玩家移動影響的盒子。然而,我不喜歡這個解決方案 - 雖然它會保持相對的對象位置(這看起來不現實),但它很凌亂,缺乏優雅。

我推薦使用物理引擎。

+0

感謝您的回答SigTerm,我會檢查是否可以得到您的任何想法的工作。 「 SigTerm:」據我所知,你使用2d或3d空間,並且你的對象不會放在某種網格上(即座標是浮動)「 第三個維度並不重要,因爲無論如何,包括盒子在內的用戶不斷地在地面上移動(即,盒子太大以至於用戶無論如何都無法跳到它們上) – 2010-07-29 07:03:30

+0

哎呀我忘記提及一些東西,我的問題是還有一些物體叫做磚塊這將阻止用戶移動。 – 2010-07-29 07:10:34

+0

@ILikeGameProgramming:對於不可移動的對象,根本不會改變移動向量。即如果B不可移動,碰撞對象A和B'A.move + = pushAway;'和B.move保持不變。其餘的都是一樣的。 – SigTerm 2010-07-29 12:21:52