7.6 进入状态和退出状态的行为
状态模式的目标就是将每个状态相关的所有的数据和行为封装到相关类里面。万里长征,我们仅仅迈出去了一步,我们还有更多路要走。
当主角更改状态的时候,我们也会切换它的贴图。现在,这段代码包含在它要切换的状态的上一个状态里面。当她从躲避状态切换到站立状态时,躲避状态将会修改它的图像:
HeroineState* DuckingState::handleInput(
Heroine& heroine, Input input)
{
if (input == RELEASE_DOWN)
{
heroine.setGraphics(IMAGE_STAND);
return new StandingState();
}
// Other code...
}
我们希望的是,每一个状态控制自己的图像。我们可以通过给每一个状态添加一个entey行为。
class StandingState : public HeroineState
{
public:
virtual void enter(Heroine& heroine)
{
heroine.setGraphics(IMAGE_STAND);
}
// Other code...
};
回到Heroine类,我们修改代码来处理状态切换的情况:
void Heroine::handleInput(Input input)
{
HeroineState* state = state_->handleInput(
*this, input);
if (state != NULL)
{
delete state_;
state_ = state;
// Call the enter action on the new state.
state_->enter(*this);
}
}
这样也可以让我们简化躲避状态的代码:
HeroineState* DuckingState::handleInput(
Heroine& heroine, Input input)
{
if (input == RELEASE_DOWN)
{
return new StandingState();
}
// Other code...
}
它所做的就是切换到站立状态,然后站立状态会自己设置图像。现在,我们的状态已经封装好了。entry动作的一个最大的好处就是它不用关心上一个状态是什么,它只需要根据自己的状态来处理图像和行为就可以了。
大部分的真实状态图里面,我们有多个状态对应同一个状态。比如,我们的女主角会在她俯冲或者跳跃之后站立在地面上。这意味着,我们可能会在每一个状态发生变化的时候重复写很多代码。但是,entry动作帮我们很好地解决了这个问题。
当然,我们也可以扩展这个功能来支持退出状态的行为。我们可以定义一个exit函数来定义一些在状态改变前的处理。
时间: 2024-09-18 21:33:23