Starting。。。
Step By Step 。。。
C++博客
首页
新随笔
联系
聚合
管理
posts - 3, comments - 0, trackbacks - 0
【个人YY--游戏中状态切换的实现模型】
以下摘自【设计模式精解(GoF 23种设计解析附C++实现源码)】中关于状态机模式的介绍
有限状态自动机(FSM)也是一个典型的状态不同,对输入有不同的响应(状态转移)。通常我们在实现这类系统会使用到很多的Switch/Case语句,Case某种状态,发生什么动作,Case另外一种状态,则发生另外一种状态。但是这种实现方式至少有以下两个问题:
1)当状态数目不是很多的时候,Switch/Case可能可以搞定。但是当状态数目很多的时候(实际系统中也正是如此),维护一大组的Switch/Case语句将是一件异常困难并且容易出错的事情。
2)状态逻辑和动作实现没有分离。在很多的系统实现中,动作的实现代码直接写在状态的逻辑当中。这带来的后果就是系统的扩展性和维护得不到保证。
State模式就是被用来解决上面列出的两个问题的,在State模式中我们将状态逻辑和动作实现进行分离。当一个操作中要维护大量的case分支语句,并且这些分支依赖于对象的状态。State模式将每一个分支都封装到独立的类中。
在这里【设计模式精解(GoF 23种设计解析附C++实现源码)】中的代码那样,我只是解释一个模型,实现一个模型,用栈来管理游戏状态。你可以称呼它为游戏状态管理栈等。
说明:
由于考虑到游戏中的状态管理一般只有一个,故这里采用单键模式模型。
由于考虑到会增加复杂度,这里不考虑模板(按道理应该采用模板,以增加代码可重用性,当然,用了模板就不再是纯单键模式了)
好了,老样子,上代码
先看看定义代码
头文件STATEMANAGER.H
1
//
********************************************************************
2
//
STATEMANAGER.H 文件注释
3
//
文件名 : STATEMANAGER.H
4
//
文件路径: J:\CODING\游戏引擎\STATEMANAGER\
5
//
作者 : RIPPLE
6
//
创建时间: 2009/10/3 13:44
7
//
文件描述: 游戏状态管理栈类声明
8
//
*********************************************************************
9
10
#ifndef _H_STATEMANGER_H_
11
#define
_H_STATEMANGER_H_
12
namespace
ripple
13
{
14
//
********************************************************************
15
//
CStateManager 类注释
16
//
类名 : CStateManager
17
//
基类名称: NULL
18
//
命名空间: ripple
19
//
作者 : RIPPLE
20
//
创建时间: 2009/10/3 13:45
21
//
类描述 : 游戏状态管理类。一般游戏只会有一个状态管理,故采用单键模式管理
22
//
*********************************************************************
23
24
class
CStateManager
25
{
26
public
:
27
static
CStateManager
&
getSingleton();
//
返回引用,这步至关重要。
28
static
CStateManager
*
getSingletonPtr();
//
返回单键指针
29
30
virtual
~
CStateManager();
31
32
//
定义状态调用函数指针类型
33
typedef
void
(
*
StateCallFunc)();
34
35
//
定义状态结构
36
typedef
struct
tagState
37
{
38
tagState()
39
{
40
this
->
Update
=
NULL;
41
this
->
Next
=
NULL;
42
}
43
StateCallFunc Update;
//
各个状态调用的函数指针
44
tagState
*
Next;
//
下个函数状态的地址(如果有的话)
45
}
STATE;
46
47
void
Push(StateCallFunc func);
//
插入一个状态
48
BOOL Pop();
//
弹出一个状态
49
BOOL Process();
//
执行栈顶状态的更新函数
50
51
private
:
52
CStateManager();
53
STATE
*
mp_TopState;
54
static
CStateManager
*
ms_Singleton;
55
}
;
56
57
}
58
#endif
对应的实现,源文件STATEMANAGER.CPP
1
//
********************************************************************
2
//
STATEMANAGER.CPP 文件注释
3
//
文件名 : STATEMANAGER.CPP
4
//
文件路径: J:\CODING\游戏引擎\STATEMANAGER\
5
//
作者 : RIPPLE
6
//
创建时间: 2009/10/3 13:47
7
//
文件描述: CSteteManager游戏状态管理类实现
8
//
*********************************************************************
9
10
#include
<
windows.h
>
11
#include
"
StateManager.h
"
12
//
引用ripple命名空间
13
using
namespace
ripple;
14
//
初始化静态指针
15
CStateManager
*
CStateManager::ms_Singleton
=
NULL;
16
//
返回单键引用,必须返回引用,否则,会在返回时复制一次对象,将导致出错
17
CStateManager
&
CStateManager::getSingleton()
18
{
19
if
(NULL
==
CStateManager::ms_Singleton)
20
{
21
new
CStateManager();
22
}
23
return
*
CStateManager::ms_Singleton;
24
}
25
//
返回单键指针
26
CStateManager
*
CStateManager::getSingletonPtr()
27
{
28
if
(NULL
==
CStateManager::ms_Singleton)
29
{
30
new
CStateManager();
31
}
32
return
CStateManager::ms_Singleton;
33
}
34
//
构造函数
35
CStateManager::CStateManager()
36
{
37
this
->
mp_TopState
=
NULL;
38
CStateManager::ms_Singleton
=
this
;
39
}
40
//
析构函数
41
CStateManager::
~
CStateManager()
42
{
43
STATE
*
tmp;
44
while
((tmp
=
this
->
mp_TopState)
!=
NULL)
45
{
46
this
->
mp_TopState
=
this
->
mp_TopState
->
Next;
47
delete tmp;
48
}
49
if
(NULL
!=
CStateManager::ms_Singleton)
50
{
51
delete CStateManager::ms_Singleton;
52
CStateManager::ms_Singleton
=
NULL;
53
}
54
}
55
//
插入一个状态
56
void
CStateManager::Push(StateCallFunc func)
57
{
58
if
(NULL
!=
func)
59
{
60
STATE
*
tmp
=
new
STATE;
61
tmp
->
Next
=
this
->
mp_TopState;
62
tmp
->
Update
=
func;
63
this
->
mp_TopState
=
tmp;
64
}
65
}
66
//
弹出一个状态
67
BOOL CStateManager::Pop()
68
{
69
STATE
*
tmp
=
this
->
mp_TopState;
70
if
(NULL
!=
tmp)
71
{
72
this
->
mp_TopState
=
this
->
mp_TopState
->
Next;
73
delete tmp;
74
}
75
76
if
(NULL
==
this
->
mp_TopState)
77
{
78
return
FALSE;
79
}
80
81
return
TRUE;
82
}
83
//
执行栈顶状态的更新函数
84
BOOL CStateManager::Process()
85
{
86
if
(NULL
!=
this
->
mp_TopState)
87
{
88
this
->
mp_TopState
->
Update();
89
return
TRUE;
90
}
91
return
FALSE;
92
}
测试代码 TEST.CPP
1
//
********************************************************************
2
//
TEST.CPP 文件注释
3
//
文件名 : TEST.CPP
4
//
文件路径: J:\CODING\游戏引擎\STATEMANAGER\
5
//
作者 : RIPPLE
6
//
创建时间: 2009/10/3 13:59
7
//
文件描述: 测试CStateManager类是否可以正常使用
8
//
*********************************************************************
9
10
#include
<
iostream
>
11
#include
<
Windows.h
>
12
#include
"
StateManager.h
"
13
using
namespace
std;
14
using
namespace
ripple;
15
//
分别定义三个函数,在具体实现时,可以是个状态对象之类的。
16
//
每个函数中都会将自己弹出,已使得其他函数有机会执行
17
void
fun1()
18
{
19
cout
<<
"
call fun1
"
<<
endl;
20
CStateManager::getSingleton().Pop();
21
}
22
void
fun2()
23
{
24
cout
<<
"
call fun2
"
<<
endl;
25
CStateManager::getSingleton().Pop();
26
}
27
28
void
fun3()
29
{
30
cout
<<
"
call fun3
"
<<
endl;
31
CStateManager::getSingleton().Pop();
32
}
33
34
35
int
main()
36
{
37
//
将三个函数压入栈内
38
//
使用指针
39
CStateManager::getSingletonPtr()
->
Push(fun1);
40
//
使用引用
41
CStateManager::getSingleton().Push(fun2);
42
//
使用指针
43
CStateManager::getSingletonPtr()
->
Push(fun3);
44
//
循环调用,当栈空是返回FALSE
45
while
(FALSE
!=
CStateManager::getSingleton().Process())
46
{
47
}
48
return
0
;
49
}
运行结果:
1
call fun3
2
call fun2
3
call fun1
4
请按任意键继续. .
这只是个模型,大家可以在此基础上,编写更多更灵活的代码。
版权所有,转载请注明出处!
如果对本文有不解之处,可以联系本人(
yeduwu@163.com
)。或在此博客留言。
有不同见解者,亦可以通过上述通道联系本人。。欢迎指教。
posted on 2009-10-03 14:07
赖建全
阅读(211)
评论(0)
编辑
收藏
引用
所属分类:
【游戏框架基础】
只有注册用户
登录
后才能发表评论。
【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态!
网站导航:
博客园
IT新闻
BlogJava
知识库
博问
管理
<
2024年8月
>
日
一
二
三
四
五
六
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
本博客所有文章,均为本人所著!版权所有,转载请注明出处! 如果对本文有不解之处,可以联系本人(yeduwu@163.com)。或在此博客留言。 有不同见解者,亦可以通过上述通道联系本人。。欢迎指教。
留言簿
给我留言
查看公开留言
查看私人留言
随笔档案
(3)
2009年10月 (3)
文章分类
(2)
【C++相关】
【HGE研究】
【OGRE研究】
【软件工程相关】(1)
【游戏框架基础】(1)
文章档案
(2)
2009年10月 (2)
最新随笔
1. 东南融通无领导小组面试记
2. 【博客声明】
3. 昨天去大利嘉城买了新的显卡。
搜索
积分与排名
积分 - 2822
排名 - 1850
最新评论
阅读排行榜
1. 东南融通无领导小组面试记(1009)
2. 【博客声明】(181)
3. 昨天去大利嘉城买了新的显卡。(162)
评论排行榜
1. 东南融通无领导小组面试记(0)
2. 【博客声明】(0)
3. 昨天去大利嘉城买了新的显卡。(0)