【发布时间】:2013-08-10 21:00:07
【问题描述】:
我一直在尝试在 XNA 4.0 中开发一款 3d 前锋游戏(如 Temple Run)。
我碰到了一堵砖墙,所以任何帮助将不胜感激!
目前,我正在使用自己的碰撞检测方法,这需要将每个模型的尺寸硬编码到碰撞方法中。我试过使用 Microsoft 的代码,直接在下面,但它总是返回 false:
static bool CheckForCollisions(Entity c1, Entity c2)
{
for (int i = 0; i < c1.body.Meshes.Count; i++)
{
// Check whether the bounding boxes of the two cubes intersect.
BoundingSphere c1BoundingSphere = c1.body.Meshes[i].BoundingSphere;
c1BoundingSphere.Center += c1.position;
for (int j = 0; j < c2.body.Meshes.Count; j++)
{
BoundingSphere c2BoundingSphere = c2.body.Meshes[j].BoundingSphere;
c2BoundingSphere.Center += c2.position;
if (c1BoundingSphere.Intersects(c2BoundingSphere))
{
return true;
}
}
}
return false;
}
这是从Here我的实体类中提取和修改的,如下所示。
我认为相关的代码是:
public class Entity
{
public int rowID;
public Model body;
public Vector3 position;
public float rotation = 0f;
public float rotatePerFrame = 0f;
protected internal float toRight = 0;
protected internal float toLeft = 0;
protected internal float forward = 0;
protected internal float back = 0;
protected internal float bottom = 0;
protected internal float top = 0;
public void setDimensions(float right, float left, float front, float back, float top, float bottom)
{
this.toRight = right;
this.toLeft = left;
this.forward = front;
this.back = back;
this.top = top;
this.bottom = bottom;
}
public Entity RotateEnt(Entity e,float degrees)//Psuedo-only accurate to 90 degrees.
{
float actual = MathHelper.ToDegrees(degrees);
switch ((int)actual)
{
case 0:
break;
case 90:
// float temp = e.forward;
// e.forward = e.toLeft;
// e.toLeft =e.back ;
// e.back = e.toRight;
// e.toRight = temp;
float temp = e.forward;
e.forward = e.toRight;
e.toRight = e.back;
e.back = e.toLeft;
e.toLeft = temp;
break;
case 180:
e.forward = e.back;
e.back = e.forward;
e.toRight = e.toLeft;
e.toLeft = e.toRight;
break;
default: //case: 270
e.toRight = e.forward;
e.back = e.toRight;
e.toLeft = e.back;
e.forward = e.toLeft;
break;
}
return e;
}
public bool Collides(Entity e)
{
Entity c1 = RotateEnt(this, this.rotation);
Entity c2 = RotateEnt(e, e.rotation);
float myRightest = c1.position.X + c1.toRight;
float myLeftest = c1.position.X - c1.toLeft;
float hisRightest = c2.position.X + c2.toRight;
float hisLeftest = c2.position.X - c2.toLeft;
if(Collides1D(myLeftest, myRightest, hisLeftest, hisRightest))
{
float myTop = c1.position.Y + c1.top;
float myBottom = c1.position.Y - c1.bottom;
float hisTop = c2.position.Y + c2.top;
float hisBottom = c2.position.Y - c2.bottom;
if (Collides1D(myBottom, myTop, hisBottom, hisTop))
{
float myBack = c1.position.Z - c1.forward;
float myForward = c1.position.Z + c1.back;
float hisBack = c2.position.Z - c2.forward;
float hisForward = c2.position.Z + c2.back;
if (Collides1D(myBack, myForward, hisBack, hisForward))
{
return true;
}
}
}
return false;
}
}
static bool Collides1D(float left1, float right1, float left2, float right2)
{
if (left1 >= left2 && left1 <= right2)
return true;
if (right1 >= left2 && right1 <= right2)
return true;
if (left2 >= left1 && left2 <= right1)
return true;
if (right2 >= left1 && right2 <= right1)
return true;
return false;
}
在尝试旋转模型时,我自己的方法也搞砸了。
理想情况下,最好知道 Microsoft 的代码有什么问题,这样我就可以在任何地方使用它,而不必担心对象维度的硬编码。
如果有人能看到我自己的基本碰撞检测方法的快速修复,那就太好了。
我看过 Reimers 的教程,但我现在没有得到它们,也许我已经盯着自己的代码太久了......
您想要的任何其他信息,我可以尝试提供。如果这是问题,我也可以上传模型。我正在使用 Maya 的模型,导出为 FBX。
我正在使用 MSVS 2010。
非常感谢!
杰克
【问题讨论】:
-
如何更新模型的位置?
-
这是我更新方法中的最后一段代码: if (kbstate.IsKeyDown(Keys.Up) || gpstate.DPad.Up == ButtonState.Pressed) { p1.position.Z -=速度; } cameraPos = p1.position; cameraPos.Y += 275; cameraPos.Z += 550; base.Update(gameTime);
-
我的速度是一个浮点数,目前是 15f,我也有重力,它是: Vector3 重力 = new Vector3(0f, -0.0017f, 0f); //稍后... if (falling) { p1Velocity += (gravity * speed);我已经放慢了速度,以确保我不会“跳过”我可能会碰到的任何东西。
-
您是否尝试过在碰撞检查代码中放置断点?如果您在知道两个模型相交时停止游戏,那么您可以检查 boundingshperes 的值并查看它们不相交的原因。
标签: xna collision-detection xna-4.0 bounding-box fbx