我正在为我的游戏设置状态系统。
class State
{
protected:
enum State_
{
STATE_INTRO,
STATE_GAME,
STATE_PAUSE,
STATE_CUTSCENE,
};
public:
State();
virtual void run(State_) = 0;
virtual ~State(); // virtual destructor cus we will be inheriting this class
};
然后我继承了代表每个州的类
class IntroState : public State
{
public:
void run(State_ STATE);
};
我希望run
函数根据游戏所处的状态而具有不同的功能,这是一种不好的做法吗?
void IntroState::run(State_ STATE)
{
if (STATE == STATE_INTRO)
{
// load the intro
}
}
我不确定其他方法,谢谢(记住,我只是在学习状态,所以我可能会完全不在这里)
答案 0 :(得分:1)
我认为您不需要多态,因为您的应用程序中只有一个State
类(如果我错了,请纠正我)。
您正在运行的功能如下所示:
void run(State_ state)
{
switch (state)
{
case STATE_INTRO:
doIntro();
case STATE_BLAH:
doBlah();
// fill all you states...
}
}
void doIntro()
{
// do something for the intro
}
void doBlah()
{
// do something for blah
}
现在,如果您真的想花哨并删除switch
语句:
class State
{
private:
void doA() {}
void doB() {}
enum State_
{
A = 0,
B,
END_
};
std::function<void(void)> functions[END_];
public:
State()
{
functions[A] = std::bind(&State::doA, this);
functions[B] = std::bind(&State::doB, this);
}
void run(State_ state)
{
functions[state]();
}
};
答案 1 :(得分:1)
为了进一步说明我的观点,这是一种可能的方法(我们对此有所改进):
class Game {
//... Initialize all State-derived classes in constructor and put them in states (not shown)
vector<unique_ptr>> states;
State_ currentState {STATE_INTRO};
State_ nextState {STATE_INTRO};
public:
void setNextState(State_ state ) {nextState = state;}
void Play() {
for(;;) { //endless loop
if (!states[currentState]->run()) return;//stopping when run returns false
currentState = nextState;
}
}
};
run
可能看起来像这样:
class IntroState : public State {
//...
void run(Game& game) {
// do stuff
game.setNextState(STATE_GAME);
return true;
}
};
当然,您需要弄清楚包含顺序,并且需要在Game
中向前声明State.hpp
(此处显示的代码仅显示中心思想)。另外,run
和Play
的实现当然应该在单独的.cpp文件中(此处没有这样做,因此该示例不会太长)