Monado引擎开发:Monado角色动画与状态机_(4).状态机基础理论

状态机基础理论

1. 状态机的概念

状态机(State Machine)是一种表示有限个状态以及在这些状态之间的转移和动作的数学模型。在计算机科学中,状态机被广泛应用于各种场景,包括软件开发、硬件设计、网络协议、编译器设计等。在虚拟现实游戏开发中,状态机特别适用于管理角色的行为和动画,因为它可以清晰地表示角色在不同状态下的行为和状态之间的转换。

1.1 有限状态机(Finite State Machine, FSM)

有限状态机是最常见的一种状态机,它由一组有限的状态、初始状态、输入事件、状态转移和输出动作组成。每个状态都有一个唯一的标识符,状态之间的转移由输入事件触发,转移过程中可以执行一些动作。

1.2 状态机的组成部分

  1. 状态(State):角色在某一时刻的行为或条件。

  2. 初始状态(Initial State):角色开始时的状态。

  3. 输入事件(Input Event):触发状态转移的条件。

  4. 状态转移(State Transition):从一个状态到另一个状态的转换。

  5. 输出动作(Output Action):在状态转移过程中或在状态中执行的动作。

1.3 状态机的优势

  • 清晰性:状态机可以清晰地表示角色的行为和状态之间的关系。

  • 可维护性:通过状态和转移的分离,代码更加模块化,易于维护和扩展。

  • 可读性:状态机的图形化表示使得代码的逻辑更加直观,易于理解。

2. 状态机的类型

2.1 确定性有限状态机(Deterministic Finite State Machine, DFSM)

确定性有限状态机在每个状态和输入事件的组合下,只会有一个确定的转移。这种状态机适用于简单的、确定性的行为管理。

2.2 非确定性有限状态机(Non-Deterministic Finite State Machine, NDFSM)

非确定性有限状态机在某些情况下,可能会有多个可能的转移。这种状态机适用于需要处理不确定性的场景,例如随机事件的处理。

2.3 层次状态机(Hierarchical State Machine, HSM)

层次状态机是一种更复杂的状态机,它可以将状态嵌套在其他状态中,形成一个状态树。这种状态机适用于管理多层复杂的行为,例如角色可以有多个子状态,每个子状态又有自己的行为和转移。

2.4 历史状态机(History State Machine)

历史状态机可以在返回到某个父状态时,记住上次离开时的子状态。这种状态机适用于需要恢复之前状态的场景,例如角色在战斗中被打断后,需要恢复到之前的战斗状态。

3. 状态机的应用场景

在虚拟现实游戏中,状态机可以用于多种场景,包括但不限于:

  • 角色动画管理:根据角色的状态(如行走、跑步、攻击等)播放相应的动画。

  • AI行为控制:管理非玩家角色(NPC)的行为,例如巡逻、攻击、逃跑等。

  • 游戏状态管理:管理游戏的整体状态,例如菜单、游戏进行中、游戏结束等。

  • 用户界面管理:管理用户界面的各个状态,例如按钮的点击状态、菜单的显示状态等。

4. 状态机的实现方式

4.1 使用状态图

状态图是一种图形化的表示状态机的方式,可以通过绘制状态图来直观地表示状态、转移和动作。状态图通常由状态节点、转移边和动作标签组成。

4.2 使用状态表

状态表是一种表格化的表示状态机的方式,通常用于简单的状态机。状态表包含状态、输入事件和转移状态的对应关系。

4.3 使用代码实现

在实际开发中,状态机通常通过代码来实现。可以通过类和对象来表示状态和转移,使用条件语句来处理输入事件。

4.3.1 状态类的设计

在Monado引擎中,状态类通常包含以下几个部分:

  • 状态标识:用于区分不同的状态。

  • 进入状态:当角色进入该状态时执行的动作。

  • 更新状态:在角色处于该状态时每帧执行的动作。

  • 退出状态:当角色离开该状态时执行的动作。

  • 状态转移:根据输入事件触发的状态转移。


class State {

public:

    virtual void Enter() = 0; // 进入状态时执行的动作

    virtual void Update(float deltaTime) = 0; // 每帧更新时执行的动作

    virtual void Exit() = 0; // 退出状态时执行的动作

