状态模式

状态模式|菜鸟教程
【游戏设计模式】之三 状态模式、有限状态机 & Unity版本实现

定义

在状态模式(State Pattern)中,类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。

在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。

使用场景

1.游戏
2.基于状态改变作出不同动作的场景

基本思路

1.为状态定义一个接口
2.为每个状态定义一个类
3.恰当地进行状态委托。

实例

假如有一款游戏, 一个女英雄他有多种状态, 如站立、下蹲、跳跃、下斩等状态,按照常规的实现方式,我们可以用大量的if else来判断,或者switch case来实现, 但是这样做缺点很明显, 会存在大量bug并且代码不移维护和扩展。

1.为状态定义一个接口:

class Heroine;

class HeroineState
{
public:
	virtual ~HeroineState() {}
	virtual void handleInput(Heroine& heroine, int input) = 0;
	virtual void update(Heroine& heroine) = 0;
};

2.为每个状态定义一个类

#pragma once
#include "HeroineState.h"
class JumpingState :
    public HeroineState
{
    // 通过 HeroineState 继承
    virtual void handleInput(Heroine& heroine, int input) override;
    virtual void update(Heroine& heroine) override;
};

void JumpingState::handleInput(Heroine& heroine, int input)
{
	if (input == 2) {
		printf("jumping state \n");
	}
}

void JumpingState::update(Heroine& heroine)
{
}
#pragma once
#include "HeroineState.h"

class StandState :public HeroineState
{
public:
	// 通过 HeroineState 继承
	virtual void handleInput(Heroine& heroine, int input) override;
	virtual void update(Heroine& heroine) override;
};

#include "StandState.h"
#include <stdio.h>
void StandState::handleInput(Heroine& heroine, int input)
{
	if (input == 1) {
		printf("stand state \n");
	}
}

void StandState::update(Heroine& heroine)
{

}

3.适当的进行状态委托

#pragma once

#include "HeroineState.h"
class Heroine
{

public:
	enum class StateCode {
		Stand = 1,
		Jump  = 2,
	};

	void setState(HeroineState* state) {
		this->state = state;
	}

	virtual void handleInput(int input) {
		if (state != nullptr) {
			state->handleInput(*this, input);
		}
	}

	virtual void update()
	{
		state->update(*this);
	}

private:
	HeroineState* state = nullptr;
};

main

#include <stdio.h>
#include "Heroine.h"
#include "StandState.h"
#include "JumpingState.h"
#include <stdlib.h>

void main() {

	Heroine* heroinePtr = new Heroine;

	heroinePtr->setState(new StandState());

	heroinePtr->handleInput(static_cast<int>(Heroine::StateCode::Stand));

	heroinePtr->setState(new JumpingState());

	heroinePtr->handleInput(static_cast<int>(Heroine::StateCode::Jump));

	system("pause");
}

之后就只需要继承state类 重写方法即可

总结

demo地址