首先是StageManager类:
class StageManager : public Singleton<StageManager> { friend class Singleton<StageManager>; private: StageManager() : _curStage(0), _pStageCreator(nullptr) {} ~StageManager(); public: bool InitStageManager(); Stage* SwitchStage(uint32 stageID, bool bDestroyOld); void SetStageCreator(StageCreator* pCreator) { _pStageCreator = pCreator; } Stage* GetStageByID(uint32 stageID); Stage* GetCurStage() { return GetStageByID(_curStage); } private: std::map<uint32, Stage*> _stages; uint32 _curStage; StageCreator* _pStageCreator; };
这个类的功能是:
1.管理Stage的生存期
2.作为单件,提供访问Stage的入口
3.接收并处理相关事件
它主要的操作是SwitchStage,首先判断Stage是否存在,如果不存在,创建,加载并显示它,并且根据bDestroyOld参数,决定是否释放前一个Stage的资源。
舞台类Stage如下:
class Stage { public: Stage() : _bLoaded(false) {} virtual ~Stage(); public: /// 向舞台加入对象 virtual bool Add2Stage(Object* pObj); /// 加载舞台 virtual void LoadStage(uint32 stageID); /// 心跳 virtual void StageTick(); public: bool IsLoaded() { return _bLoaded; } protected: bool _bLoaded; std::vector<Object*> _objs; };
这个类的功能是:
1.加载舞台对象,管理对象生存期。
在游戏初始化的时候,会读入一个类似下面的资源文件:
<Stages> <Stage id = "1", file="stage1.xml" /> <Stage id = "2", file="stage2.xml" />
……
</Stages>
stageN.xml的结构也很简单:
<Stage> <Object type="npc" file="object1.xml"> <Object type="npc" file="object2.xml"> ……
</Stage>
StageManager和Stage根据这两个文件加载舞台和舞台上的对象。
2.以适当的方式加载和显示地图。目前比较常见的地图加载方式有tilemap,整图加载,整图切片加载等,这些处理都被封装在Stage内部。随着项目需求的变化,会逐渐增加StageTileMap,StageWhole等派生类,服务器和客户端使用的Stage类也可能有所不同。但是StageManager并不知道应该创建哪一类Stage,为此需要增加一个抽象工厂:
class StageCreator { public: virtual ~StageCreator() {} virtual Stage* CreateStage() = 0; virtual void ReleaseStage(Stage* pStage) = 0; };
逻辑层需要实现该工厂,以指定创建的Stage类别。
下面是一个简单的,基于cocos2d,整图加载,以指定角色为中心移动的Stage:
class StageView : public Stage { public: StageView() : _pCenter(nullptr), _pScene(nullptr), _pLayer(nullptr) {} public: virtual bool InitStage(); virtual bool Add2Stage(Object* pObj); virtual void LoadStage(uint32 stageID); virtual void StageTick(); public: /// 以pObj为中心显示舞台 void CenterStage(Object* pObj); /// 指定舞台的中心对象 void SetCenter(Object* pObj) { _pCenter = pObj; } public: cocos2d::CCScene* Scene() { return _pScene; } protected: Object* _pCenter; cocos2d::CCScene* _pScene; StageLayer* _pLayer; };