    virtual State* HandleInput(Input input) = 0; // 处理输入事件并返回下一个状态

};



class IdleState : public State {

public:

    void Enter() override {

        // 角色进入空闲状态时的动作

        std::cout << "Entering Idle State" << std::endl;

    }



    void Update(float deltaTime) override {

        // 空闲状态下的每帧更新

        std::cout << "Idle State Update" << std::endl;

    }



    void Exit() override {

        // 角色离开空闲状态时的动作

        std::cout << "Exiting Idle State" << std::endl;

    }



    State* HandleInput(Input input) override {

        if (input == Input::MOVE) {

            return new MoveState(); // 返回移动状态

        }

        return this; // 保持当前状态

    }

};



class MoveState : public State {

public:

    void Enter() override {

        // 角色进入移动状态时的动作

        std::cout << "Entering Move State" << std::endl;

    }



    void Update(float deltaTime) override {

        // 移动状态下的每帧更新

        std::cout << "Move State Update" << std::endl;

    }



    void Exit() override {

        // 角色离开移动状态时的动作

        std::cout << "Exiting Move State" << std::endl;

    }



    State* HandleInput(Input input) override {

        if (input == Input::STOP) {

            return new IdleState(); // 返回空闲状态

        }

        return this; // 保持当前状态

    }

};

4.4 状态机类的设计

状态机类负责管理状态的转换和执行状态的动作。通常包含以下几个部分:

  • 当前状态:当前角色所处的状态。

  • 状态转移:根据输入事件触发状态的转换。

  • 状态管理:管理状态的进入、更新和退出。


class StateMachine {

private:

    State* currentState; // 当前状态

    State* globalState; // 全局状态



public:

    StateMachine(State* initialState) : currentState(initialState), globalState(nullptr) {}



    void SetGlobalState(State* state) {

        globalState = state;

    }



    void Update(float deltaTime) {

        if (globalState != nullptr) {

            globalState->Update(deltaTime);

        }

        if (currentState != nullptr) {

            currentState->Update(deltaTime);

        }

    }



    void HandleInput(Input input) {

        State* nextState = currentState->HandleInput(input);

        if (nextState != currentState) {

            Transition(nextState);

        }

    }



    void Transition(State* newState) {

        if (currentState != nullptr) {

            currentState->Exit();

        }

        currentState = newState;

        if (currentState != nullptr) {

            currentState->Enter();

        }

    }

};

5. 状态机的优化

5.1 状态复用

通过将相似的状态抽象成一个基类,可以减少代码重复,提高代码的复用性。


class BaseMoveState : public State {

public:

    void Enter() override {

        std::cout << "Entering Base Move State" << std::endl;

    }



    void Update(float deltaTime) override {

        std::cout << "Base Move State Update" << std::endl;

    }



    void Exit() override {

        std::cout << "Exiting Base Move State" << std::endl;

    }

};



class WalkState : public BaseMoveState {

public:

    State* HandleInput(Input input) override {

        if (input == Input::RUN) {

            return new RunState(); // 返回跑步状态

        }

        return this; // 保持当前状态

    }

};



class RunState : public BaseMoveState {

public:

    State* HandleInput(Input input) override {

        if (input == Input::WALK) {

            return new WalkState(); // 返回步行状态

        }

        return this; // 保持当前状态

    }

};

5.2 状态转移的优化

通过使用状态转移表,可以减少条件语句的嵌套,提高代码的可读性和执行效率。


class StateMachine {

private:

    State* currentState; // 当前状态

    State* globalState; // 全局状态

    std::unordered_map<std::pair<State*, Input>, State*> transitionTable; // 状态转移表



public:

    StateMachine(State* initialState) : currentState(initialState), globalState(nullptr) {}



    void SetGlobalState(State* state) {

        globalState = state;

    }



    void AddTransition(State* fromState, Input input, State* toState) {

        transitionTable[{fromState, input}] = toState;

    }



    void Update(float deltaTime) {

        if (globalState != nullptr) {

            globalState->Update(deltaTime);

        }

        if (currentState != nullptr) {

            currentState->Update(deltaTime);

        }

    }



