能帮到你的话,就给个赞吧 😘
文章目录
- collisionBox.h
- collisionLayer.h
- collisionManager.h
collisionBox.h
#pragma once
#include "collisionLayer.h"
#include "vector2.h"
#include <functional>
class CollisionManager;
class CollisionBox {
friend CollisionManager;
private:
//碰撞箱不能随意创建
//所有的碰撞箱都由管理器统一管理,没有注册到管理器的碰撞箱毫无意义。
CollisionBox() = default;
~CollisionBox() = default;
public:
void setEnable(bool enable);
void setLayerSrc(CollisionLayer layer);
void setLayerDst(CollisionLayer layer);
void setOnCollide(const std::function<void()>& onCollide);
void setPosition(const Vector2& position);
void setSize(const Vector2& size);
public:
const Vector2& getSize();
private:
Vector2 position;
Vector2 size;
bool enable = true; //是否开启碰撞
std::function<void()> onCollide; //处理碰撞
CollisionLayer layerSrc = None; //自身碰撞层——被撞
CollisionLayer layerDst = None; //目标碰撞层——撞别人
};
void CollisionBox::setEnable(bool enable){
this->enable = enable;
}
void CollisionBox::setLayerSrc(CollisionLayer layer){
layerSrc = layer;
}
void CollisionBox::setLayerDst(CollisionLayer layer){
layerDst = layer;
}
void CollisionBox::setOnCollide(const std::function<void()>& onCollide){
this->onCollide = onCollide;
}
void CollisionBox::setPosition(const Vector2& position){
this->position = position;
}
void CollisionBox::setSize(const Vector2& size){
this->size = size;
}
const Vector2& CollisionBox::getSize(){
return size;
}
collisionLayer.h
#pragma once
enum CollisionLayer{
None,
Player,
Enemy
};
collisionManager.h
#pragma once
#include "collisionBox.h"
#include <vector>
#include <graphics.h>
class CollisionManager {
private:
CollisionManager() = default;
~CollisionManager() = default;
public:
static CollisionManager* getInstance(); //单例
CollisionBox* createCollisionBox(); //工厂
void destroyCollisionBox(CollisionBox* collisionBox);
void processCollide(); //碰撞检测
void debugRender(); //调试渲染
private:
std::vector<CollisionBox*> collisionBoxs;
static CollisionManager* collisionManager;
};
CollisionManager* CollisionManager::getInstance(){
if (!collisionManager)
collisionManager = new CollisionManager;
return collisionManager;
}
inline CollisionBox* CollisionManager::createCollisionBox(){
collisionBoxs.push_back(new CollisionBox);
}
inline void CollisionManager::destroyCollisionBox(CollisionBox* collisionBox){
//从collisionBoxs中移除所有与collisionBox相等的元素
collisionBoxs.erase(remove(collisionBoxs.begin(), collisionBoxs.end(), collisionBox), collisionBoxs.end());
delete collisionBox;
}
inline void CollisionManager::processCollide(){
//处理 collisionBox 与 其他碰撞箱的碰撞
for (auto& collisionBox : collisionBoxs) {
if (!collisionBox->enable || collisionBox->layerDst == None)
continue;
for (auto& collisionBoxDst : collisionBoxs) {
if (collisionBox == collisionBoxDst
|| !collisionBoxDst->enable
|| collisionBox->layerDst != collisionBoxDst->layerSrc)
continue;
auto xRightCollisionBox = collisionBox->position.x + collisionBox->size.x;
auto xRightCollisionBoxDst = collisionBoxDst->position.x + collisionBoxDst->size.x;
auto collisionX = max(xRightCollisionBox, xRightCollisionBoxDst)
- min(collisionBox->position.x, collisionBoxDst->position.x)
<= collisionBox->size.x + collisionBoxDst->size.x;
auto yDownCollisionBox = collisionBox->position.y + collisionBox->size.y;
auto yDownCollisionBoxDst = collisionBoxDst->position.y + collisionBoxDst->size.y;
auto collisionY = max(yDownCollisionBox, yDownCollisionBoxDst)
- min(collisionBox->position.y, collisionBoxDst->position.y)
<= collisionBox->size.y + collisionBoxDst->size.y;
if (collisionX && collisionY && collisionBox->onCollide)
collisionBox->onCollide();
}
}
}
inline void CollisionManager::debugRender(){
for (auto& collisionBox : collisionBoxs) {
setlinecolor(collisionBox->enable ? RGB(295, 155, 155) : RGB(115, 115, 175));
//rectangle以position为中心
rectangle(
collisionBox->position.x - collisionBox->size.x / 2,
collisionBox->position.y - collisionBox->size.y / 2,
collisionBox->position.x + collisionBox->size.x / 2,
collisionBox->position.y + collisionBox->size.y / 2
);
}
}