在2D环境中使用dynamic_cast进行碰撞检测

时间:2013-10-10 17:10:24

标签: c++ c++11 collision-detection variadic-templates

我正在为2D游戏开发基础。我的总体设计是这样的:

class Entity:
    Every object class (like a wall, an enemy, floor etc.) derives
    from this class. Most of the functions are pure virtual. There is
    a hitbox as well.

class Scene:
    Contains pointers to Entity-objects. When an Entity-pointer is added,
    it will be given a Scene-pointer to its parent so it may access that.

场景还具有碰撞检测功能:

getIntersections<T> (Entity *)
getIntersections<T...> (Entity *)
    (both return a std::vector<Entity *>)

这基本上会使所有Entity *与参数相交 - Entity *(通过检查命中框),然后尝试dynamic_cast<T *>它们。然后返回所有匹配的Entity * s(不是已转换的)。可变参数模板用于检查多个交叉类。

我背后的基本想法是,如果我有一个Player - 类(显然代表了玩家),以及其他一些类,如EnemyWall等,它检查Player - 对象是否与其中一个(或多个)碰撞是一件容易的事:

// (inside Player::tick(); quick and dirty)
{
    if ( (this->parentScene->getIntersections<Wall>(this)).empty() )
        // player does not collide with a wall, just move.
    else
        // player does collide with a wall, do whatever.
}

但是,我有两个问题:

  1. 我的(一般)设计是否显示出需要dynamic_cast<T *>作为instanceof的替代品的缺陷(例如Java中的内容)
  2. 这是一项高效的解决方案吗?因为对于每次碰撞检查,Scene基本上遍历它包含的每个 Entity *,检查它是否与给定的Entity *发生碰撞并最终投射它以检查它是否存在来自另一个给定的类。如果

1 个答案:

答案 0 :(得分:0)

在性能部分,最好用原始类型在单独的向量中分隔实体。不仅你可以专门测试一个平面与一个球体,例如它不需要完全使用dynamic_cast( - >额外的加速)。此外,由于您已经将向量中的类型分开,因此您可以忽略虚拟函数并进行非虚拟调用,从而提供额外的性能提升; 所以你的场景看起来像这样:

class scene
{
    std::vector<PlaneEntity> m_planes;
    std::vector<CircleEntity> m_circles;
};

关于设计,在交叉原始时选择正确的算法要容易得多: 这是基于此设计的基本碰撞检查的示例:

void colide(const PlaneEntity & e)
{
    for each plane
        call plane vs plane collision
    for each circle
        call plane vs circle collision;
};
void colide(const CircleEntity & e)
{
    for each plane
        call plane vs circle collision;
    for each circle
        call circle vs circle collision;
};

所以回答你的问题:

1:使用或不使用dynamic_cast不是规则天气,众所周知,不使用它对性能更好。

2:上述设计完全没有效果。你的动态演员设计也更慢。为了改善这一点,你需要研究加速结构(这是一个很大的主题,所以我不能在这里解释所有内容)来加速碰撞检测。它们基本上减少了每个原语的冲突检查次数,从而大大提高了性能。基本结构是KD-Tree,Quad-Trees,Spacial-Hash,Grid等。你可以通过google来找到每个代码的大量代码。

希望这有帮助, Raxvan。