    void HandleInput(Input input) {

        auto it = transitionTable.find({currentState, input});

        if (it != transitionTable.end()) {

            State* nextState = it->second;

            Transition(nextState);

        }

    }



    void Transition(State* newState) {

        if (currentState != nullptr) {

            currentState->Exit();

        }

        currentState = newState;

        if (currentState != nullptr) {

            currentState->Enter();

        }

    }

};

5.3 状态机的调试

为了更好地调试状态机,可以在状态转换和动作执行时输出日志信息,或者使用可视化工具来查看状态机的运行情况。


class State {

public:

    virtual void Enter() {

        std::cout << "Entering " << this->GetName() << std::endl;

    }



    virtual void Update(float deltaTime) {

        std::cout << this->GetName() << " Update" << std::endl;

    }



    virtual void Exit() {

        std::cout << "Exiting " << this->GetName() << std::endl;

    }



    virtual State* HandleInput(Input input) = 0;



    virtual const std::string& GetName() const = 0;

};



class IdleState : public State {

public:

    const std::string& GetName() const override {

        static std::string name = "Idle State";

        return name;

    }



    State* HandleInput(Input input) override {

        if (input == Input::MOVE) {

            return new MoveState();

        }

        return this;

    }

};



class MoveState : public State {

public:

    const std::string& GetName() const override {

        static std::string name = "Move State";

        return name;

    }



    State* HandleInput(Input input) override {

        if (input == Input::STOP) {

            return new IdleState();

        }

        return this;

    }

};

6. 状态机在虚拟现实游戏中的应用

6.1 角色动画管理

在虚拟现实游戏中,角色的动画管理是一个重要的部分。通过状态机,可以根据角色的状态(如空闲、行走、跑步、攻击等)播放相应的动画。每个状态可以包含一个动画控制器,负责播放特定的动画。


class AnimationController {

public:

    void PlayAnimation(const std::string& animationName) {

        std::cout << "Playing " << animationName << std::endl;

    }

};



class IdleState : public State {

private:

    AnimationController* animationController;



public:

    IdleState(AnimationController* controller) : animationController(controller) {}



    void Enter() override {

        State::Enter();

        animationController->PlayAnimation("Idle");

    }



    void Update(float deltaTime) override {

        State::Update(deltaTime);

    }



    void Exit() override {

        State::Exit();

    }



    State* HandleInput(Input input) override {

        if (input == Input::MOVE) {

            return new MoveState(animationController);

        }

        return this;

    }



    const std::string& GetName() const override {

        static std::string name = "Idle State";

        return name;

    }

};



class MoveState : public State {

private:

    AnimationController* animationController;



public:

    MoveState(AnimationController* controller) : animationController(controller) {}



    void Enter() override {

        State::Enter();

        animationController->PlayAnimation("Move");

    }



    void Update(float deltaTime) override {

        State::Update(deltaTime);

    }



    void Exit() override {

        State::Exit();

    }



    State* HandleInput(Input input) override {

        if (input == Input::STOP) {

            return new IdleState(animationController);

        }

        return this;

    }



    const std::string& GetName() const override {

        static std::string name = "Move State";

        return name;

    }

};



class PlayerCharacter {

private:

    StateMachine* stateMachine;

    AnimationController* animationController;



public:

    PlayerCharacter() : animationController(new AnimationController()), stateMachine(new StateMachine(new IdleState(animationController))) {

        stateMachine->SetGlobalState(new GlobalState(animationController));

    }



    void Update(float deltaTime) {

        stateMachine->Update(deltaTime);

    }



    void HandleInput(Input input) {

        stateMachine->HandleInput(input);

    }

};

6.2 AI行为控制

状态机在AI行为控制中也非常有用。可以为NPC设计一个状态机,管理其在不同状态下的行为,例如巡逻、攻击、逃跑等。


class PatrolState : public State {

private:

    AIController* aiController;



public:

    PatrolState(AIController* controller) : aiController(controller) {}



    void Enter() override {

        State::Enter();

        aiController->StartPatrol();

    }



    void Update(float deltaTime) override {

        State::Update(deltaTime);

        aiController->Patrol(deltaTime);

    }



    void Exit() override {

        State::Exit();

        aiController->StopPatrol();

    }



