cocos2d-x 游戏开发之有限状态机(FSM) (一)
cocos2d-x 游戏开发之有限状态机(FSM) (一)
参考:
http://blog.csdn.net/mgphuang/article/details/5845252
《Cocos2d-x游戏开发之旅》(钟迪龙)
基本上所有的软件都是有限状态机(finite-state machine,FSM)。它是一个有向图,由一组节点和一组相应的转移函数组成。通俗点讲,它是一个事件驱动系统的模型,这个模型由有限数目的状态,若干输入和状态与状态之间转换的规则组成。在某一时刻,有一个或一组状态是FSM的当前状态,FSM接收输入事件并根据转换规则,将当前状态转为新的状态。正是由于这三个元素的组合,使得FSM具备了自己的行为特点。在游戏开发中,FSM被用来实现人工智能的决策过程,控制游戏对象的行为。
1 最简单的状态机
可能上面的解释还是有些抽象,绝大多数的文章会举用“门”或“锁”的例子来说明什么是状态机,我想还是举一个新鲜的例子吧:有一个叫做“猴子”的NPC,它会在指定的区域里行走,有时候停留,当行走到区域的边界所时,会自己转向(图1)。我们把状态机的转换规则函数列出表格(图2),并根据列出的规则写出是这个简单状态机的C++实现:
#ifndef MONKEY_H_
#define MONKEY_H_
#include <time.h>
#include "cocos2d.h"
USING_NS_CC;
#define MAX_STOP_TIME  10
#define MAX_WALK_TIME  20
#define MAX_WALK_DIST  100
enum MonkeyState
{
    stSTOP,
    stWALK,
    stTURN
};
class Monkey
    : public Node
{
public:
    Monkey()
    {
        log("Monkey()");
    }
    CREATE_FUNC(Monkey);
    virtual bool init()
    {
        _curPos = 0;
        _step = 1;
        changeState(stSTOP);
        this->scheduleUpdate();
        return true;
    }
    void changeState(MonkeyState newState)
    {
        _curState = newState;
        _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)
    {
        switch (_curState) {
        case stSTOP:
            if (isStopTimeout()) {
                changeState(stWALK);
                walk();
            }
            break;
        case stWALK:
            walk();
            if (isWalkOutBorder()) {
                changeState(stTURN);
                turn();
            } else if (isWalkTimeout()) {
                changeState(stSTOP);
                stop();
            }
            break;
        case stTURN:
            changeState(stWALK);
            walk();
            break;
        }
    }
private:
    MonkeyState _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_
2 坏代码的味道
显然,如果继续将上面的代码写完整的话,它一定能很好的工作。但我似乎已经闻到了传说中“坏代码”的味道,上面长长的条件判断语句,会随着状态的增多变得更长。每增加一个状态,就需要在长长的条件判断语句中小心查找和修改。当这样的条件语句增长到需要多个人合作完成时,那当导致严重的维护与调试方面的问题。另外,对于编译型语言而言,一个具有N个状态的FSM要查找一个正确的状态,平均需要进行N/2次的判断。
在上面的状态机中,其实是让这个对象在不同的状态中表现出了不同的行为特征,那不同的行为特征之间除了有类似的形式化的接口之外,基本上没有任何的联系。那我们很自然地想到状态模式,利用状态模式维护状态,实现对象与维护状态的分离。
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) (二) 1 状态模式
 - iOS cocos2d 2游戏开发实战(第3版)书评
		
2013是游戏爆发的一年,手游用户也是飞速暴增.虽然自己不做游戏,但也是时刻了解手机应用开发的新动向.看到CSDN的"写书评得技术图书赢下载分"活动,就申请了一本<iOS c ...
 - java游戏开发杂谈 - 有限状态机
		
在不同的阶段,游戏所运行的逻辑.所显示的界面,都是不同的. 以五子棋举例,游戏开始.游戏中.胜负已分,对应的界面和逻辑都不同. 在游戏中,又分为:自己下棋.对方下棋.游戏暂停.悔棋等多个状态. 再比如 ...
 - (转载)如何学好iphone游戏开发
		
转自:http://www.cnblogs.com/zilongshanren/archive/2011/09/19/2181558.html 自从发布<如何学习iphone游戏开发>到 ...
 - 游戏开发设计模式之状态模式 & 有限状态机 & c#委托事件(unity3d 示例实现)
		
命令模式:游戏开发设计模式之命令模式(unity3d 示例实现) 对象池模式:游戏开发设计模式之对象池模式(unity3d 示例实现) 原型模式:游戏开发设计模式之原型模式 & unity3d ...
 - cocos2d 游戏开发实战
		
文章转自:http://uliweb.clkg.org/tutorial/read/40 6 cocos2d 游戏开发实战 6.1 创建cocos2d项目 6.2 cocos2d v3 & ...
 - 【Cocos2D研究院之游戏开发】
		
http://www.xuanyusong.com/archives/category/ios/cocos2d_game 分类目录归档:[Cocos2D研究院之游戏开发] 201211-19 Co ...
 
随机推荐
- Ubuntu14下安装svn仓库,以及权限配置
			
sudo apt-get update 接下来安装svn apt-get install subversionapt-get install libapache2-svn 检查svn是否安装成功了: ...
 - Python尾递归-创始人为何不愿TRE以及我们如何模拟TRE
			
TRE=Tail Recursion Elimination 创始人是不愿意实现TRE的.他专门用了一篇文章来阐述原因. http://neopythonic.blogspot.com/2009/04 ...
 - JVM垃圾回收总结
			
来自Oracle官方文档,对JVM GC知识整理的清晰易懂,查资料还是看官方的好! 1 GC步骤简述 步骤1:标记 (Marking) 根据对象引用关系,将未被任何对象引用的对象实例标记出来,如下图中 ...
 - 十六进制字符串转化为十进制值strtoul函数
			
eg: NSString *strtest =@"7fffffff"; NSUInteger val = strtoul([[strtest substringWithRange: ...
 - 没有文件扩展“.js”的脚本引擎问题解决
			
安装MinGW的时候提示没有文件扩展".js"的脚本引擎. 原因:系统安装Dreamwear.UltraEdit.EditPlus后修改了.js文件的默认打开方式.当想直接执行js ...
 - How to generate the complex data regularly to Ministry of Transport of P.R.C by DB Query Analyzer
			
How to generate the complex data regularly to Ministry of Transport of P.R.C by DB Query Analyzer 1 ...
 - Eclipse中设置VM参数
			
eclipse.ini -Xms256m //设置堆最小值 -Xmx1024m //设置堆最大值 Eclipse 做JVM 的分析时,需要动态设置JVM的参数来进行各种测试, 可以在下图地方进行设置 ...
 - VNC 登录上去灰屏,没有shell脚本,鼠标变成X
			
CenterOS 1.安装vncserver yum install tigervnc-server -y 2.vncpasswd 设置pwd 3./etc/sysconfig/vncservers ...
 - 02_3中方式的反射,通过Class.forName获得Class对象,通过类.class获得字节码对象,通过类实例.getClass()的方式获得Class对象
			
 反射中加载类: Java中有一个Class类用于代表某一个类的字节码 .class文件 对应Class //1 加载类 // java中Class代表一个类,但是到底代表哪个类要明确指出 ...
 - ormlite介绍一
			
概述 ORMlite是类似hibernate的对象映射框架,主要面向java语言,同时,是时下最流行的android面向数据库的的编程工具. 官方网站:http://ormlite.com ...