cocos2d-x 游戏开发之有限状态机(FSM) (二)
cocos2d-x 游戏开发之有限状态机(FSM) (二)
1 状态模式
State是状态基类。它其实是一个接口,它有3个实现类,分别对应每个状态。Monkey类只需要维护State类,而具体的行为通过3个实现类完成。这就是多态。下面是完整的代码:
2 状态基类
// State.h // #ifndef STATE_H_ #define STATE_H_ class Monkey; struct State { virtual void execute(Monkey *mk) = 0; }; #endif // STATE_H_
3 实现类
3.1 StopState
// StopState.h // #ifndef STOP_STATE_H_ #define STOP_STATE_H_ #include "State.h" #include "Monkey.h" class StopState : public State { public: virtual void execute(Monkey *mk); }; #endif // STOP_STATE_H_
// StopState.cpp // #include "StopState.h" #include "WalkState.h" void StopState::execute(Monkey *mk) { if (mk->isStopTimeout()) { mk->changeState(new WalkState()); mk->walk(); } }
3.2 WalkState
// WalkState.h // #ifndef WALK_STATE_H_ #define WALK_STATE_H_ #include "State.h" #include "Monkey.h" class WalkState : public State { public: virtual void execute(Monkey *mk); }; #endif // WALK_STATE_H_
// WalkState.cpp // #include "WalkState.h" #include "TurnState.h" #include "StopState.h" void WalkState::execute(Monkey *mk) { mk->walk(); if (mk->isWalkOutBorder()) { mk->changeState(new TurnState()); mk->turn(); } else if (mk->isWalkTimeout()) { mk->changeState(new StopState()); mk->stop(); } }
3.3 TurnState
// TurnState.h // #ifndef TURN_STATE_H_ #define TURN_STATE_H_ #include "State.h" #include "Monkey.h" class TurnState : public State { public: virtual void execute(Monkey *mk); }; #endif // TURN_STATE_H_
// TurnState.cpp // #include "TurnState.h" #include "WalkState.h" void TurnState::execute(Monkey *mk) { mk->changeState((State*) new WalkState()); mk->walk(); }
4 Monkey
#ifndef MONKEY_H_ #define MONKEY_H_ #include <time.h> #include "cocos2d.h" USING_NS_CC; #include "State.h" #define MAX_STOP_TIME 10 #define MAX_WALK_TIME 20 #define MAX_WALK_DIST 100 class Monkey : public Node { public: Monkey() { log("Monkey()"); } CREATE_FUNC(Monkey); virtual bool init() { _curPos = 0; _step = 1; _curState = 0; this->scheduleUpdate(); return true; } void changeState(State * newState) { State * oldState = _curState; _curState = newState; if (oldState) { delete oldState; } _curTime = time(0); } void stop() { cocos2d::log("stop()"); } void walk() { _curPos += _step; cocos2d::log("walk(): pos=%d", _curPos); } void turn() { _step *= -1; cocos2d::log("turn(): step=%d", _step); } void update(float dt) { if (_curState) { _curState->execute(this); } } private: State * _curState; time_t _curTime; int _curPos; int _step; public: bool isStopTimeout() { return (time(0) - _curTime > MAX_STOP_TIME); } bool isWalkTimeout() { return (time(0) - _curTime > MAX_WALK_TIME); } bool isWalkOutBorder() { return (_curPos > MAX_WALK_DIST || _curPos < -MAX_WALK_DIST); } }; #endif // MONKEY_H_
5 总结
当我们需要添加了一种新的状态时,不需要去修改长长的条件判断语句了,只需要构造一个新的状态类,修改它的前序和后序状态类就可以了。对于任何一个状态的特有行为,都是独立的,不会混杂在其它状态的代码里。原为决定状态转移逻辑的那个长长的条件语句不见了,而是被分布在State的子类之间。另一方面,从设计的角度看,原先对当前状态的标识,是FSM内部的一个自有变量,状态与状态之间的转换也仅仅是表现为对自有变量的赋值,如果这个自有变量衍生为变量数组时,那极易出现FSM内部状态不一致的情况,而State的引入可以使得这样的情况变得相当简单。对于新版本的FSM来说,状态与状态之间的转换也成了原子化的操作,不需要兼顾多个变量的赋值。
既然所有状态机具有同样的规则和范式,那么状态机应该与具体对象无关,完全可以提炼出纯粹的状态机类来管理任何对象的状态。下节就完成这个任务。
cocos2d-x 游戏开发之有限状态机(FSM) (二)的更多相关文章
- cocos2d-x 游戏开发之有限状态机(FSM) (四)
cocos2d-x 游戏开发之有限状态机(FSM) (四) 虽然我们了解了FSM,并且可以写自己的FSM,但是有更好的工具帮我们完成这个繁琐的工作.SMC(http://smc.sourceforge ...
- cocos2d-x 游戏开发之有限状态机(FSM) (三)
cocos2d-x 游戏开发之有限状态机(FSM) (三) 有限状态机简称FSM,现在我们创建一个专门的FSM类,负责管理对象(Monkey)的状态.然后Monkey类就实现了行为与状态分离.Monk ...
- cocos2d-x 游戏开发之有限状态机(FSM) (一)
cocos2d-x 游戏开发之有限状态机(FSM) (一) 参考:http://blog.csdn.net/mgphuang/article/details/5845252<Cocos2d-x游 ...
- 《C++游戏开发》笔记十二 战争迷雾:初步实现
本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9475979 作者:七十一雾央 新浪微博:http:/ ...
- iOS cocos2d 2游戏开发实战(第3版)书评
2013是游戏爆发的一年,手游用户也是飞速暴增.虽然自己不做游戏,但也是时刻了解手机应用开发的新动向.看到CSDN的"写书评得技术图书赢下载分"活动,就申请了一本<iOS c ...
- java游戏开发杂谈 - 有限状态机
在不同的阶段,游戏所运行的逻辑.所显示的界面,都是不同的. 以五子棋举例,游戏开始.游戏中.胜负已分,对应的界面和逻辑都不同. 在游戏中,又分为:自己下棋.对方下棋.游戏暂停.悔棋等多个状态. 再比如 ...
- (转载)如何学好iphone游戏开发
转自:http://www.cnblogs.com/zilongshanren/archive/2011/09/19/2181558.html 自从发布<如何学习iphone游戏开发>到 ...
- 整理了一下浅墨大神的Visual C++/DirectX 9.0c的游戏开发手记
还是非常棒的博客,只是没有一个文件夹.所以自己做了一个山寨文件夹在这里.便于随时查找. 前面31期从略. [Visual C++]游戏开发笔记三十二 浅墨DirectX提高班之中的一个 DirectX ...
- HTML5物理游戏开发 - 越野山地自行车(三)粉碎自行车
自上一章公布到如今已时隔四月,实在对不住大家.让大家久等了~话说不是我不关注我的博客,而是事情一多起来写博客的时间就少了. 待到今日有空了,回头看了看自己曾经写的文章,猛得发现已经四个月不曾写文章了. ...
随机推荐
- Swift:Minimizing Annotation with Type Inference
许多程序猿更喜欢比如Python和Javascript这样的动态语言,因为这些语言并不要求程序猿为每个变量声明和管理它们的类型. 在大多数动态类型的语言里,变量可以是任何类型,而类型声明是可选的或者根 ...
- 微信小程序基础之input输入框控件
今天主要详写一下微信小程序中的Input输入框控件,输入框在程序中是最常见的,登录,注册,获取搜索框中的内容等等都需要,同时,还需要设置不同样式的输入框,今天的代码中都要相应的使用. input输入框 ...
- The Zen Programmer
专注 何为专注 关于 休息 怎么睡觉 心无杂念 我的体会 自我分析 初学者心态 无我 不要设置职业目标 敏事慎言 正念 做自己的老板 玩物养志 结语 最近在研读Christian Grobmeier ...
- Spring之AOP模块
AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的一个重要特征 Spring推荐使用接口编程 Spring提供三种拦截器:方法前拦截器.返回后拦截器.异 ...
- Android的SharedPreferences(首选项)保存键值对
使用共享首选项 如果您有想要保存的相对较小键值集合,您应使用 SharedPreferences API.SharedPreferences 对象指向包含键值对的文件并提供读写这些文件的简单方法. 每 ...
- 有N个数,组成的字符串,如012345,求出字串和取MOD3==0的子串,如012 12 123 45。
#include <iostream> using namespace std; int getSum(string str, int begin, int len) { int sum ...
- GridView如何适配不同屏幕
GridView和ListView一样,都是项目中常用的控件之一,那么本篇文章要讲的是GridView如何适应不同大小的屏幕,首先,我们来看一张效果图,如下: 每行为四个item,上下左右间距大概2d ...
- FFmpeg源代码简单分析:常见结构体的初始化和销毁(AVFormatContext,AVFrame等)
===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...
- 对N各集合中的任意元素进行排列组合问题
小李去市场买菜,有蔬菜(茄子.黄瓜.大白菜...等k中素菜),和肉类(牛肉,羊肉,鸡肉...等m种荤菜),及点心(麻饼,桃酥,枣花...等n中点心),现在老婆要求每天一荤一素一点心 并且每天的样式要尽 ...
- Android的ToggleButton和Switch以及AnalogColok和DigitalColok的用法-android学习之旅(二十)
ToggleButton 和Switch简介 ToggleButton 和Switch都是继承了Button,所以他们的属性设置和Button差不多. 分别支持的属性 ToggleButton 的属性 ...