    State* HandleInput(Input input) override {

        if (input == Input::ENEMY_DETECTED) {

            return new AttackState(aiController);

        }

        return this;

    }



    const std::string& GetName() const override {

        static std::string name = "Patrol State";

        return name;

    }

};



class AttackState : public State {

private:

    AIController* aiController;



public:

    AttackState(AIController* controller) : aiController(controller) {}



    void Enter() override {

        State::Enter();

        aiController->StartAttack();

    }



    void Update(float deltaTime) override {

        State::Update(deltaTime);

        aiController->Attack(deltaTime);

    }



    void Exit() override {

        State::Exit();

        aiController->StopAttack();

    }



    State* HandleInput(Input input) override {

        if (input == Input::ENEMY_LOST) {

            return new PatrolState(aiController);

        }

        return this;

    }



    const std::string& GetName() const override {

        static std::string name = "Attack State";

        return name;

    }

};



class AIController {

public:

    void StartPatrol() {

        std::cout << "AI starts patrolling" << std::endl;

    }



    void Patrol(float deltaTime) {

        std::cout << "AI patrolling" << std::endl;

    }



    void StopPatrol() {

        std::cout << "AI stops patrolling" << std::endl;

    }



    void StartAttack() {

        std::cout << "AI starts attacking" << std::endl;

    }



    void Attack(float deltaTime) {

        std::cout << "AI attacking" << std::endl;

    }



    void StopAttack() {

        std::cout << "AI stops attacking" << std::endl;

    }

};



class NPCCharacter {

private:

    StateMachine* stateMachine;

    AIController* aiController;



public:

    NPCCharacter() : aiController(new AIController()), stateMachine(new StateMachine(new PatrolState(aiController))) {}



    void Update(float deltaTime) {

        stateMachine->Update(deltaTime);

    }



    void HandleInput(Input input) {

        stateMachine->HandleInput(input);

    }

};

6.3 游戏状态管理

状态机可以用于管理游戏的整体状态,例如菜单、游戏进行中、游戏结束等。通过状态机,可以清晰地表示不同游戏状态之间的转换。每个状态可以包含特定的逻辑和动作,确保游戏在不同状态下的行为有序且可预测。


class MenuState : public State {

public:

    void Enter() override {

        State::Enter();

        std::cout << "Entering Menu State" << std::endl;

    }



    void Update(float deltaTime) override {

        State::Update(deltaTime);

        // 菜单状态下的更新逻辑,例如处理用户输入

    }



    void Exit() override {

        State::Exit();

        std::cout << "Exiting Menu State" << std::endl;

    }



    State* HandleInput(Input input) override {

        if (input == Input::START_GAME) {

            return new InGameState();

        }

        return this;

    }



    const std::string& GetName() const override {

        static std::string name = "Menu State";

        return name;

    }

};



class InGameState : public State {

public:

    void Enter() override {

        State::Enter();

        std::cout << "Entering In-Game State" << std::endl;

    }



    void Update(float deltaTime) override {

        State::Update(deltaTime);

        // 游戏进行中的更新逻辑,例如更新游戏世界、处理玩家输入

    }



    void Exit() override {

        State::Exit();

        std::cout << "Exiting In-Game State" << std::endl;

    }



    State* HandleInput(Input input) override {

        if (input == Input::GAME_OVER) {

            return new EndGameState();

        }

        return this;

    }



    const std::string& GetName() const override {

        static std::string name = "In-Game State";

        return name;

    }

};



class EndGameState : public State {

public:

    void Enter() override {

        State::Enter();

        std::cout << "Entering End Game State" << std::endl;

    }



    void Update(float deltaTime) override {

        State::Update(deltaTime);

        // 游戏结束状态下的更新逻辑,例如显示分数、提供重新开始选项

    }



    void Exit() override {

        State::Exit();

        std::cout << "Exiting End Game State" << std::endl;

    }



    State* HandleInput(Input input) override {

        if (input == Input::RETURN_TO_MENU) {

            return new MenuState();

        }

        return this;

    }



    const std::string& GetName() const override {

        static std::string name = "End Game State";

        return name;

    }

};



class Game {

private:

    StateMachine* stateMachine;



public:

    Game() : stateMachine(new StateMachine(new MenuState())) {}



