西西软件下载最安全的下载网站、值得信赖的软件下载站!

首页编程开发其它知识 → 对游戏中的各种状态进行统一管理维护代码分享

对游戏中的各种状态进行统一管理维护代码分享

相关软件相关文章发表评论 来源:西西整理时间:2013/1/23 8:35:37字体大小:A-A+

作者:西西点击:0次评论:1次标签: 状态管理

设备状态管理器绿色免费版
  • 类型:系统优化大小:490KB语言:中文 评分:5.0
  • 标签:
立即下载

说到状态管理,很多人第一时间想到的,就是状态机了,根据不同的游戏状态,调用不同的游戏过程,来进行游戏更新和渲染 。一般来说,我们都是在游戏更新和渲染过程里面,用一个大大的 switch 语句,来确定当前的游戏状态,如果状态数量少的话,倒没所谓,但是,一旦游戏状态多起来了,全部状态都塞到一个过程里面,阅读起来,就变得非常困难了,维护起来的话,就更加难上加难 。

那么,有没有什么比较好的办法,对游戏中的各种状态进行一个统一的管理呢 ? 至少,看起来,代码不会那么乱七八糟(笑),答案显然易见的,废话不说,我们直接上代码 :

 1 //-----------------------------------
 2 // 游戏状态祖先类
 3 //-----------------------------------
 4 
 5 class IGameState
 6 {
 7     //
 8     // 初始化
 9     //
10     virtual initialize( ) = 0;
11 
12     //
13     // 销毁
14     //
15     virtual shutdown( ) = 0;
16 
17     //
18     // 更新
19     //
20     virtual update( ) = 0;
21 
22     //
23     // 渲染
24     //
25     virtual render( ) = 0;
26 
27     //
28     // 暂停
29     //
30     virtual pause( ) = 0;
31 
32     //
33     // 恢复
34     //
35     virtual resume( ) = 0;
36 
37     //
38     // windows 消息处理
39     //
40     virtual msgproc( UINT _msg, WPARAM _wParam, LPARAM _lParam ) = 0;
41 };

我们创建一个 IGameState 纯虚类,抽象出一个游戏状态应有的各种行为和能力,然后,我们再来实际创建不同的游戏状态 :

 1 //-----------------------------------
 2 // 创建一个游戏介绍状态
 3 //-----------------------------------
 4 
 5 class CIntroGameState : public IGameState
 6 {
 7 };
 8 
 9 //-----------------------------------
10 // 创建一个游戏主菜单状态
11 //-----------------------------------
12 
13 class CMainMenuState : public IGameState
14 {
15 };
16 
17 //-----------------------------------
18 // 创建一个系统设定状态
19 //-----------------------------------
20 
21 class CSystemSetting : public IGameState
22 {
23 };
24 
25 // ...

最后一行注释里面的三个点是告诉我们,我们可以创建更多的游戏状态,而不是仅仅限制在上面三个状态,然后,我们的游戏状态,理所当然地就交给我们的游戏对象来进行维护啦 :

 1 //-----------------------------------
 2 // 游戏对象类
 3 //-----------------------------------
 4 
 5 class CGame : public IGameState
 6 {
 7     // CGame 可以通过切换 game state 来更新绘制不同的状态
 8 
 9     setGameState( IGameState * _state ){ cur_game_state = _state; }
10 
11     // 返回 cur_game_state 可以得知当前正在更新绘制哪一个状态
12 
13     IGameState * getGameState( void ){ return cur_game_state; }
14 
15     // 保存游戏状态
16 
17     pushGameState( IGameState * _state ){ game_state.push( cur_game_state ); cur_game_state = _state; }
18 
19     // 恢复游戏状态
20 
21     popGameState( void ){ cur_game_state = game_state.top( ); game_state.pop( ); }
22 
23 private:
24 
25     // 当前正在运行哪一个状态
26 
27     IGameState * cur_game_state;
28 
29     // 游戏状态堆栈, 用于游戏状态的回溯
30 
31     stack< IGameState * > game_state;
32 };

为了让各种游戏状态对象之间可以互相交互,我们必须提供一些全局的函数以及全局的对象,当然,如果各位读者们有更好的方法,请留言给我哈(笑) :

 1 //-----------------------------------
 2 // 全局对象和函数
 3 //-----------------------------------
 4 
 5 CGame _game;
 6 
 7 CGame * getGame( void ){ return & _game; }
 8 
 9 IGameState * intro_game = new CIntroGameState( );
10 IGameState * main_menu = new CMainMenuGameState( );
11 IGameState * sys_setting = new CSystemSetting( );

然后就是我们的游戏初始化过程:

 1 //-----------------------------------
 2 // 程序入口点
 3 //-----------------------------------
 4 
 5 void main( void )
 6 {
 7     // 初始化游戏
 8 
 9     _game.initialize( );
10 
11     // 游戏初始化后进入介绍界面
12 
13     _game.setGameState( intro_game );
14 
15     // 运行游戏
16 
17     while( true )
18     {
19         _game.update( );
20         _game.render( );
21     }
22 
23     // 销毁游戏
24 
25     _game.shutdown( );
26 }

最后,重头戏到了,我们每一个游戏状态对象,只管负责自己的更新和渲染,如果需要通知游戏对象进行状态切换,那么可以看看下面代码 :

 1 class CIntroGameState : public IGameState
 2 {
 3     update( )
 4     {
 5         // 如果在播放游戏介绍画面时, 用户按下了 Esc 按键
 6 
 7         if( ESC_key pressed )
 8         {
 9             // 切换到游戏主菜单状态
10 
11             getGame( )->setGameState( main_menu );
12         }
13     }
14 };
15 
16 class CMainMenuGameState : public IGameState
17 {
18     update( )
19     {
20         // 如果在游戏主菜单里面, 用户点击了系统设置按钮
21 
22         if( sys_setting_button clicked )
23         {
24             // 切换到系统设置状态
25 
26             getGame( )->setGameState( sys_setting );
27         }
28     }
29 };
30 
31 class CSysMenuGameState : public IGameState
32 {
33     // ......
34 };

---------------------------------------------------------------------------------

OK,这些代码,应该不需要太多的描述了,看起来也很容易懂 。

最后,请大家不要吝啬自己的技术,把自己用过的管理游戏状态或者游戏对象的方法都说出来,大家互相学习学习哈,因为如果我们死死将知识揣在口袋里面,那么那些没有掌握到这些知识的人,又非常迫切需要这些知识的人,就会非常着急,甚至会退缩,这样子,我们就当真成了罪人咯嘻嘻 。

    相关评论

    阅读本文后您有什么感想? 已有人给出评价!

    • 8 喜欢喜欢
    • 3 顶
    • 1 难过难过
    • 5 囧
    • 3 围观围观
    • 2 无聊无聊

    热门评论

    最新评论

    发表评论 查看所有评论(1)

    昵称:
    表情: 高兴 可 汗 我不要 害羞 好 下下下 送花 屎 亲亲
    字数: 0/500 (您的评论需要经过审核才能显示)
    推荐文章

    没有数据