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

Using dynamic_cast for collision detection in a 2D environment

本文关键字:cast 碰撞检测 dynamic 2D 环境      更新时间:2023-10-16

我正在为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 *(不是强制转换的(。可变参数模板用于检查多个相交类。

我的基本想法是,如果我有一个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 *冲突,最后强制转换它以检查它是否派生自另一个给定类。如果这不符合性能,那么在我的设计中进行哪些更改才能使其具有性能?

在性能部分,最好按基元类型将实体分隔在单独的向量中。您不仅可以专门测试平面与球体,例如,它消除了完全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树,四叉树,空间哈希,网格等。你可以通过谷歌搜索找到每个代码的大量代码。

希望这有帮助,拉克斯万。