    void Update(float deltaTime) {

        stateMachine->Update(deltaTime);

    }



    void HandleInput(Input input) {

        stateMachine->HandleInput(input);

    }

};

6.4 用户界面管理

状态机也可以用于管理用户界面的各种状态,例如按钮的点击状态、菜单的显示状态等。通过状态机,可以确保用户界面在不同状态下的行为一致且逻辑清晰。


class ButtonState : public State {

public:

    void Enter() override {

        State::Enter();

        std::cout << "Button is active" << std::endl;

    }



    void Update(float deltaTime) override {

        State::Update(deltaTime);

        // 按钮激活状态下的更新逻辑

    }



    void Exit() override {

        State::Exit();

        std::cout << "Button is inactive" << std::endl;

    }



    State* HandleInput(Input input) override {

        if (input == Input::BUTTON_CLICKED) {

            return new ButtonPressedState();

        }

        return this;

    }



    const std::string& GetName() const override {

        static std::string name = "Button State";

        return name;

    }

};



class ButtonPressedState : public State {

public:

    void Enter() override {

        State::Enter();

        std::cout << "Button is pressed" << std::endl;

    }



    void Update(float deltaTime) override {

        State::Update(deltaTime);

        // 按钮按下状态下的更新逻辑,例如触发某个功能

    }



    void Exit() override {

        State::Exit();

        std::cout << "Button is released" << std::endl;

    }



    State* HandleInput(Input input) override {

        if (input == Input::BUTTON_RELEASED) {

            return new ButtonState();

        }

        return this;

    }



    const std::string& GetName() const override {

        static std::string name = "Button Pressed State";

        return name;

    }

};



class MenuUI {

private:

    StateMachine* stateMachine;



public:

    MenuUI() : stateMachine(new StateMachine(new ButtonState())) {}



    void Update(float deltaTime) {

        stateMachine->Update(deltaTime);

    }



    void HandleInput(Input input) {

        stateMachine->HandleInput(input);

    }

};

7. 状态机的设计模式

状态机的设计模式可以帮助开发者更好地组织和管理状态机的代码。常见的设计模式包括状态模式和责任链模式。

7.1 状态模式

状态模式是一种行为设计模式,它允许对象在内部状态改变时改变其行为。状态模式通过将每个状态封装成一个类,使得状态的转换和管理更加清晰和模块化。


class Context {

private:

    State* currentState;



public:

    Context(State* initialState) : currentState(initialState) {}



    void Request1() {

        currentState->Handle1(this);

    }



    void Request2() {

        currentState->Handle2(this);

    }



    void TransitionTo(State* state) {

        if (currentState != nullptr) {

            currentState->Exit();

        }

        currentState = state;

        if (currentState != nullptr) {

            currentState->Enter();

        }

    }

};



class State {

public:

    virtual void Handle1(Context* context) = 0;

    virtual void Handle2(Context* context) = 0;

    virtual void Enter() = 0;

    virtual void Exit() = 0;

};



class ConcreteStateA : public State {

public:

    void Handle1(Context* context) override {

        std::cout << "ConcreteStateA handles request1." << std::endl;

        std::cout << "ConcreteStateA wants to change the state of the context." << std::endl;

        context->TransitionTo(new ConcreteStateB());

    }



    void Handle2(Context* context) override {

        std::cout << "ConcreteStateA handles request2." << std::endl;

    }



    void Enter() override {

        std::cout << "Entering ConcreteStateA" << std::endl;

    }



    void Exit() override {

        std::cout << "Exiting ConcreteStateA" << std::endl;

    }

};



class ConcreteStateB : public State {

public:

    void Handle1(Context* context) override {

        std::cout << "ConcreteStateB handles request1." << std::endl;

    }



    void Handle2(Context* context) override {

        std::cout << "ConcreteStateB handles request2." << std::endl;

        std::cout << "ConcreteStateB wants to change the state of the context." << std::endl;

        context->TransitionTo(new ConcreteStateA());

    }



    void Enter() override {

        std::cout << "Entering ConcreteStateB" << std::endl;

    }



    void Exit() override {

        std::cout << "Exiting ConcreteStateB" << std::endl;

    }

};

7.2 责任链模式

