0

我正在开发一个 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 *s 与参数相交Entity *- (通过检查命中框)然后尝试dynamic_cast<T *>它们。然后返回所有匹配Entity *的 s(不是强制转换的)。可变参数模板用于检查多个相交类。

我背后的基本想法是,如果我有一个Player-class(显然代表玩家)和其他一些类,如Enemy,等,那么检查一个-object 是否与一个(或更多)碰撞Wall将是一件容易的事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 *
4

1 回答 1

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 等。你可以通过谷歌搜索找到很多代码。

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

于 2013-10-10T17:35:48.073 回答