我正在写一个游戏,我想以一种干净的,面向对象的方式来模拟它的不同状态(Game Maker类比将是帧,我猜).以前,我是通过以下方式完成的:
class Game
{
enum AppStates
{
APP_STARTING,
APP_TITLE,
APP_NEWGAME,
APP_NEWLEVEL,
APP_PLAYING,
APP_PAUSED,
APP_ENDED
};
typedef AppState(Game::*StateFn)();
typedef std::vector<StateFn> StateFnArray;
void Run()
{
// StateFn's to be registered here
AppState lastState(APP_STARTING);
while(lastState != APP_ENDED)
{
lastState = GetCycle_(lastState);
}
// cleanup
}
protected:
// define StateFn's here
AppState GetCycle_(AppState a)
{
// pick StateFn based on passed variable, call it and return its result.
}
StateFnArray states_;
};
Run Code Online (Sandbox Code Playgroud)
这对于一个较小的项目来说几乎无法管理.状态所使用的所有变量都被转储到Game类中,但是我希望将面向对象保持为最大值,只显示由多个状态共享的变量.我还希望能够在切换到新状态时初始化,而不是必须在刚完成的状态下进行(因为它可能有多个结果 - APP_PLAYING可以切换到APP_PAUSED,APP_GAMEOVER,APP_NEWLEVEL等).
我想到了这样的事情(小心!模糊的东西!):
struct AppState
{
enum { LAST_STATE = -1; }
typedef int StateID;
typedef std::vector<AppState*> StateArray;
static bool Add(AppState *state, StateID desiredID);
// return false if desiredID is an id already assigned to
static void Execute(StateID state)
{
while(id != LAST_STATE)
{
// bounds check etc.
states_[id]->Execute();
}
}
AppState() {};
virtual ~AppState() {};
virtual StateID Execute() =0; // return the ID for the next state to be executed
protected:
static StageArray stages_;
};
Run Code Online (Sandbox Code Playgroud)
这里的问题是类和实例级别混乱(静态与虚拟).状态需要从AppState继承,但是 - 我怎么想 - 它们中的大多数都是具有全静态成员的类,或者,至少我不需要一个类中的多个实例(TitleState,LevelIntroState,PlayingState) ,GameOverState,EndSequenceState,EditorState ... - 暂停将不再是一个状态,而不是在有意义的状态下处理.
怎样才能优雅高效地完成?
Jes*_*der 10
以下文章提供了一种管理游戏状态的简单方法:
http://gamedevgeek.com/tutorials/managing-game-states-in-c/
基本上,你保持一堆游戏状态,然后运行顶级状态.你是对的,许多州只有一个实例,但这不是一个真正的问题.实际上,你所谈论的许多州可能有多个实例.例如:
push TitleState
push MenuState
push LevelIntroState
change_to PlayingState
change_to GameOverState
pop (back to MenuState)
Run Code Online (Sandbox Code Playgroud)
...你可以从一个新的实例开始LevelIntroState
,依此类推.
归档时间: |
|
查看次数: |
2437 次 |
最近记录: |