责任链模式是一种行为设计模式,它允许将请求的发送者和接收者解耦。通过将处理请求的多个对象链接成一条链,每个对象都可以处理请求或将其传递给下一个对象。这种模式可以用于处理复杂的输入事件,每个状态可以负责处理特定的事件。


class Handler {

public:

    virtual void SetNext(Handler* handler) = 0;

    virtual void Handle(Input input) = 0;

};



class BaseHandler : public Handler {

protected:

    Handler* nextHandler;



public:

    void SetNext(Handler* handler) override {

        nextHandler = handler;

    }



    void Handle(Input input) override {

        if (nextHandler != nullptr) {

            nextHandler->Handle(input);

        }

    }

};



class IdleHandler : public BaseHandler {

public:

    void Handle(Input input) override {

        if (input == Input::MOVE) {

            std::cout << "Handling MOVE in Idle State" << std::endl;

            // 转换到移动状态

            Transition(new MoveHandler());

        } else {

            BaseHandler::Handle(input);

        }

    }



    void Transition(Handler* newHandler) {

        if (nextHandler != nullptr) {

            nextHandler->SetNext(newHandler);

        }

    }

};



class MoveHandler : public BaseHandler {

public:

    void Handle(Input input) override {

        if (input == Input::STOP) {

            std::cout << "Handling STOP in Move State" << std::endl;

            // 转换到空闲状态

            Transition(new IdleHandler());

        } else {

            BaseHandler::Handle(input);

        }

    }



    void Transition(Handler* newHandler) {

        if (nextHandler != nullptr) {

            nextHandler->SetNext(newHandler);

        }

    }

};



class PlayerCharacter {

private:

    Handler* currentHandler;



public:

    PlayerCharacter() : currentHandler(new IdleHandler()) {}



    void Update(float deltaTime) {

        // 处理当前状态的更新逻辑

    }



    void HandleInput(Input input) {

        currentHandler->Handle(input);

    }

};

8. 状态机的高级应用

8.1 多层状态机

多层状态机(又称层次状态机)可以用于管理更复杂的行为。通过将状态嵌套在其他状态中,可以形成一个状态树,每个子状态可以有自己的行为和状态转移。


class RootState : public State {

public:

    void Enter() override {

        State::Enter();

        std::cout << "Entering Root State" << std::endl;

    }



    void Update(float deltaTime) override {

        State::Update(deltaTime);

        // 根状态的更新逻辑

    }



    void Exit() override {

        State::Exit();

        std::cout << "Exiting Root State" << std::endl;

    }



    State* HandleInput(Input input) override {

        if (input == Input::ENTER_SUBSTATE) {

            return new SubStateA();

        }

        return this;

    }



    const std::string& GetName() const override {

        static std::string name = "Root State";

        return name;

    }

};



class SubStateA : public State {

public:

    void Enter() override {

        State::Enter();

        std::cout << "Entering SubStateA" << std::endl;

    }



    void Update(float deltaTime) override {

        State::Update(deltaTime);

        // 子状态A的更新逻辑

    }



    void Exit() override {

        State::Exit();

        std::cout << "Exiting SubStateA" << std::endl;

    }



    State* HandleInput(Input input) override {

        if (input == Input::ENTER_SUBSTATE) {

            return new SubStateB();

        }

        if (input == Input::RETURN_TO_ROOT) {

            return new RootState();

        }

        return this;

    }



    const std::string& GetName() const override {

        static std::string name = "SubStateA";

        return name;

    }

};



class SubStateB : public State {

public:

    void Enter() override {

        State::Enter();

        std::cout << "Entering SubStateB" << std::endl;

    }



    void Update(float deltaTime) override {

        State::Update(deltaTime);

        // 子状态B的更新逻辑

    }



    void Exit() override {

        State::Exit();

        std::cout << "Exiting SubStateB" << std::endl;

    }



    State* HandleInput(Input input) override {

        if (input == Input::RETURN_TO_SUBSTATE_A) {

            return new SubStateA();

        }

        if (input == Input::RETURN_TO_ROOT) {

            return new RootState();

        }

        return this;

    }



    const std::string& GetName() const override {

        static std::string name = "SubStateB";

        return name;

    }

};



