我目前正在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#和整体编程都很陌生,所以如果不解释它就不要太高级了。我学得很快。
答案 0 :(得分:3)
你可以做很多事情:
嵌套的for
循环产生二次运行时间,随着对象数量的增加,这种运行时间会相当快。相反,您可以使用一些加速度数据结构(例如网格,kd树,BVH)。这些允许您将交叉点检查仅减少到可能相交的实体。
如果你可以订购你的实体,你可以通过检查实体对来减少一半的碰撞检查,其中第二个是&#34;更大&#34; (关于订单)比第一个。即如果您已经检查过a-b,则无需检查b-a。
这部分可能很慢:
!Exclude(new Collision(obja, objb)))
如果Collision
是一个类,那么它将始终在堆上分配新内存并最终回收它。因此,最好将Collision
设为struct
(如果尚未设置)或将obja
和objb
直接传递给Exclude()
。这也适用于Collision
的其他用途。您还没有显示Exclude()
的实现,但如果它是一个简单的线性搜索,则可以改进(例如,如果您在包含每个对象的条目的列表中线性搜索,则您已经有一个立方体只是循环的运行时间。)
FindCollision()
的实施很可能是线性搜索(取决于AllCollisions
是什么)并且它可能变得非常慢。你为什么要存储碰撞?一旦发现碰撞,你就不能打电话给OnCollision()
吗?如果要检查冲突是否与特定实体有效关联,则更合适不同的数据结构(例如哈希映射)。
最后,并行化事物肯定是一个可行的选择。但是,这有点牵扯,我建议首先关注基础知识。如果操作正确,您可以将立方体的运行时间缩短为n log n
甚至n
。