|
这里指出了一个情况,例如我们有三种物体,且都继承GameObject
- SpaceShip 飞船
- SpaceStation 空间站
- Asteroid 陨石
不同的物体会相撞,且会产生不同的结果。例如飞船和空间站相撞,飞船能进入到空间站内;飞船和陨石相撞,两者都会摧毁。
这个时候,我们需要一个方法,传入任意俩个GameObject都可以处理。
void processCollision(GameObject& object1, GameObject& object2)
书中讨论了一套方法,是一个不错的方法,但是感觉还不是很完美。目前就整理一下代码,记录下来。
#include <iostream>
#include <memory>
#include <string>
#include <map>
class GameObject {
public:
virtual ~GameObject() {} //基类里面有虚函数,派生类继承后,使用typeid().name才能取得对应的class name
};
class SpaceShip : public GameObject {};
class SpaceStation : public GameObject {};
class Asteroid : public GameObject {};
//匿名namespace
namespace {
using std::string;
using std::map;
using std::make_pair;
using std::pair;
using std::cout;
using std::endl;
void shipAsteroid(GameObject& spaceShip, GameObject& asteroid) { cout << &#34;spaceShip collide with asteroid&#34; << endl; };
void shipStation(GameObject& spaceShip, GameObject& spaceStation) { cout << &#34;spaceShip collide with spaceStation&#34; << endl; };
void asteroidStation(GameObject& asteroid, GameObject& spaceStation) { cout << &#34;asteroid collide with spaceStation&#34; << endl; };
void asteroidShip(GameObject& asteroid, GameObject& spaceShip) { shipAsteroid(spaceShip, asteroid); };
void stationShip(GameObject& spaceStation, GameObject& spaceShip) { shipStation(spaceShip, spaceStation); };
void stationAsteroid(GameObject& spaceStation, GameObject& asteroid) { asteroidStation(asteroid, spaceStation); };
}
//碰撞map
class CollisionMap {
public:
//这里使用单例
static CollisionMap* theCollisionMap() {
static CollisionMap CM;
return &CM;
};
typedef void (*HitFunctionPtr)(GameObject&, GameObject&);
//这里添加新的碰撞处理函数,成对处理
void addEntry(const string& type1, const string& type2, HitFunctionPtr collisionFunction)
{
if (collisionMap.find(std::make_pair(type1, type2)) != collisionMap.end()) return;
//成对添加
collisionMap[std::make_pair(type1, type2)] = collisionFunction;
collisionMap[std::make_pair(type2, type1)] = collisionFunction;
}
//这里移除碰撞函数
void removeEntry(const string& type1, const string& type2) {
if (collisionMap.find(std::make_pair(type1, type2)) != collisionMap.end()) return;
//成对移除
collisionMap.erase(std::make_pair(type1, type2));
collisionMap.erase(std::make_pair(type2, type1));
}
//查找有没有对应的碰撞函数
HitFunctionPtr lookup(const string& class1, const string& class2) {
HitMap::iterator it = collisionMap.find(make_pair(class1, class2));
if (it == collisionMap.end()) return 0;
return (*it).second;
}
private:
typedef map<pair<string, string>, HitFunctionPtr> HitMap;
HitMap collisionMap;
CollisionMap() { initializeCollisionMap(); };
CollisionMap(const CollisionMap&);
// 这里可以内部初始化,也可以改为一个函数,来注册一下函数
void initializeCollisionMap() {
collisionMap.clear();
addEntry(&#34;class SpaceShip&#34;, &#34;class Asteroid&#34;, &shipAsteroid);
addEntry(&#34;class SpaceShip&#34;, &#34;class SpaceStation&#34;, &shipStation);
// ...
}
};
//匿名namespace
namespace
{
//这里处理碰撞,会查找碰撞map,如果有函数就执行,没有的话就抛出异常
void processCollision(GameObject& object1, GameObject& object2) {
CollisionMap* CM = CollisionMap::theCollisionMap();
CollisionMap::HitFunctionPtr phf = CM->lookup(typeid(object1).name(), typeid(object2).name());
if (phf) phf(object1, object2);
else cout << &#34;UnkowCollision! &#34; << typeid(object1).name() << &#34; - &#34; << typeid(object2).name() << endl;
}
}
int main() {
SpaceShip spaceShip;
Asteroid asteroid;
SpaceStation spaceStation;
processCollision(spaceShip, asteroid); //spaceShip collide with asteroid
processCollision(asteroid, spaceShip); //UnkowCollision! class Asteroid - class SpaceShip
processCollision(spaceShip, spaceStation); //spaceShip collide with spaceStation
processCollision(asteroid, spaceStation); //UnkowCollision! class Asteroid - class SpaceStation
return 0;
}
<hr/>上一篇:【《More Effective C++ (35个改善编程与设计的有效方法)》 读书笔记】条款30:Proxy classes(替身类、代理类)
下一篇:【《More Effective C++ (35个改善编程与设计的有效方法)》 读书笔记】条款32:在未来时态下发展程序 |
|