class MultiLevelStateMachine {

private:

    State* currentState;



public:

    MultiLevelStateMachine(State* initialState) : currentState(initialState) {}



    void Update(float deltaTime) {

        if (currentState != nullptr) {

            currentState->Update(deltaTime);

        }

    }



    void HandleInput(Input input) {

        if (currentState != nullptr) {

            State* nextState = currentState->HandleInput(input);

            if (nextState != currentState) {

                Transition(nextState);

            }

        }

    }



    void Transition(State* newState) {

        if (currentState != nullptr) {

            currentState->Exit();

        }

        currentState = newState;

        if (currentState != nullptr) {

            currentState->Enter();

        }

    }

};

8.2 状态机的并发执行

在某些复杂的应用场景中,角色可能需要同时处理多个状态。并发状态机允许角色在同一时刻处于多个状态,每个状态独立运行,相互之间可以协调。


class ConcurrentState {

public:

    virtual void Enter() = 0;

    virtual void Update(float deltaTime) = 0;

    virtual void Exit() = 0;

    virtual void HandleInput(Input input) = 0;

};



class ConcurrentStateMachine {

private:

    std::vector<ConcurrentState*> states;



public:

    void AddState(ConcurrentState* state) {

        states.push_back(state);

        state->Enter();

    }



    void RemoveState(ConcurrentState* state) {

        auto it = std::find(states.begin(), states.end(), state);

        if (it != states.end()) {

            state->Exit();

            states.erase(it);

        }

    }



    void Update(float deltaTime) {

        for (auto& state : states) {

            state->Update(deltaTime);

        }

    }



    void HandleInput(Input input) {

        for (auto& state : states) {

            state->HandleInput(input);

        }

    }

};



class CombatState : public ConcurrentState {

public:

    void Enter() override {

        std::cout << "Entering Combat State" << std::endl;

    }



    void Update(float deltaTime) override {

        std::cout << "Combat State Update" << std::endl;

        // 战斗状态的更新逻辑

    }



    void Exit() override {

        std::cout << "Exiting Combat State" << std::endl;

    }



    void HandleInput(Input input) override {

        // 处理战斗状态的输入事件

    }

};



class MovementState : public ConcurrentState {

public:

    void Enter() override {

        std::cout << "Entering Movement State" << std::endl;

    }



    void Update(float deltaTime) override {

        std::cout << "Movement State Update" << std::endl;

        // 移动状态的更新逻辑

    }



    void Exit() override {

        std::cout << "Exiting Movement State" << std::endl;

    }



    void HandleInput(Input input) override {

        // 处理移动状态的输入事件

    }

};



class PlayerCharacter {

private:

    ConcurrentStateMachine* stateMachine;



public:

    PlayerCharacter() : stateMachine(new ConcurrentStateMachine()) {}



    void EnterCombat() {

        stateMachine->AddState(new CombatState());

    }



    void ExitCombat() {

        stateMachine->RemoveState(new CombatState());

    }



    void Move() {

        if (std::find_if(stateMachine->states.begin(), stateMachine->states.end(), [](ConcurrentState* state) {

            return dynamic_cast<MovementState*>(state) != nullptr;

        }) == stateMachine->states.end()) {

            stateMachine->AddState(new MovementState());

        }

    }



    void StopMove() {

        stateMachine->RemoveState(new MovementState());

    }



    void Update(float deltaTime) {

        stateMachine->Update(deltaTime);

    }



    void HandleInput(Input input) {

        stateMachine->HandleInput(input);

    }

};

9. 总结

状态机是一种强大的工具,适用于多种场景,特别是在虚拟现实游戏开发中。通过清晰地表示角色的行为和状态之间的关系,状态机可以提高代码的可维护性和可读性。不同的状态机类型(如确定性有限状态机、非确定性有限状态机、层次状态机和历史状态机)提供了不同的灵活性和复杂性,可以根据具体需求选择合适的状态机类型。此外,通过设计模式(如状态模式和责任链模式)和高级应用(如多层状态机和并发状态机),可以进一步优化状态机的实现,使其更加高效和灵活。

希望本文对您理解状态机的基础理论和应用有所帮助,如果您有任何疑问或需要进一步的解释,请随时联系。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值