c++ - 状态机状态之间的通信

标签 c++ state state-machine

我在应用程序中实现状态机时遇到了一些困难。

所以我有我的状态机:

class StateMachine
{
public:
enum State { MENU, GAME };
    StateMachine();
    void Update();
    void Render();

private:
    Menu* mMenu;
    Game* mGame;
    State mState;
};

StateMachine::StateMachine()
{
    mState = MENU;
}

void StateMachine::Update()
{
    switch(mState)
    {
        case MENU:
        mMenu -> Update(); break;
        case GAME:
        mGame -> Update(); break;
    }
}
void StateMachine::Render()
{
    switch(mState)
    {
        case MENU:
        mMenu -> Render(); break;
        case GAME:
        mGame -> Render(); break;
    }
}

我的菜单和游戏类封装了更新、渲染、键盘输入处理等。

所以我的问题是,如果状态处于MENU,我如何在对象mMenu与状态机之间进行通信以告诉它进入游戏状态?我是否需要在菜单和游戏中使用一个变量来供状态机选择然后切换状态?

最佳答案

如果要更新状态机,菜单类和游戏类都需要了解状态机。

最好的方法是在 Game 和 Menu 类中保留对状态机的引用,以更新当前状态。您可以进一步将其封装在一个接口(interface)中,两个接口(interface)都实现,以使事情更加清晰。

// State.hpp
class State {
    public:
        virtual Handle() = 0;
};

// Cotext.hpp
#include "State.hpp"

class Context {
private:
    State* currentState;

public:
    void Update() {
        currentState->handle():
    }

    void setState(State* state) {
        currentState = state;
    }
};

class ContextSwitcher {
    virtual void SetContext(Context* context) = 0;
};

// Game.hpp
#include "Context.hpp"

class Game : public State, ContextSwitcher {
    Context* context_;
    State* menu_;

public:
    virtual void SetContext(Context* context) {
        context_ = context;
    }

    virtual void SetMenu(State* menu) {
        menu_ = menu;
    }

    virtual void Handle() {
        // Do update stuff
        if (shouldGoToMenu) {
            context_->setState(menu_);
        }
    }
}

// Menu.hpp
class Menu : public State, ContextSwitcher {
    Context* context_;
    State* game_;

public:
    virtual void SetContext(Context* context) {
        context_ = context;
    }

    void SetGame(State* game) {
        game_ = game;
    }

    virtual void Handle() {
        // Do update stuff
        if (shouldGoToGame) {
            context_->setState(game_);
        }
    }
}

// GameContext.hpp
#include "Context.hpp"
#include "Menu.hpp"
#include "Game.hpp"

class GameContext : public Context {
private:
    Menu menu;
    Game game;

public:
    void Init() {
        menu->SetContext(this);
        menu->SetGame(&game);
        game->SetContext(this);
        game->SetMenu(&menu);

    }
    // ...
};

关于c++ - 状态机状态之间的通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28219497/

相关文章:

algorithm - 每个算法都可以用有限状态机表示吗?

java - 状态机中的动态目标

Python C API : PyDateTime_FromTimestamp causes segmentation fault

javascript - 如何在 react 中创建更多状态? react 状态的属性数量是否固定?

c++ - IBM Rhapsody c++ 代码生成 - 为什么总是在状态图周围放置一个事件状态?

reactjs - 在构造函数中声明 React 状态,而不是在构造函数外

android - 如何销毁 PhoneStateListener 类的对象?

c++ - 在 Omnetpp 中从消息到数据包的类型转换

c++ - 如何在用户不可见的情况下每月下载并执行一个文件?

c++ - 在 iostream 中缓冲