提高冲突检测的效率 (C# XNA)
本文关键字:XNA 效率 冲突检测 | 更新日期: 2023-09-27 18:32:50
我是一个相当缺乏经验的程序员,目前正在学习C#并尝试学习游戏设计。
我正在使用Microsoft的XNA框架来构建一个Galaga式的滚动射击游戏。 经过几次粗略的试验,我在劣质的OOP结构中挣扎,做出了一些糟糕的设计选择,我终于想出了一个体面的引擎启动。
目前,我在使碰撞检测不滞后于游戏方面遇到了问题。 我目前的引擎将所有活动游戏对象保存在一个 List 对象中,并在每个对象之间循环,检查它是否与其他对象发生冲突。 不用说,它可能会好得多。
这是我在 ObjectHandler 类中完成的碰撞检查。
public override void Update(GameTime gameTime)
{
...
//Handle collisions
foreach (GameObject obj in Objects)
{
ICollideable e = obj as ICollideable;
//Check if the object implements ICollideable
if (e != null)
{
//Check collision with each other object
foreach (GameObject obj2 in Objects)
{
//Check if the second object implements ICollideable
ICollideable e2 = obj2 as ICollideable;
//check if they are in the same sector
if (e2 != null && SameSector(e.Sector,e2.Sector))
{
//Check if the collision masks interesect
//if so call each object's collision event
if (e.Mask.Intersects(e2.Mask))
{
e.CollisionEvent(e2);
e2.CollisionEvent(e);
}
}
}
}
}
...
}
这是同扇区函数。
private bool SameSector(Point p1, Point p2)
{
if (Math.Abs(p1.X-p2.X)<=1 && Math.Abs(p1.Y-p2.Y)<=1)
return true;
else
return false;
}
这里的"掩码"是一个矩形对象,它是XNA框架的一部分。 如您所见,我实现了一种空间分区系统,其中每个对象都设置了它所在的 60x60 正方形。 但是,我不确定我是否做了任何有用的事情,因为检查两个对象是否在同一扇区(或相邻扇区(中所需的时间与检查它们是否碰撞所需的时间一样多。
我已经看到一个与此类似的问题,但它并没有完全满足我的问题。从中我确实了解到时间管理系统是有用的。 我最终会尝试实现它,但由于我对编程还相当陌生,我想在深入研究更高级的设计之前优化碰撞检查本身。
那么,我有没有办法有效地优化我当前的碰撞检查,或者我还有很长的路要走?
不需要以某种方式将每个对象与每个对象进行比较的方式实现空间分区时,空间分区才会对您有所帮助。
在空间分区格网中,您希望每个格网单元中都有某种对象成员资格列表,并且希望每个对象都知道它所在的格号。 然后,您只需要在对象与该单元格内和紧邻单元格内的所有其他对象之间进行比较(因为对象可能重叠边界(。 缺点是你现在需要保持所有这些状态的更新。
我强烈推荐《实时碰撞检测》一书,该书深入介绍了几种不同的宽相位分区方案及其相对优缺点,以及其他 CD 主题。 除了统一网格之外,还有分层网格、四叉树、扫描和修剪以及其他可能更适合您的技术(扫描和修剪可能特别有益(。