使碰撞检测更有效(C#XNA)

时间:2012-04-29 20:19:28

标签: c# .net xna collision-detection game-physics

我是一名相当缺乏经验的程序员,目前正在学习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平方。然而,我不确定我做了什么有用的东西,因为它花了很多时间检查是否两个对象位于同一扇区(或相邻扇区)中,以检查它们是否发生碰撞。

我已经看过一个与此相似的问题,但它并不能完全满足我的问题。从中我确实认为时间管理系统很有用。我将尝试最终实现这一点,但由于我还是相当新的编程,我想在深入研究更先进的设计之前优化碰撞检查。

那么,我是否有办法有效地优化当前的碰撞检查,或者是我开始时的方式?

1 个答案:

答案 0 :(得分:3)

空间分区只会帮助您实现它,而不需要您以某种方式将每个对象与每个对象进行比较。

在空间分区网格中,您希望每个网格单元格中都包含某种对象的成员资格列表,以及每个对象都要知道它所在的单元格。然后您只需要对它们进行比较。对象和该单元格内以及紧邻的单元格内的所有其他对象(因为对象可能与边界重叠)。缺点是你现在需要更新所有状态。

除了其他CD主题之外,我强烈推荐书籍Real-Time Collision Detection,其中涵盖了几个不同的广泛分区方案,以及它们的相对优势和劣势。除了统一网格,还有分层网格,四叉树,扫描和修剪以及其他可能更适合您的技术(sweep and prune可能特别有用)。