Game Framework的两种实现方式

转载自:http://www.bennychen.cn/2011/04/game-framework%e7%9a%84%e4%b8%a4%e7%a7%8d%e5%ae%9e%e7%8e%b0%e6%96%b9%e5%bc%8f/


游戏框架尽量用接口,将功能解耦。libgdx就是如此。


一年多前,曾经写过一篇关于Game Engine Framework的文章,当时基本上是为了巩固并加深对framework的理解。最近又做了一些关于framework的工作,对于framework的实现方式又有了些新的认识。虽然我现在做的已经完全不是game了,不过方式对于game也同样适用。

这篇文章主要希望通过一些示例性的C++代码介绍game framework的两种实现方式。首先,我还是搬出一年多前的那篇文章里的game流程图,以下的一些代码也主要基于这张图实现。对于图的细节在这里不再赘述,可以再去翻看之前的那篇文章。

FoC of Game

1.通过继承

这是一种最传统的方式了,之前我一直使用这种方式。基本上是提供一个基类,基类封装并决定了整个程序控制流,同时基于该控制流,基类提供了一系列的接口(在C++里是虚函数),以供继承类override,并实现定制化的行为。就像下面的这个Game类,run函数决定了整个程序的执行逻辑,同时initialize,update,render等非纯虚函数则提供了接口以供用户定制并实现具体Game想要的行为。

1// 通过继承来实现的framework
2class Game
3{
4public:
5    voidrun()
6    {
7        m_isQuit =false;
8        initialize();
9        while( !m_isQuit )
10        {
11            handleInput();
12            update();
13            render();
14        }
15        destroy();
16    }
17     
18protected:
19    virtualvoid initialize() {}
20    virtualvoid update() {}
21    virtualvoid render() {}
22    virtualvoid destroy() {}
23    virtualvoid onMouse( Mouse mouse ) {}
24    virtualvoid onKeyboard( Keyboard keyboard ) {}
25     
26private:
27    voidhandleInput()
28    {
29        Event e;
30        while( popEvent( &e )  )
31        {
32            switch( e.type )
33            {
34            caseEVENT_QUIT:
35                m_isQuit =true;
36                break;
37            caseEVENT_MOUSE;
38                onMouse( e.mouse );
39                break;
40            caseEVENT_KEYBOARD:
41                onKeyboard( e.keyboard );
42                break;
43            default:
44                break;
45            }
46        }
47    }
48     
49private:
50    boolm_isQuit;
51};

在上面的代码中,我把实现全部写在了类的定义头文件中,在这里只是为了省事,在现实中你最好还是分开在.h和.cpp文件中。而且在这里,Game类还可以做的更多,我这里只是为了说明实现方式,所以依照前面的流程图而尽量让它简单。另外,不要纠结这段代码中的Event,Mouse,Keyboard等几个类和popEvent方法,它们只是我为了将故事说得更圆满一点而假象出来的几个类,我想你应该能猜到它们是用来干嘛的。

基于此framework,一个具体的游戏只需要重写这些虚函数就可以了,像下面的这些代码。

1class ConcreteGame :public Game
2{
3private:
4    voidinitialize()
5    {
6        // do some real initialization
7    }
8     
9    voidupdate()
10    {
11        // do some real update
12    }
13     
14    voidrender()
15    {
16        // do some real rendering
17    }
18 
19    voiddestroy()
20    {
21        // do some real destroy
22    }
23     
24    voidonMouse( Mouse mouse )
25    {
26        // handle mouse event
27    }
28     
29    voidonKeyboard( Keyboard keyboard )
30    {
31        // handle keyboard event
32    }
33};
34 
35int main()
36{
37    ConcreteGame mygame;
38    mygame.run();
39    return0;
40}

2.通过Delegation模式

前一种方法有一个缺点,就是将程序的控制流和具体行为紧耦合在了一起,而且还必须使用继承,不易于扩展。现代软件设计的一些方法告诉我们,要尽量使用接口,且尽量使用组合而非继承。Delegation模式就可以帮我们达到这一目的。

何为Delegation模式,wiki上的解释一语中的:

Delegation is the simple yet powerful concept of handing a task over to another part of the program.

Delegation将一些task委托给程序的另外一部分来处理,以达到了行为使用者和具体行为的松耦合。

以下是通过Delegation模式重新实现的framework。

1// 通过Delegation模式来实现的framework
2class GameDelegation
3{
4public:
5    virtualvoid initialize() {}
6    virtualvoid update() {}
7    virtualvoid render() {}
8    virtualvoid destroy() {}
9    virtualvoid onMouse( Mouse mouse ) {}
10    virtualvoid onKeyboard( Keyboard keyboard ) {}
11};
12 
13class Game
14{
15public:
16    Game( GameDelegation *gameDelegation )
17    {
18        m_gameDelegation = gameDelegation;
19    }
20     
21    voidrun()
22    {
23        m_isQuit =false;
24        if( m_gameDelegation == NULL )
25        {
26            return;
27        }
28         
29        m_gameDelegation->initialize();
30        while( !m_isQuit )
31        {
32            handleInput();
33            m_gameDelegation->update();
34            m_gameDelegation->render();
35        }
36    }
37     
38private:
39    voidhandleInput()
40    {
41        Event e;
42        while( popEvent( &e ) )
43        {
44            switch( e.type )
45            {
46            caseEVENT_QUIT:
47                m_isQuit =true;
48                break;
49            caseEVENT_MOUSE;
50                m_gameDelegation->onMouse( e.mouse );
51                break;
52            caseEVENT_KEYBOARD:
53                m_gameDelegation->onKeyboard( e.keyboard );
54                break;
55            default:
56                break;
57            }
58        }
59    }
60     
61private:
62    boolm_isQuit;
63    GameDelegation *m_gameDelegation;
64};

基于此framework,当需要具体实现一个游戏的时候,只需要实现GameDelegation接口即可,然后将Game类的GameDelegation设置为你所实现的具体的ConcreteGameDelegation类,代码如下。

1class ConcreteGameDelegation :public GameDelegation
2{
3public:
4    voidinitialize()
5    {
6        // do some real initialization
7    }
8     
9    voidupdate()
10    {
11        // do some real update
12    }
13     
14    voidrender()
15    {
16        // do some real rendering
17    }
18 
19    voiddestroy()
20    {
21        // do some real destroy
22    }
23     
24    voidonMouse( Mouse mouse )
25    {
26        // handle mouse event
27    }
28     
29    voidonKeyboard( Keyboard keyboard )
30    {
31        // handle keyboard event
32    }
33};
34 
35int main()
36{
37    ConcreteGameDelegation myGameDelegation;
38    Game mygame( &myGameDelegation );
39    mygame.run();
40    return0;
41}

最近我正好做了一些iOS上开发的研究,发现Delegation在iOS框架中被普遍使用。比如,iOS中的每个应用程序对应的是一个UIApplication类,为每一个UIApplication,开发人员必须要实现一个特定的UIApplicationDelegate,并将它指定给当前的应用程序(在main函数中通过UIApplicationMain函数指定,或者是在nib文件中绑定)。在这个UIApplicationDelegate类中,开发人员就需要重写诸如didFinishLaunchingWithOptions,applicationWillTerminate这样的方法,就类似与上面game framework中的initialize,destroy等方法。当然iOS框架要复杂很多,它还用到其它一系列的设计模式,有空研究些这样设计是非常有趣的。

图片来自于这篇苹果官方关于iOS中delegation的介绍:http://developer.apple.com/library/ios/#documentation/General/Conceptual/DevPedia-CocoaCore/Delegation.html


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值