空洞武士笔记5
碰撞管理器的简单设计
面对物理世界的所有碰撞我们都整合在一起管理所有物体的碰撞箱,方便我们统一的进行处理。
就是为了方便这些的统一管理所有碰撞箱子的碰撞发生。
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;
// 碰撞体形状可以添加其他通用功能...
};
然后我们可以依照这个逻辑衍生出不同的形状碰撞箱的类管理。