LOADING

加载过慢请开启缓存 浏览器默认开启

碰撞管理器的简单设计

空洞武士笔记5

碰撞管理器的简单设计

面对物理世界的所有碰撞我们都整合在一起管理所有物体的碰撞箱,方便我们统一的进行处理。

image-20240923203406205

就是为了方便这些的统一管理所有碰撞箱子的碰撞发生。

1.层级

这个我们在前面也大体的讲过了用位运算实现层级,最后作为成员组合在碰撞箱子中作为成员变量实现,所以不再提了。

2.碰撞箱子的设计

rivate:
    Vector2 size;
    Vector2 position;
    bool enabled = true;
    std::function<void()> on_collide;
    CollisionLayer layer_src = CollisionLayer::None;
    CollisionLayer layer_dst = CollisionLayer::None;

可以看到这些成员变量

  • 因为暂且都用矩形的设计,所以我们用俩个变量代替。size尺寸,和position矩形中心位置。
  • enable表明当前的碰撞箱子是否启用。
  • 然后就是碰撞发生的回调函数。
  • 然后就是俩个层级,自身所处的层级,和目标碰撞层级。
public:
    void set_enabled(bool flag)
    {
        enabled = flag;
    }
    void set_layer_src(CollisionLayer layer)
    {
        layer_src = layer;
    }
    void set_layer_dst(CollisionLayer layer)
    {
        layer_dst = layer;
    }
    void set_on_collide(std::function<void()> on_collide)
    {
        this->on_collide = on_collide;
    }
    void set_size(const Vector2& size)
    {
        this->size = size;
    }
    const Vector2& get_size()const
    {
        return size;
    }
    void set_position(const Vector2& position)
    {
        this->position = position;
    }

对成员对象暴露的接口就是一些基本碰撞箱子的属性设置,例如位置,碰撞回调函数,是否启用之类的

friend class CollisionManager;
private:
    CollisionBox() = default;
    ~CollisionBox() = default;

因为我们使用工厂模式,创造和销毁的细节全部存放在碰撞管理器,所以友元声明表明管理器可以接触到构造函数创建碰撞箱子,而玩家需要调用碰撞管理器的函数来创建。

3.碰撞管理器的实现

class CollisionManager
{
public:
    static CollisionManager* instance();


    CollisionBox* create_collision_box();
    void destroy_collision_box(CollisionBox* collision_box);

    void process_collide();
    void on_debug_render();


private:
    static CollisionManager* manager;
    std::vector<CollisionBox*> collision_box_list;
private:
    CollisionManager();
    ~CollisionManager();

private:

};

当前的设计也非常简单,单例模式管理器。

  • 创建碰撞箱
  • 销毁碰撞箱子
  • 处理碰撞逻辑
  • 碰撞箱子绘制
  • 碰撞箱子使用列表存放

就这样,就实现了简单的碰撞箱管理器。

4.可实现的优化

1.四叉树的空间管理优化

前面简单介绍了一下四叉树的实现,其实就是重新创建一个类代替上面的vector取管理碰撞箱子。

三维的我们有八叉树的空间管理方法等等。

2.碰撞箱子形状的优化

我们显然让玩家选择一些基本的碰撞箱子类型。

我们可以设计一个碰撞箱子的基类,然后去拓展一些类。

class Collider {
public:
    virtual ~Collider() = default;

    // 碰撞检测接口,与其他 Collider 进行碰撞检测
    virtual bool CheckCollision(const Collider& other) const = 0;

    // 获取碰撞体的包围盒 (Bounding Box)
    virtual Rect GetBoundingBox() const = 0;

    // 获取碰撞体的位置
    virtual Vector2D GetPosition() const = 0;

    // 更新碰撞体的位置
    virtual void SetPosition(const Vector2D& newPosition) = 0;

    // 碰撞体形状可以添加其他通用功能...
};

然后我们可以依照这个逻辑衍生出不同的形状碰撞箱的类管理。