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 ... 
随机推荐
- DragVideo,一种在播放视频时,可以任意拖拽的方案
			转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/53638896 前言 项目已开源到 ... 
- ROS机器人程序设计(原书第2版)学习镜像分享及使用说明
			ROS机器人程序设计(原书第2版)学习镜像分享及使用说明 系统用于ROS爱好者学习交流,也可用于其他用途,并不局限于ROS. 这款镜像文件是基于一年前的Ubuntu ROS Arduino Gazeb ... 
- 关于Android PullTorefreshScrollview回到顶部实例
			列表滑动下面显示按钮,点击按钮回到顶部的功能,一般scrollview会有滑动监听的事件,通过setOnScrollChangeListener()滑动监听滑动的距离来判断是否显示按钮就好了,但是Pu ... 
- 有n个数,输出其中所有和为s的k个数的组合。
			分析:此题有两个坑,一是这里的n个数是任意给定的,不一定是:1,2,3...n,所以可能有重复的数(如果有重复的数怎么处理?):二是不要求你输出所有和为s的全部组合,而只要求输出和为s的k个数的组合. ... 
- Spring Boot微服务架构入门
			概述 还记得在10年毕业实习的时候,当时后台三大框架为主流的后台开发框架成软件行业的标杆,当时对于软件的认识也就是照猫画虎,对于为什么会有这么样的写法,以及这种框架的优势或劣势,是不清楚的,Sprin ... 
- 关于activitygroup过时,用frament替换操作
			现在Fragment的应用真的是越来越广泛了,之前Android在3.0版本加入Fragment的时候,主要是为了解决Android Pad屏幕比较大,空间不能充分利用的问题,但现在即使只是在手机上, ... 
- Runtime系列(二)--Runtime的使用场景
			Runtime 理解介绍的文章非常多,我只想讲讲Runtime 可以用在哪里,而我在项目里哪些地方用到了runtime.多以实际使用过程为主,来介绍runtime的使用. * 那么runtime 怎么 ... 
- 创建一个QT for Android的传感器应用应用程序(摘自笔者2015年将出的《QT5权威指南》,本文为试读篇)
			 这个手册描述了使用Qt Quick面访的方式在Android和ios设备上开发QtQuick应用程序的方法.我们使用Qt Creator实现一个QtQuick应用程序,这个应用程序基于加速器的值 ... 
- Android开发学习之路--Notification之初体验
			一般当我们收到短信啊,微信啊,或者有些app的提醒,我们都会在通知栏收到一天简单的消息,然后点击消息进入到app里面,其实android中有专门的Notification的类可以完成这个工作,这里就实 ... 
- UNIX网络编程——fcntl函数
			fcntl函数提供了与网络编程相关的如下特性: 非阻塞式I/O. 通过使用F_SETFL命令设置O_NONBLOCK文件状态标志,我们可以把一个套接字设置为非阻塞型. 信号驱动式I/O. 通过使用F ... 
