碰撞跳过某些四边形

本文关键字:四边形 碰撞 | 更新日期: 2023-09-27 18:02:36

我已经在OpenTK的修改版本中制定了自己的碰撞系统。它的工作原理是运行一个foreach循环,检查游戏中的所有四边形(当物体移动时运行),并将它们的位置设置回上一帧的位置,即如果它与这一帧相交。我可能没有很好地解释,所以这里是SetXVelocity代码,当玩家向右移动时调用。

public void SetXVelocity(float x)
        {
            foreach (Quad quad in quads)
            {
                if (!quad.Equals(this))
                {
                    if (Intersects(quad))
                    {
                        Velocity.x = 0;
                        Position = OldPosition;
                        continue;
                    }
                    if (!Intersects(quad))
                    {
                        OldPosition = Position;
                        Velocity.x = x;
                        continue;
                    }
                }
                else
                {
                    OldPosition = Position;
                    continue;
                }
                OldPosition = Position;
                continue;
            }
        }

以下是Intersects的代码:

public bool Intersects(Quad quad)
        {
            #region
            if (TLCorner.x > quad.TLCorner.x && TLCorner.x < quad.BRCorner.x && TLCorner.y < quad.TLCorner.y && TLCorner.y > quad.BRCorner.y)
            {
                 return true;
            }
            if (BRCorner.x < quad.BRCorner.x && BRCorner.x > quad.TLCorner.x && BRCorner.y > quad.BRCorner.y && BRCorner.y < quad.TLCorner.y)
            {
                return true;
            }
            if (TRCorner.x < quad.TRCorner.x && TRCorner.x > quad.BLCorner.x && TRCorner.y < quad.TRCorner.y && TRCorner.y > quad.BLCorner.y)
            {
                return true;
            }
            if (BLCorner.x > quad.BLCorner.x && BLCorner.x < quad.TRCorner.x && BLCorner.y > quad.BLCorner.y && BLCorner.y < quad.TRCorner.y)
            {
                return true;
            }
            #endregion // Corner Intersection
            if (Math.Round(Left, 2) == Math.Round(quad.Right, 2) && TRCorner.y > quad.TRCorner.y && BRCorner.y < quad.BRCorner.y)
                return true;
            if (Math.Round(Right, 2) == Math.Round(quad.Left, 2) && TRCorner.y > quad.TRCorner.y && BRCorner.y < quad.BRCorner.y)
                return true;
            return false;
        }

顺便说一下,TRCorner是一个Vector3表示右上角等

最后一块代码是Quad类,请记住,实际的类是巨大的,所以我将尽量不包括所有的:

public Vector3 Velocity;
public Vector3 Position;
public int Index;
public VBO<Vector3> VertexData
    {
        get;
        set;
    }
    public VBO<int> VertexCount
    {
        get;
        set;
    }
    public VBO<Vector2> VertexTexture
    {
        get;
        set;
    }

由于某种原因,一些四边形没有碰撞,而另一些有。有些甚至有碰撞,让玩家坚持下去。

碰撞跳过某些四边形

我认为有些四分之一是缺失的,因为所有可能的条件都没有包括在你的比较中。

由于您&&了所有条件,因此碰撞需要满足所有条件才能被检测到。

if (TLCorner.x > quad.TLCorner.x && TLCorner.x < quad.BRCorner.x && TLCorner.y < quad.TLCorner.y && TLCorner.y > quad.BRCorner.y)
        {
             return true;
        }

if( TLCorner.x == quad.TLCorner.x && TLCorner.y < quad.TLCorner.y && TLCorner.y > quad.BRCorner.y )矩形仍然碰撞,但未被检测到。

其他情况同。

您可能希望在代码中使用>=<=,以便覆盖所有条件。

至于为什么它们会互相卡住,你的速度可能会把它们推到一个让它们永远碰撞的状态,因为你是在它们相互碰撞之后才检测到碰撞的,而不是在边界重叠的时候。

当检测到碰撞时,你可能想要反转速度并"解除"它们,以一种不会使它们卡在附近其他矩形中的方式。

我强烈建议你使用更好的碰撞检测逻辑

链接:https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection

可以在这里测试http://jsfiddle.net/knam8/