博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
state模式实现游戏动画系统
阅读量:4679 次
发布时间:2019-06-09

本文共 1784 字,大约阅读时间需要 5 分钟。

在游戏中,游戏人物根据玩家的输入以及人物与游戏世界交互,会有许多动作动画效果的转换。简单的比如马里奥,玩家没有输入,没有发生游戏事件(吃到蘑菇、碰到怪物)时,马里奥大叔静止不动。玩家按下移动按钮,马里奥开始走动,这时需要绘制走路的动画效果。按下跳跃键,绘制跳跃的动画效果。而按键和动作并不是一一对应的关系,比如跳跃过程中按下左右移动键,并不能绘制走路的动画效果。

 

这些状态之间的转换可以使用if else,switch case,语句来完成,如下:

//这里把人物写成一个Role类class Role{public:enum STATE{IDLE,WALK,JUMP,}void JumpInput(){	_state = JUMP;	//..设置当前动画为跳跃的动画}void WalkInput(){	if (_state == IDLE)	{		_state = WALK;		//..设置当前动画为行走的动画	}}// 跳跃后角色落地,由碰撞检测触发void OnLand(){	 _state = IDLE;}private:STATE _state;}
 

貌似挺完美,嗯,这样完美的情况仅仅只限于状态比较少,状态转换比较简单的条件下,如果人物状态一增多,状态转换条件一变复杂,那将变成一场噩梦,代码中会产生大量的if else条件判断,比如我们再增加一个蹲下的状态,蹲下时按下跳跃键让游戏人物快速向前贴地滑动一段距离,Rockman的操作好像就是这样。再加一个约束条件,蹲下时按下左右移动键无效果。哇哦,这样再看看上面那段简单的代码要变成什么样子了。

 

如何以一种条理清晰,便于维护的方式来实现以上需求呢? 以上需求的核心是状态的转换,自然而然,带有“状态”这个关键字的state模式首先成了思考方向。state模式将每个状态抽象成类,状态的转换由状态自己来操作,是一种比较灵活的实现方式。基于state模式,将代码重构如下(伪代码):

// 伪代码class IStatus{	Role* role;	// 输入向上键	virtual void Up();	// 输入向下键	virtual void Down();	// 输入向左键	virtual void Left();	// 输入向右键	virtual void Right();	// 输入跳跃键	virtual void Jump();	// 输入攻击键	virtual void Attack();	// 动作完成后	virtula void Done();};class IdleState;{	Left() {role->setState(WalkState);}	Right() {role->setState(WalkState);}	Down() {role->setState(CrouchState);}	Jump() {role->setState(JumpState);}}class WalkState{	Jump() {role->setState(JumpState);}}class JumpState;{}class CrouchState{	Jump() {role->setState(SlipState);}}class SlipState{}
 
Role类:
class Role{		IState _state;	// 输入向上键	void Up() { _state.Up();}	// 输入向下键	void Down() { _state.Down();}	// 输入向左键	void Left() { _state.Left();}	// 输入向右键	void Right() { _state.Right();}	// 输入跳跃键	void Jump() { _state.Jump();}	// 输入攻击键	void Attack() { _state.Attack();}}
 
这样用state模式来写,后期维护和加入新的状态也变得十分容易,加入新的状态只需要加入一个新的类,而不需变更以有的代码。

转载于:https://www.cnblogs.com/hj046/archive/2011/08/13/2136886.html

你可能感兴趣的文章
AES对上传文件解密并加密的实现(JAVA实现)
查看>>
ThreadLocal 正名
查看>>
AngularJS自定义指令详解(有分页插件代码)
查看>>
数据挖掘学习--数据仓库
查看>>
基于Eclipse的Hadoop应用开发环境配置
查看>>
howto:Vaadin开发环境部署 for Spring Roo - vaadin.com
查看>>
mariadb semi plugin遇到的坑
查看>>
使用Collectd + InfluxDB + Grafana进行JMX监控
查看>>
Linux下tar,zip命令详解
查看>>
NABCD分析
查看>>
input实时监听
查看>>
Maven学习:常用mvn命令
查看>>
C#垃圾回收机制
查看>>
web项目部署到Tomcat服务器的三种方式
查看>>
P1962 斐波那契数列-题解(矩阵乘法扩展)
查看>>
Kibana6.x.x源码分析--Error: $injector:nomod Module Unavailable
查看>>
周围区域问题
查看>>
31、任务三十一——表单联动
查看>>
[ios] IOS文件操作的两种方式:NSFileManager操作和流操作【转】
查看>>
Jenkins之Linux和window配置区别
查看>>