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来说,状态与状态之间的转换也成了原子化的操作,不需要兼顾多个变量的赋值。

既然所有状态机具有同样的规则和范式,那么状态机应该与具体对象无关,完全可以提炼出纯粹的状态机类来管理任何对象的状态。下节就完成这个任务。

时间: 2024-08-05 16:54:32

cocos2d-x 游戏开发之有限状态机(FSM) (二)的相关文章

cocos2d-x 游戏开发之有限状态机(FSM) (四)

cocos2d-x 游戏开发之有限状态机(FSM) (四) 虽然我们了解了FSM,并且可以写自己的FSM,但是有更好的工具帮我们完成这个繁琐的工作.SMC(http://smc.sourceforge.net/)就是这样的工具.下载地址: http://sourceforge.net/projects/smc/files/latest/download 在bin下面的Smc.jar是用于生成状态类的命令行工具.使用如下命令: $ java -jar Smc.jar Monkey.sm 1 真实世

cocos2d-x 游戏开发之有限状态机(FSM) (三)

cocos2d-x 游戏开发之有限状态机(FSM) (三) 有限状态机简称FSM,现在我们创建一个专门的FSM类,负责管理对象(Monkey)的状态.然后Monkey类就实现了行为与状态分离.Monkey类只负责自己的行为,MonkeyFSM作为Monkey的成员,负责状态调度.MonkeyFSM调用状态模式类的方法,状态模式类调用真实对象Monkey的方法.注意本文例子代码只是为了说明问题,并不能真正用于实际当中.其中Monkey与MonkeyFSM互相保存对方的指针,存在循环引用问题. 代码

cocos2d-x 游戏开发之有限状态机(FSM) (一)

cocos2d-x 游戏开发之有限状态机(FSM) (一) 参考:http://blog.csdn.net/mgphuang/article/details/5845252<Cocos2d-x游戏开发之旅>(钟迪龙) 基本上所有的软件都是有限状态机(finite-state machine,FSM).它是一个有向图,由一组节点和一组相应的转移函数组成.通俗点讲,它是一个事件驱动系统的模型,这个模型由有限数目的状态,若干输入和状态与状态之间转换的规则组成.在某一时刻,有一个或一组状态是FSM的当

【cocos2dx游戏开发】之 坐标系(二) convertToNodeSpace和convertToWorldSpace

游戏中经常会用到一些变换: 游戏中武器和角色在一个layer上,为了效率,会考虑将bullet, effect和 PhysicsParticle分别放到不用的层上,对应的层上使用batchnode来提高效率 武器和PhysicsParticleLauncher(粒子发射器)绑定,发射的时候,会向PhysicsParticleLayer的武器相同的位置上生成一个物理粒子特效 会经常用到convertToNodeSpace和convertToWorldSpace转换坐标 我们加三个sprite,r0

java游戏开发杂谈 - 有限状态机

在不同的阶段,游戏所运行的逻辑.所显示的界面,都是不同的. 以五子棋举例,游戏开始.游戏中.胜负已分,对应的界面和逻辑都不同. 在游戏中,又分为:自己下棋.对方下棋.游戏暂停.悔棋等多个状态. 再比如RPG游戏的人物,站立.行走.奔跑.攻击.死亡都是不同的动画, 发出一颗子弹,从出现,到往前运动.打到目标,或飞出屏幕,都是不同逻辑. 怎么实现这些效果呢? 程序里设定不同的状态,当前是什么状态,就执行什么逻辑. 这个就叫做:有限状态机! 是不是很简单,不要小瞧它,复杂的游戏功能都是靠它实现的. 接

h5牛牛平台架设游戏开发的架构总结(一) 客户端

有问题Q1446595067官网:h5.haozibbs.com或http:\www.qabaa.com [客户端]1.关于游戏引擎在15年3月开始准备做h5游戏的时候,首先遇到的问题就是引擎选型的问题.当时市面上的2d引擎主要有3个:白鹭egret,layabox和cocos2d-js.一方面,是因为我以前用cocos2d-x(c++)做了一年多的手游客户端,所以,很自然就选择了cocos2d-js.另一方面,是因为当时市面上其他两个引擎的成功项目还不多.cocos引擎的每一次版本更新,我们都

HTML5物理游戏开发 - 越野山地自行车(三)粉碎自行车

自上一章发布到现在已时隔四月,实在对不住大家,让大家久等了~话说不是我不关注我的博客,而是事情一多起来写博客的时间就少了.待到今日有空了,回头看了看自己以前写的文章,猛得发现已经四个月不曾写文章了,便只得叫声:"苦也~",我害怕本系列文章会拖得更久,于是立刻提笔,也好为本系列文章留个凤尾. 首先,大家来温习一下前面两篇里的内容吧: HTML5物理游戏开发 - 越野山地自行车(二)创建一辆可操控的自行车 http://blog.csdn.net/yorhomwang/article/de

Unity3D游戏开发软件的基本组成有哪些?

Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏.建筑可视化.实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎,下面跟大家介绍的是Unity3D游戏开发软件的基本组成有哪些,希望对大家有帮助. Unity3D游戏开发软件基本组成一:Scene场景 类似于Flash中的stage,用于放置各种对象. Unity3D游戏开发软件基本组成二:GameObject 可以携带各种Component(每个GameObject至

史上最全最完整的IOS 游戏开发 PDF电子书定制下载

<iOS 5游戏开发>作者:(新西兰)James·Sugrue著 页数:191 出版社:北京市:人民邮电出版社 出版日期:2012.08 简介:<iOS5游戏开发>是一本iOS5游戏开发的基础入门书.全书使用通俗易懂的简单实例,带领读者经历构建经典动作游戏的整个周期.读者在本书的阅读过程中,将经历从开发概念.规划设计一直到编写实际代码的全过过程.本书的每一章,都将演示游戏创建过程中的一个逻辑步骤,读者将在其中学习如何创建Sprite,用触摸屏.重力感应器和屏幕游戏棒控制玩家角色等-