首先是StageManager类:
class StageManager : public Singleton<StageManager>
{
friend class Singleton<StageManager>;
private:
StageManager() : _curStage(), _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() = ;
virtual void ReleaseStage(Stage* pStage) = ;
};
逻辑层需要实现该工厂,以指定创建的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;
};