我是一名相当缺乏经验的程序员,目前正在学习C#并试图学习游戏设计。
我正在使用微软的XNA框架来构建Galaga-esque Scrolling Shooter游戏。经过几次艰难的试验,我在讨论劣质的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);
}
}
}
}
}
...
}
这是SameSector功能。
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;
}
“Mask”这里是一个Rectangle对象,它是XNA框架的一部分。正如你所看到的,我已经实现了一种空间分区系统,每个对象设置了60x60平方。然而,我不确定我做了什么有用的东西,因为它花了很多时间检查是否两个对象位于同一扇区(或相邻扇区)中,以检查它们是否发生碰撞。
我已经看过一个与此相似的问题,但它并不能完全满足我的问题。从中我确实认为时间管理系统很有用。我将尝试最终实现这一点,但由于我还是相当新的编程,我想在深入研究更先进的设计之前优化碰撞检查。
那么,我是否有办法有效地优化当前的碰撞检查,或者是我开始时的方式?
答案 0 :(得分:3)
空间分区只会帮助您实现它,而不需要您以某种方式将每个对象与每个对象进行比较。
在空间分区网格中,您希望每个网格单元格中都包含某种对象的成员资格列表,以及每个对象都要知道它所在的单元格。然后您只需要对它们进行比较。对象和该单元格内以及紧邻的单元格内的所有其他对象(因为对象可能与边界重叠)。缺点是你现在需要更新所有状态。
除了其他CD主题之外,我强烈推荐书籍Real-Time Collision Detection,其中涵盖了几个不同的广泛分区方案,以及它们的相对优势和劣势。除了统一网格,还有分层网格,四叉树,扫描和修剪以及其他可能更适合您的技术(sweep and prune可能特别有用)。