`
izuoyan
  • 浏览: 9222123 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

在游戏中使用面向对象的FSM

阅读更多

在游戏中使用面向对象的FSM

以前一直是用switch的状态机,因为J2ME没办法用太多类,现在改做c++了,终于可以试一试面向对象的状态机了,代码果然简洁了好多。参考的是《Programming Game AI by Example》第2章,大约改了下。首先要定义一个状态基类:



这是一个模板类,因为状态要对应不同的所有者,比如游戏状态的所有者是游戏类Game,而主角状态这里的entity_type就是主角类Hero。总之,状态对于状态拥有者实体是依赖关系。因为实体有很多种状态,所以要定义具体的状态子类,比如主菜单状态是游戏状态类的子类:



状态子类采用了单件模式,所以状态子类中不能存放对于拥有者实体来说是自有的数据,比如有很多士兵,那么士兵的状态子类中就不能存放生命值,只能存放在实体中,在状态类中通过实体的指针去访问。我觉得状态采用单件更清晰些,数据就在实体中维护吧,当然也许每个实体有一个对应的状态实例也有合适的使用之处。

然后需要定义状态机类:


状态机类也是模板类,道理一样,每种实体必须有一个对应的状态机类,状态机和实体是聚合关系,状态机保存了实体的指针,从而让状态可以访问实体。状态机和状态既有聚合关系也有依赖关系,状态机维护了当前状态,上一个状态,以及一个全局状态,从而对当前及全局状态进行Update和Render,并且通过 ChangeState管理状态的切换,切换状态时要调用旧状态的OnExit和新状态的OnEnter,设置第一个状态比较特殊,所以我加了 SetFirstState,只有对新状态的处理,原书中是直接设置,这样不会调用OnEnter了。

最后看实体怎么使用状态机,比如有一个Game类,首先他需要拥有一个状态机实例(也是聚合关系):
class Game
{
StateMachine<Game>* m_pFSM;
};

这个实例可以在Game构造时构造好:
Game::Game(void)
{
m_pFSM = new StateMachine<Game>(this);
}
析构时删除
Game::~Game()
{
delete m_pFSM;
}
游戏初始化时可设置第一个状态:
m_pFSM->SetFirstState(GSLogo::GetInstance());//这里是显示Logo

在Game Update和Render时分别调用状态机的Update和Render即可
void Game::Update(float dt)
{
...
m_pFSM->Update(dt);
...
}

void Game::Render(float dt)
{
...
m_pFSM->Render(dt);
...
}

那么状态的切换呢?是在状态子类中进行的,比如游戏从主菜单进入关卡,在主菜单状态的Update逻辑中:
void GSMainMenu::Update(Game* pGame, float dt)
{
...
if(Start按钮按下)
{
pGame->GetFSM()->ChangeState(GSLevelLoading::GetInstance());
}
...
}
游戏类有GetFSM方法让状态类得到状态机,切换状态时直接调用相应状态类的GetInstance得到唯一的状态实例

总结:
1)实体拥有一个状态机,实体通过状态机的Update和Render来实现不同状态下的逻辑和渲染
2)状态机指向他的拥有者实体,并且聚合了状态,状态机通过Update和Render来让当前状态执行逻辑和渲染,并且状态机提供了统一的状态切换流程,即先Exit前一状态,然后设置当前状态,并Enter新状态
3)每个实体对应一个状态基类(通过模板化),以及若干子类(通过继承模板基类),状态子类是实体状态的具体实现者,状态子类进行实际的Update和 Render,并且通过实体指针访问实体数据和方法,状态切换也是通过状态子类进行的,即各个子类是独立的,这样能很方便的增加和删除状态,只要修改前后状态的切换就可以了。

分享到:
评论

相关推荐

    vc下的状态机程序,演示程序1为"用过程编程的方法实现FSM的源程序代码";演示程序2为"用面向对象方法实现FSM的源程序代码

    状态机(Finite State Machine, FSM)是一种模型,用于描述系统或程序在不同条件下的...通过对这两个示例的学习,开发者可以更好地理解和运用状态机在实际项目中的应用,同时也能提升对过程编程和面向对象编程的理解。

    FSM_Project

    这种方式更易于扩展和理解,是面向对象设计的一个例子。 4. 使用状态机库或框架,如Boost.Statechart(C++),Automatons(Java)等,它们提供更高级的抽象,简化了状态机的实现和调试。 在实际应用中,FSM有广泛的...

    C++游戏设计案例教程

    其次,C++的面向对象特性在游戏编程中尤为重要。通过封装、继承和多态,我们可以设计出可复用、可扩展的游戏组件。例如,创建一个基类`GameObject`,然后派生出`Player`、`Enemy`等子类,这样就能有效地组织游戏对象...

    Unity3D仿仙剑回合制游戏源码.zip

    在仿仙剑游戏中,开发者可能会使用Unity的内置编辑器创建地形、建筑和环境物体,同时设计直观的UI元素,如血条、技能图标和状态面板,以提供良好的用户体验。 【源码分析】 "介绍.txt"可能是对游戏源码的简要说明...

    Java游戏编程(游戏开发与编程序列).rar

    1. **Java基础知识**:游戏编程首先需要掌握Java的基本语法、面向对象编程概念以及异常处理等。这是所有Java编程的基础,也是进一步学习游戏开发的前提。 2. **图形库和框架**:Java有许多用于游戏开发的库和框架,...

    游戏脚本高级编程附带资料.7z

    1. **C++游戏开发**:C++提供了面向对象的编程模型,使得游戏对象如角色、敌人、道具等可以被封装和抽象。同时,C++的模板和STL库能帮助开发者高效处理数据结构和算法,实现游戏的物理系统、图形渲染和内存管理。 2...

    fsm.js:JavaScript 中的有限状态机

    有限状态机(Finite State Machine, FSM)是一种...结合JavaScript的面向对象特性,`fsm.js` 可以成为构建模块化、可复用代码的强大工具。通过学习和使用`fsm.js`,开发者能够提升代码的结构化程度,提高软件的可靠性。

    Go-FSM-为Golang提供了一种轻量级有限状态机

    在Go-FSM中,你可以定义一系列的状态和它们之间的转换,以及每个转换所响应的事件。这使得代码结构清晰,易于理解和维护。 **设计原理:** Go-FSM的设计基于Golang的面向对象特性,它允许通过接口来定义状态和事件...

    FSM_状态机_

    这种方式更加面向对象,可以更好地封装状态的逻辑,但实现起来相对复杂。 在"FSM_状态机_"的class8_FSM文件中,可能包含了状态机的核心实现,例如一个`State`基类和几个继承自`State`的子类,每个子类代表一个特定...

    有限状态机游戏编程

    本主题将深入探讨如何在C++中使用面向对象编程技术来实现有限状态机,特别是在游戏场景中的应用。我们将通过一个具体的例子——"Mao"类及其相关状态和消息系统来阐述这一概念。 首先,我们来看“人物类”的实现。在...

    fsm状态机设计相关资料

    3. 面向对象编程:利用类和对象来实现状态机,每个状态对应一个类实例。 四、状态机应用 1. 控制逻辑:如微处理器指令执行、自动售货机控制等。 2. 网络协议:TCP/IP协议栈中的各个状态管理。 3. 游戏逻辑:角色...

    fsm:Go中的FSM实施

    1. **状态**:FSM中定义的一组可能存在的状态,每个状态代表系统的一种行为模式。 2. **初始状态**:FSM开始执行时所处的状态。 3. **事件/输入**:触发状态转换的外部刺激或用户操作。 4. **转换**:定义了当某个...

    C++ 魔塔 游戏 源代码

    首先,C++是面向对象的编程语言,它允许我们通过类和对象来构建复杂的游戏世界。在魔塔游戏中,每个角色、怪物、道具等都可以看作是一个对象,它们各自拥有特定的属性(如生命值、攻击力)和行为(如移动、攻击)。...

    Java2游戏设计(PDG).rar

    在游戏设计中,面向对象的编程(OOP)是至关重要的,因为它允许我们将游戏的不同元素(如角色、敌人、道具等)封装为独立的对象,每个对象都有自己的属性和行为。 其次,Java的图形库Swing和AWT在构建游戏UI时非常...

    游戏脚本高级编程光盘文件1

    2. **面向对象编程**:游戏脚本通常采用面向对象编程(OOP),通过类和对象来组织代码,实现模块化和可重用性。理解类、对象、继承、封装和多态等概念对于编写高效的游戏脚本至关重要。 3. **游戏逻辑控制**:编写...

    Visual.C++经典游戏程序设计/罗伟坚编著

    1. **C++基础**:首先,读者需要具备C++基础知识,包括语法、面向对象编程(OOP)概念,如类、对象、继承、多态等。C++的强大功能和灵活性使得它成为游戏开发的首选语言之一。 2. **Windows API**:Visual C++通常...

    传智播客贪吃蛇游戏源代码

    8. **对象导向编程**:在源代码中,蛇、食物等可能被设计为类,使用面向对象的方法来组织代码,提高可读性和复用性。 9. **调试与优化**:通过阅读源码,可以学习如何使用调试工具找出并修复程序错误,以及如何优化...

    这是一些我自己做的游戏!

    在C++游戏开发中,这些游戏可能使用了一些关键的技术和库。例如,可能使用了DirectX或OpenGL进行图形渲染,SDL(Simple DirectMedia Layer)或SFML(Simple and Fast Multimedia Library)处理输入、音频和窗口管理...

    Java游戏编程原理与实践教程(文档地址+源代码)

    在游戏开发中,更常使用的是JavaFX或LibGDX这样的专业游戏框架,它们提供了绘制2D和3D图形、处理输入事件、音频播放等功能,大大简化了游戏开发工作。 四、游戏循环 游戏的核心是游戏循环,它负责处理用户的输入、...

    vc++游戏源码包1

    2. **面向对象编程(OOP)**:在游戏开发中,OOP用于组织和结构化代码,如游戏对象(角色、敌人、道具等)可以设计为类,通过继承和多态性来实现复杂的游戏逻辑。 3. **游戏框架**:源码包可能包含自定义的游戏框架...

Global site tag (gtag.js) - Google Analytics