我为我正在进行的游戏编写了一个碰撞检测系统,我遇到了一个奇怪的故障,偶尔会有射弹穿过整个关卡的玩家或墙壁。因为射弹可以以任何角度射击,所以我将每个射弹的边界框分解成多个较小的边界框,然后根据弹丸在空间中的旋转,围绕纹理的中心旋转。出于某种原因,偶尔使用Spear射弹会穿过玩家或墙壁,即使是其他人也不会。
我使用以下方法确定纹理的旋转并转换边界框:
public double RotateToFaceTarget()
{
double rotation = Math.Atan2((double)_direction.Y, (double)_direction.X);
return rotation;
}
public List<BoundingBox> TranslateBoundingBox(List<BoundingBox> box, double rotation)
{
List<BoundingBox> newBounds = new List<BoundingBox>();
foreach (BoundingBox b in box)
{
Vector2 boundsOrigin = new Vector2(b.Pos.X + b.Size.X / 2, b.Pos.Y + b.Size.Y / 2);
Vector2 texOrigin = new Vector2(_pos.X + _texture.Width / 2, _pos.Y + _texture.Height / 2);
Vector2 newPosBasedOnOrigin = Vector2.Transform(boundsOrigin - texOrigin, Matrix.CreateRotationZ((float)rotation)) + boundsOrigin;
newBounds.Add(new BoundingBox(newPosBasedOnOrigin, b.Size));
}
return newBounds;
}
_direction是通过从目标位置减去射弹的位置并进行归一化来计算的。我使用这种方法来确定抛射物是否与另一个实体发生碰撞:
public bool ProjectileCollision(Entity e, Projectile entity2)
{
if (entity2.CanCollide)
{
foreach(GameObject.BoundingBox b in entity2.BoundingBox)
{
foreach(GameObject.BoundingBox b2 in e.BoundingBox)
{
if (b2.Intersect(b) && (entity2.IgnoredEntities.Contains(e.Type) == false))
{
entity2.IsActive = false;
e.Health -= entity2.Damage;
return true;
}
return false;
}
}
return false;
}
return false;
}
这是我的Bounding Box Intersection方法:
public bool Intersect(BoundingBox intersected)
{
if ((_pos.Y < intersected.Pos.Y + intersected.Size.Y) && (_pos.Y + _size.Y > intersected.Pos.Y) && (_pos.X + _size.X > intersected.Pos.X) && (_pos.X < intersected.Pos.X + intersected.Size.X))
{ return true; }
return false;
}
编辑:在进一步测试中,如果玩家基于左上角点击(现在我看到我的交叉码有意义),似乎射弹总会检测到命中。还有另一种方法可以重新编写Intersect方法,使用比左上角更准确的东西吗?
EDIT2:我为某些对象画了一个hitbox,这是我抓住长矛进入玩家的一个例子:
玩家是较大的粉红色方块。 hitboxes没有正确翻译,但它不应该停止工作,对某些人而不是其他人,对吗?
答案 0 :(得分:0)
可能会发生,因为高速度和小物体,弹丸可以飞过物体。除了检查对象是否相交之外,还必须检查对象是否相交,以检查对象是否在火线中。你可以通过光线投射实现这一目标。
在那些像我的函数那样检查对象是否在其他附近的情况下。简单检查对象是否在其他对象的某个半径范围内。如果是,那么我正在检查物体是否飞向其他物体,并检查它们之间的距离。当距离非常接近时,发生碰撞。