XNA如何编写好的碰撞算法?

时间:2017-06-18 14:30:37

标签: c# algorithm xna collision-detection monogame

我目前正在XNA中开发一款新游戏,我只是设置基本内容,如精灵/动画,输入,游戏对象等。

与此同时,我试图想出一种检测所有游戏对象碰撞的好方法,但我真的不能想到快速算法,这会将游戏限制在极少数对象上。 这就是我在上一个项目中所做的学校作业

    public static void UpdateCollisions()
{
    //Empty the list
    AllCollisions.Clear();

    //Find all intersections between collision rectangles in the game
    for (int a = 0; a < AllGameObjectsWithCollision.Count; a++)
    {
        GameObject obja = AllGameObjectsWithCollision[a];
        for (int b = a; b < AllGameObjectsWithCollision.Count; b++)
        {
            GameObject objb = AllGameObjectsWithCollision[b];

            if (obja.Mask != null & objb.Mask!= null && obja != objb && !Exclude(new Collision(obja, objb)))
            {
                if (obja.Mask.CollisionRectangle.Intersects(objb.Mask.CollisionRectangle))
                    AllCollisions.Add(new Collision(obja, objb));
            }
        }
    }
}

因此它会检查所有对象之间的所有碰撞,但不包括添加我认为不必要的碰撞。

然后通知我的对象它们正在碰撞,我使用了一个虚拟方法OnCollision,我这样称呼

//Look for collisions for this entity and if a collision is found, call the OnCollision method in this entity
        var entityCol = FindCollision(entity);

        if (entityCol != null)
        {
            if (entityCol.Other == entity)
                entityCol = new Collision(entity, entityCol.Obj1);
            entity.OnCollision(entityCol);
        }

Collision FindCollision(GameObject obj)
{
    Collision collision = AllCollisions.Find(delegate (Collision col) { return (GameObject)col.Obj1 == obj || (GameObject)col.Other == obj; });
    return collision;
}

当游戏对象的数量增加时,这使我的游戏运行得相当慢。

首先出现在我头脑中的是创造新的线程,这是一个好主意,并且我怎么能这样做呢?

我已经研究了一些算法,所以我知道基本概念以及ordo是如何工作的。

我对c#和整体编程都很陌生,所以如果不解释它就不要太高级了。我学得很快。

1 个答案:

答案 0 :(得分:3)

你可以做很多事情:

嵌套的for循环产生二次运行时间,随着对象数量的增加,这种运行时间会相当快。相反,您可以使用一些加速度数据结构(例如网格,kd树,BVH)。这些允许您将交叉点检查仅减少到可能相交的实体。

如果你可以订购你的实体,你可以通过检查实体对来减少一半的碰撞检查,其中第二个是&#34;更大&#34; (关于订单)比第一个。即如果您已经检查过a-b,则无需检查b-a。

这部分可能很慢:

!Exclude(new Collision(obja, objb)))

如果Collision是一个类,那么它将始终在堆上分配新内存并最终回收它。因此,最好将Collision设为struct(如果尚未设置)或将objaobjb直接传递给Exclude()。这也适用于Collision的其他用途。您还没有显示Exclude()的实现,但如果它是一个简单的线性搜索,则可以改进(例如,如果您在包含每个对象的条目的列表中线性搜索,则您已经有一个立方体只是循环的运行时间。)

FindCollision()的实施很可能是线性搜索(取决于AllCollisions是什么)并且它可能变得非常慢。你为什么要存储碰撞?一旦发现碰撞,你就不能打电话给OnCollision()吗?如果要检查冲突是否与特定实体有效关联,则更合适不同的数据结构(例如哈希映射)。

最后,并行化事物肯定是一个可行的选择。但是,这有点牵扯,我建议首先关注基础知识。如果操作正确,您可以将立方体的运行时间缩短为n log n甚至n