我正在尝试制作游戏(使用带有c ++的irrlicht引擎),你可以使用盒子捕获你的敌人。但是,当我检测到用户与一个或多个盒子之间的碰撞时,我只是不知道如何检测应该移动的内容。另一件事是,还会有一些叫砖的物体能够阻挡运动。
由于我不太善于解释事物,所以我添加了一张图片,因此希望澄清我的意思:alt text http://jrahmati.info/images/collision.gif
我用我的代码尝试了几件事但没有成功。所以我真的希望有人会努力回答这个问题。提前致谢。 顺便说一句,我不需要c ++,java或.Net语言中的答案也可以。
对于对代码感兴趣的人:
bool Game :: 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 :(得分:0)
据我了解,你使用的是2d或3d空间,而你的对象并没有放在某种网格上(即坐标是浮点数)。在这种情况下,有两种解决方案:
解决方案#1:
使用物理引擎,例如PhysX。
解决方案#2:
A.move += pushAway*0.5f; B.move += -0.5f*pushAway;
。不要替换 .move与pushAway向量,但添加pushAway移动。否则结果将不太可靠。您还可以考虑物体的质量,如下所示:A.move += (B.mass/(A.mass + B.mass))*pushAway; B.move += -(A.mass/(A.mass+B.mass))*pushAway;
,在这种情况下,较轻的物体更难以推动较重的物体; obj.position += obj.move;
请注意,在每种情况下,都不能保证盒子保持精确的相对位置。但是当玩家移动时,它们会被推开,并且会阻挡玩家的移动。
请注意,使用物理引擎会产生更接近您想要的结果。
另一种解决方案是,一旦玩家触摸一个盒子,找到彼此碰撞的一组盒子和一个玩家,然后移除不受当前玩家移动影响的盒子。但是,我不喜欢这种解决方案 - 它很杂乱,缺乏优雅,虽然它会保持相对的对象位置(这也看起来不切实际)。
我建议使用物理引擎。
答案 1 :(得分:0)
这是一种推箱子游戏,玩家可以在8个方向移动,并且能够一次移动几个盒子吗?从Sokoban的鸟瞰视角观看比赛场地,还是他们在示例中看到的落下的箱子(侧视图,如俄罗斯方块)?盒子和玩家之间的摩擦力是无限的(换句话说,当玩家正在移动的方向,当它对角移动时,是否禁止玩家正在触摸的盒子滑动)?两个盒子之间的摩擦是无限的吗?
我无法专注于你的代码,但这是我的2cents算法。该算法意味着任何两个对象之间的摩擦是无限的。
当玩家移动时,您需要确定哪些可移动物体可能受到影响。将播放器在移动方向上触摸的那些放入某些搜索堆栈,然后对于搜索堆栈中的每个项目,通过将更多对象放入其中来重复搜索过程。最后,你将耗尽可移动的物体。如果你在任何时候偶然发现一个不可移动的物体,那么玩家也不能移动(因为无限的摩擦规则),所以没有任何动作。如果没有涉及不可移动的对象,则将堆栈中的所有对象移动一个网格单元。