四、自行仿真虚函数表格(使用非成员函数的碰撞处理函数)
//GameObject.h #ifndef GAMEOBJECT_H #define GAMEOBJECT_H class GameObject{ //抽象基类 public: virtual ~GameObject() = 0; }; class SpaceShip : public GameObject{ //宇宙飞船类 public: virtual ~SpaceShip(); }; class SpaceStation : public GameObject{ //太空站类 public: virtual ~SpaceStation(); }; class Asteroid : public GameObject{ //小行星类 public: virtual ~Asteroid(); }; class UnkonwnCollision{//异常类 public: UnkonwnCollision(GameObject& whatWeHit1, GameObject& whatWeHit2); }; #endif //GameObject.cpp #include"GameObject.h" #include<iostream> GameObject::~GameObject(){} SpaceShip::~SpaceShip(){} SpaceStation:: ~SpaceStation(){} Asteroid::~Asteroid(){} UnkonwnCollision::UnkonwnCollision(GameObject& whatWeHit1, GameObject& whatWeHit2){ std::cout << "异常类" << std::endl; } //collision.h #ifndef COLLISION_H #define COLLISION_H #include "GameObject.h" #include<string> #include<map> #include<iostream> namespace{ //主要的碰撞处理函数 void shipStation(GameObject& spaceShip, GameObject& spaceStation){ std::cout << "SpaceShip<=>SpaceStation" << std::endl; } void shipAsteroid(GameObject& spaceShip, GameObject& asteroid){ std::cout << "SpaceShip<=>Asteroid" << std::endl; } void stationAsteroid(GameObject& spaceStation, GameObject& asteroid){ std::cout << "SpaceStation<=>Asteroid" << std::endl; } void shipShip(GameObject& spaceShip1, GameObject& spaceShip2){ std::cout << "SpaceShip<=>SpaceShip" << std::endl; } void stationStation(GameObject& spaceStation1, GameObject& spaceStation2){ std::cout << "SpaceStation<=>SpaceStation" << std::endl; } void asteroidAsteroid(GameObject& asteroid1, GameObject& asteroid2){ std::cout << "Asteroid<=>Asteroid" << std::endl; } //对称版本 void stationShip(GameObject& spaceStation, GameObject& spaceShip){ shipStation(spaceShip, spaceStation); } void asteroidShip(GameObject& asteroid, GameObject& spaceShip){ shipAsteroid(spaceShip, asteroid); } void asteroidStation(GameObject& asteroid, GameObject& spaceStation){ stationAsteroid(spaceStation, asteroid); } typedef void(*HitFunctionPtr)(GameObject&, GameObject&); //指向碰撞函数的函数指针 //函数表的类型:每项关联了碰撞函数两个参数的动态类型名和碰撞函数本身 typedef std::map<std::pair<std::string,std::string>, HitFunctionPtr> HitMap; std::pair<std::string, std::string> makeStringPair(const char* s1,const char* s2); HitMap* initializeCollisionMap(); ////建立函数表 //在函数表中查找需要的碰撞函数 HitFunctionPtr lookup(const std::string& class1, const std::string& class2); } void processCollision(GameObject& object1, GameObject& object2){ //根据参数的动态类型查找相应碰撞函数 HitFunctionPtr phf = lookup(typeid(object1).name(), typeid(object2).name()); if (phf) phf(object1, object2); //调用找到的碰撞处理函数来进行碰撞处理 else throw UnkonwnCollision(object1, object2); //没有找到则抛出异常 } namespace{ std::pair<std::string, std::string> makeStringPair(const char* s1, const char* s2){ return std::pair<std::string, std::string>(s1, s2); } } namespace{ HitMap* initializeCollisionMap(){ //创建并初始化虚函数表 HitMap *phm = new HitMap; //创建函数表 //初始化函数表 (*phm)[makeStringPair(typeid(SpaceShip).name(), typeid(SpaceStation).name())] = &shipStation; (*phm)[makeStringPair(typeid(SpaceShip).name(), typeid(Asteroid).name())] = &shipAsteroid; (*phm)[makeStringPair(typeid(SpaceShip).name(), typeid(SpaceShip).name())] = &shipAsteroid; (*phm)[makeStringPair(typeid(SpaceStation).name(), typeid(Asteroid).name())] = &shipAsteroid; (*phm)[makeStringPair(typeid(SpaceStation).name(), typeid(SpaceShip).name())] = &shipStation; (*phm)[makeStringPair(typeid(SpaceStation).name(), typeid(SpaceStation).name())] = &shipAsteroid; (*phm)[makeStringPair(typeid(Asteroid).name(), typeid(SpaceShip).name())] = &shipAsteroid; (*phm)[makeStringPair(typeid(Asteroid).name(), typeid(SpaceStation).name())] = &asteroidStation; (*phm)[makeStringPair(typeid(Asteroid).name(), typeid(Asteroid).name())] = &asteroidAsteroid; return phm; } } namespace{ //根据参数类型名在函数表中查找需要的碰撞函数 HitFunctionPtr lookup(std::string const& class1, std::string const& class2){ //用智能指针指向返回的函数表,为静态,表示只能有一个函数表 static std::auto_ptr<HitMap> collisionMap(initializeCollisionMap()); HitMap::iterator mapEntry = collisionMap->find(make_pair(class1, class2)); if (mapEntry == collisionMap->end()) return 0; //没找到,则返回空指针 return (*mapEntry).second; //找到则返回关联的碰撞函数 } } #endif //main.cpp #include"Collision.h" using namespace std; int main(){ SpaceShip sp; SpaceStation ss; Asteroid ad; processCollision(sp, ss); processCollision(sp, ad); processCollision(sp, sp); cout << "-----------" << endl; processCollision(ss, sp); processCollision(ss, ad); processCollision(ss, ss); cout << "-----------" << endl; processCollision(ad, sp); processCollision(ad, ss); processCollision(ad, ad); system("pause"); return 0; }
五、自行仿真虚函数表格(使用非成员函数的碰撞处理函数)
//GameObject.h #ifndef GAMEOBJECT_H #define GAMEOBJECT_H class GameObject{ //抽象基类 public: virtual ~GameObject() = 0; }; class SpaceShip : public GameObject{ //宇宙飞船类 public: virtual ~SpaceShip(); }; class SpaceStation : public GameObject{ //太空站类 public: virtual ~SpaceStation(); }; class Asteroid : public GameObject{ //小行星类 public: virtual ~Asteroid(); }; class UnkonwnCollision{//异常类 public: UnkonwnCollision(GameObject& whatWeHit1, GameObject& whatWeHit2); }; #endif //GameObject.cpp #include"GameObject.h" #include<iostream> GameObject::~GameObject(){} SpaceShip::~SpaceShip(){} SpaceStation:: ~SpaceStation(){} Asteroid::~Asteroid(){} UnkonwnCollision::UnkonwnCollision(GameObject& whatWeHit1, GameObject& whatWeHit2){ std::cout << "异常类" << std::endl; } //collision.h #ifndef COLLISION_H #define COLLISION_H #include "GameObject.h" #include<string> #include<map> #include<iostream> //主要的碰撞处理函数 void shipStation(GameObject& spaceShip, GameObject& spaceStation){ std::cout << "SpaceShip<=>SpaceStation" << std::endl; } void shipAsteroid(GameObject& spaceShip, GameObject& asteroid){ std::cout << "SpaceShip<=>Asteroid" << std::endl; } void stationAsteroid(GameObject& spaceStation, GameObject& asteroid){ std::cout << "SpaceStation<=>Asteroid" << std::endl; } void shipShip(GameObject& spaceShip1, GameObject& spaceShip2){ std::cout << "SpaceShip<=>SpaceShip" << std::endl; } void stationStation(GameObject& spaceStation1, GameObject& spaceStation2){ std::cout << "SpaceStation<=>SpaceStation" << std::endl; } void asteroidAsteroid(GameObject& asteroid1, GameObject& asteroid2){ std::cout << "Asteroid<=>Asteroid" << std::endl; } //对称版本 void stationShip(GameObject& spaceStation, GameObject& spaceShip){ shipStation(spaceShip, spaceStation); } void asteroidShip(GameObject& asteroid, GameObject& spaceShip){ shipAsteroid(spaceShip, asteroid); } void asteroidStation(GameObject& asteroid, GameObject& spaceStation){ stationAsteroid(spaceStation, asteroid); } #endif //CollisionMap.h #ifndef COLLISIONMAP_H #define COLLISIONMAP_H #include "GameObject.h" #include <string> #include <memory> #include <map> class CollisionMap{ //碰撞函数映射表 public: typedef void(*HitFunctionPtr)(GameObject&, GameObject&); //指向碰撞函数的函数指针 //函数表的类型:每项关联了碰撞函数两个参数的动态类型名和碰撞函数本身 typedef std::map<std::pair<std::string, std::string>, HitFunctionPtr> HitMap; //根据参数类型名称向映射表中加入一个碰撞函数 void addEntry(const std::string& type1, const std::string& type2, HitFunctionPtr collisionFunction, bool symmetric = true); //根据参数类型名称从映射表中删除一个碰撞函数 void removeEntry(const std::string& type1, const std::string& type2); //根据参数类型名称在函数映射表中查找需要的碰撞函数 HitFunctionPtr lookup(const std::string& type1, const std::string& type2); static CollisionMap& theCollisionMap();//返回唯一的一个碰撞函数映射表 private: std::auto_ptr<HitMap> collisionMap; //函数映射表,用智能指针存储 //构造函数声明为私有,以避免创建多个碰撞函数映射表 CollisionMap(); CollisionMap(const CollisionMap&); }; CollisionMap::CollisionMap() : collisionMap(new HitMap){} //根据参数类型名称向映射表中加入一个碰撞函数 void CollisionMap::addEntry(const std::string& type1, const std::string& type2, HitFunctionPtr collisionFunction, bool symmetric){ if (lookup(type1, type2) == 0) //映射表中没找到时插入相应条目 collisionMap->insert(make_pair(make_pair(type1, type2), collisionFunction)); } //根据参数类型名称从映射表中删除一个碰撞函数 void CollisionMap::removeEntry(const std::string& type1, const std::string& type2){ if (lookup(type1, type2) != 0) //若找到,则删除该条目 collisionMap->erase(make_pair(type1, type2)); } //根据参数类型名称在函数映射表中查找需要的碰撞函数 CollisionMap::HitFunctionPtr CollisionMap::lookup(const std::string& type1, const std::string& type2){ HitMap::iterator mapEntry = collisionMap->find(make_pair(type1, type2)); if (mapEntry == collisionMap->end()) return 0; //没找到,则返回空指针 return (*mapEntry).second; //找到则返回关联的碰撞函数 } //返回唯一的一个碰撞函数映射表 CollisionMap& CollisionMap::theCollisionMap(){ static CollisionMap cm; return cm; } void processCollision(GameObject& object1, GameObject& object2){ //根据参数的动态类型查找相应碰撞函数 CollisionMap::HitFunctionPtr phf = CollisionMap::theCollisionMap().lookup(typeid(object1).name(), typeid(object2).name()); if (phf) phf(object1, object2); //调用找到的碰撞处理函数来进行碰撞处理 else throw UnkonwnCollision(object1, object2); //没有找到则抛出异常 } #endif //RegisterCollisionFunction.h #ifndef REGISTERCOLLISONFUNCTION_H #define REGISTERCOLLISONFUNCTION_H #include"CollisionMap.h" #include<string> class RegisterCollisionFunction{ public: RegisterCollisionFunction(const std::string& type1, const std::string& type2, CollisionMap::HitFunctionPtr collisionFunction, bool sysmetric = true){ CollisionMap::theCollisionMap().addEntry(type1, type2, collisionFunction, sysmetric); } }; #endif //main.cpp #include"Collision.h" #include"RegisterCollisionFunction.h" using namespace std; RegisterCollisionFunction cf1("class SpaceShip", "class SpaceShip", &shipShip); RegisterCollisionFunction cf2("class SpaceShip", "class SpaceStation", &shipStation); RegisterCollisionFunction cf3("class SpaceShip", "class Asteroid", &shipAsteroid); RegisterCollisionFunction cf4("class SpaceStation", "class SpaceStation", &stationStation); RegisterCollisionFunction cf5("class SpaceStation", "class SpaceShip", &stationShip); RegisterCollisionFunction cf6("class SpaceStation", "class Asteroid", &stationAsteroid); RegisterCollisionFunction cf7("class Asteroid", "class Asteroid", &asteroidAsteroid); RegisterCollisionFunction cf8("class Asteroid", "class SpaceShip", &asteroidShip); RegisterCollisionFunction cf9("class Asteroid", "class SpaceStation", &asteroidStation); int main(){ SpaceShip sp; SpaceStation ss; Asteroid ad; processCollision(sp, ss); processCollision(sp, ad); processCollision(sp, sp); cout << "-----------" << endl; processCollision(ss, sp); processCollision(ss, ad); processCollision(ss, ss); cout << "-----------" << endl; processCollision(ad, sp); processCollision(ad, ss); processCollision(ad, ad); system("pause"); return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。