能帮到你的话,就给个赞吧 😘
文章目录
- 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 onceenum 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);}
}