您好,欢迎访问三七文档
实现游戏GUIGUI哪一个商业游戏没有GUI呢?估计现在很难找到这样的例子了。相反,现在的GUI越来越人性化,考虑的越来越多,甚至在某些游戏中已经喧宾夺主,俨然让GUI成为了游戏中必不可少的一环。人们往往在游戏的片头之后,接触的第一个就是GUI。一个游戏的GUI如何,对于这个游戏来说是异乎重要的。比较差的GUI能让人由于要从成屏幕的乱七八糟信息中寻找一个小小的消息而疯掉,而比较好的GUI,往往简洁明快,却又醒目……GUI我们在这里不准备谈GUI设计的艺术。而是准备讨论一下GUI的编码。GUI的编码有什么好讨论的?无非就是响应用户输入……确实是,GUI就是一种交互的手段,它一定会获取用户输入,同时一定会向外输出,但是编码中,我们就会遇到很多超乎理论的实际问题了。GUI多说一句,Windows的GUI,MFC和WTL的组织方式应该算作是最好的参考资料。GUI将被谁调用?如何调用?对比MFC,GUI有两种调用方式,一种是消息式,一种是查询式。消息式即是由GUI系统给出每个GUI元素的消息,然后由每个GUI元素写下自己对这些消息的处理方式。这就类似于Windows消息循环。查询式即是GUI系统改变GUI元素的状态,然后由游戏逻辑查询这些GUI元素的状态,并根据状态完成游戏逻辑。GUI层次问题由此可见,GUI的层次应高于引擎本身,但低于游戏逻辑,也属于引擎层的外围部分。GUI从引擎获取信息和指令,并将这些指令转化为逻辑,最后影响游戏的方方面面。GUI的几类不同设计GUI目前的设计主要包括插件扩展的和脚本扩展的两个思路。插件扩展即是高层留下抽象的GUI接口,需要的时候,从这些接口派生并写下自己的逻辑。脚本扩展主要出现在利用现有的编辑器开发中,编辑器提供一定数量的GUI,用户通过脚本为这些GUI添加逻辑,甚至将这些GUI组合成新的GUI。GUI的基础:EVENT类比Windows,GUI最关键的问题是消息流从何而来到哪里去。消息流有些人称作Message有些人称作Event,但是概念都是一样的。GUI系统所接收的消息一般主要是:键盘鼠标等标准输入设备的消息;其他操作系统消息;控件消息,即控件之间相互发出和接收的消息;EVENT消息流GUISystem,也就是GUI系统的总管,一般而言,必须接管系统消息和输入设备消息。GUISystem本身也是一个消息的处理者,他从底层的输入模块等模块得到消息之后,判断哪些GUI元素该处理这些消息,然后向这些GUI元素派发消息。例如GUISystem应获得鼠标击键消息,然后查询当前鼠标点击到了哪个GUI元素上,最后调用这个GUI元素的EventHandler。EVENT消息流其他的控件消息则就由各个控件自己做逻辑的时候产生并派发给其他控件了。例如当点中本来被覆盖的窗口B的时候,这个B窗口需要翻上来,将原本覆盖它的窗口A盖住。这样就需要给A窗口发一个“丧失焦点”的消息。控件消息一般就是这样产生并处理的。EVENT处理:HANDLER有了消息就要处理,一般而言,我们把发送的消息称为Event或者Msg,相应的,处理消息的一般称为Processor或者HandlerEvent系统最一般的都会包括EventHandler和Event本身。多一点的话,可能会包括Dispatcher(消息调度器)、BroadCaster(群发器)。而Handler是Event最核心的部分。它的设计决定了整个GUI处理的形态。HANDLER的设计Handler的设计一般分为类EventHandler,和对象EventHandler。类EVENTHANDLER举个例子:classButton:publicGUIElements{virtualboolHandle(Event&evt)=0;};在逻辑中写:classXButton:publicButton{boolHandle(Event&evt){/*dosthhere*/}};类EH的一个缺点是:每一个控件都需要写一个类,但要重载的函数却只是寥寥数个。最后发现写了很多很多类,这样很不利于管理,程序也臃肿很多。一个游戏成百上千个GUI元素难道要写成百上千个类?不可想象!类EVENTHANDLER最关键的不是类多了带来的臃肿和压力,而是为了要生成这些类,几乎无法采取一个统一的方式来完成抽象工厂。如果像OGRE那样,就需要为这成百上千控件每个都单独写一个Factory,这个成本就高了……因此类EventHandler经常与“查询式”一起使用,以降低成本。这像什么?MFC!类EVENTHANDLER类EventHandler仅适用于描述大量控件都具有的“共性”的东西,不适用于描述“个性”。它适用于描述Button按下去外观会变的“共性”,不适用于描述Button实现各自逻辑的“个性”。对象EVENTHANDLER对象EventHandler,举个例子:classGUIElement{typedefbool(*PFN_PROC)(Event&arg);PFN_PROCm_pHandler;}对象Event即是为每个对象都挂接各自不同的Handler,这个Handler可以是函数指针也可以是像OGRE那样的Listener。其实大部分情况下只要是一个函数指针就完全够用了。对象EVENTHANDLER对象EventHandler非常适合于描述每个控件所具有的个性,但是却非常不适合描述某类控件所具有的共性。HANDLER的设计一般而言,现在的Event设计基本上都会为类式的和对象式的都留下空间。诸如向CEGUI就是这样子。但是GUI作为外围系统,同样其设计应当紧凑而避免复杂,做成像CEGUI那样过度设计的,就会由于对象式过于复杂而导致运行时成本下降。游戏的效率就是这样一点点被消耗的,如果每个系统不注意反省自己,那么最后的结果就只能是使得游戏整体帧率下降。HANDLER的设计一个核心问题是,看你用不用得到这个东西,如果用得到,没有困难制造困难也要上,如果用不到,那就还是“到下个版本中添加”吧。几个主要的组件Button、Panel和StaticArea一般是三个主要的组件。其他组件基本都可以由这三个生成出来。作为GUI元素,Panel是与众不同的,在很多设计中,Panel被称为Container,属于GUI容器而不是元素。容器和元素的区别是容器可以有子元素或容器、但是元素没有。在现在的一些设计中,已经抛弃了容器和元素的概念,元素也是容器,也可以有子元素,这样相对就更加方便一些,少了一些概念。
本文标题:实现游戏GUI
链接地址:https://www.777doc.com/doc-3346416 .html