2010-07-28 63 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