前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >学以致用C++设计模式 之 “状态模式”

学以致用C++设计模式 之 “状态模式”

作者头像
看、未来
发布2020-08-25 23:06:08
5460
发布2020-08-25 23:06:08
举报
在这里插入图片描述
在这里插入图片描述

从DFA讲起

何为DFA?确定的有穷状态机。这里

看完上面那篇博客,就明白状态机还挺好用的。 那么现在,转场。

游戏角色

要开发一款游戏,咱负责的模块是处理游戏角色属性框架的搭建,目前已知角色有:坦克、法师、射手,他们都有属性:血量、物攻、物抗、法攻、法抗、角色转换技能。

同样,可以采用自动机的方式来进行处理:

坦克

法师

射手

坦克

-

双抗-,法攻+

双抗-,物攻+

法师

双抗+,法攻-

-

物攻+,法攻-

射手

双抗+,物攻-

物攻-,法攻+

-

也挺好办的,就这样封装好了。

但是,这毕竟是C语言的方式,面向过程,如果我要拓展,加俩新角色进去呢?加个近战战士,怎么办?把写好的代码拆了重写?那明天再加个辅助进去,再重写?

既然学了面向对象,那就用面向对象的方式来解决这类问题:将每种状态封装成类,然后该怎么办就不用我多说了。

类怎么设计呢?看这样好不好:

代码语言:javascript
复制
class 坦克{
private:
	int 血量;
	int 物攻;
	int	物抗;
	int 法攻;
	int 法抗;
public:
	void 攻击();
	void 防守();
	void 技能();
}

可还行? 然后场景类就这样:

代码语言:javascript
复制
int main(){

	class* 坦克兵 = new 坦克();
	class* 魔法师 = new 法师();
	class* 狙击手 = new 射手();
	
//被人打了,用坦克
	坦克兵->防守();

//要打消耗,用法师
	魔法师->攻击();

//敌人要跑,用射手
	狙击手->技能();

···
}

这样始终是零散,疏于管教。而且,并不能实现自动啊,顶多就是个手动状态机。 那怎么弄哦?将前边的DFA再看看,再配上责任链的思想,想想就知道该来了父类,然后每个子类中自己管理自己的状态,再维护一条状态链表,实现有穷的自动状态机(C++状态模式版)。

你看这样可好?

代码语言:javascript
复制
class 状态基类{
private:
	string 当前状态;
	状态基类* 下一状态;
public:
	virtual void 攻击();
	virtual void 防守();
	virtual void 技能();
	void setState(string 状态){this->当前状态 = 状态;}
	void setNextNode(状态基类* 下一状态){this->下一状态 = 下一状态;};
	状态基类* 遍历状态(string 目标状态){
		if(this->当前状态 == 目标状态)
			return this;
		else if(this->下一状态 != NULL)
			下一状态->遍历状态(目标状态);
		else
			return NULL;
	}
}

class 坦克:public 状态基类{
public:
	void 攻击(){···}
	void 防守(){···}
	void 技能(){···}
}

···

场景类就这样实现了:

代码语言:javascript
复制
状态基类* 状态1 = new 坦克();
状态基类* 状态2 = new 战士();
状态基类* 状态3 = new 法师();
状态基类* 状态4 = new 射手();

状态基类* 当前状态;

状态1->setState("坦克");
状态2->setState("战士");
状态3->setState("法师");
状态4->setState("射手");


状态1->setNextNode(状态2);
状态2->setNextNode(状态3);
状态3->setNextNode(状态4);

//被人打了
当前状态 = 状态1->遍历状态(坦克);
当前状态->防守();

//要打消耗,用法师
当前状态 = 状态1->遍历状态(法师);
当前状态->攻击();

//敌人要跑,用射手
当前状态 = 状态1->遍历状态(射手);
当前状态->技能();

//中埋伏了,换战士
当前状态 = 状态1->遍历状态(战士);
当前状态->攻击();
当前状态->防守();
当前状态->放技能();

这样连轴转。


什么是状态模式

当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其种类。

状态模式的核心是封装,状态的变更引起了行为的变更,从外部看起来就好像这个对象对应的类发生了改变一样。

状态模式的应用

优点:

结构清晰、遵循设计原则、封装性好

缺点:

要避免状态过多。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-07-02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 从DFA讲起
  • 游戏角色
  • 什么是状态模式
    • 状态模式的应用
      • 优点:
      • 缺点:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档