我所遭遇过的游戏中间件---Scaleform

Scaleform帮助开发人员利用现代系统的三维硬件加速性能创建电影品质的菜单、游戏内HUD,动画纹理、迷你游戏以及移动游戏与应用。Scaleform作为一个可视化UI设计的中间件解决方案,其高性能已被充分证明,有了它,开发者通过Adobe Flash Studio可以高效率、低成本地创建富有现代感的GPU加速动画用户界面和矢量图形,而无需学习新工具的使用或者动画处理方法。Scaleform的另外一个名子叫GFX,在本文中有时使用Scaleform,有时会使用GFX,读者把它们当成一个东西就可以了.GFx为直接在Flash Studio创作游戏用户界面开辟了一条可视化开发途径,能够无缝衔接工作中的各个环节。

除了普通的UI界面显示,开发者还可以利用GFx在3D场景中显示Flash动画,将Flash画面映射到3D表面。同样,3D对象和视频也可以在Flash UI当中显示。由此,Scaleform GFx即可以作为单独的UI设计工具,也可以用来增强游戏前端界面设计功能。Scaleform已被大多数主流游戏引擎所集成。支持Scaleform GFx的游戏引擎中只需少量的代码便可以使用。最新版本的Scaleform GFx 4.0直持Flash的大部分AS 3.0脚本。并且可以通过Flash实现3D的游戏UI界面。

以上文字是从Scaleform的官网和宣传手册上扒下来的,而我这篇文章的题目是:"我所遭遇过的游戏中间件".对我来说"遭遇"这个词,用在Scaleform上是最恰当不过了.Scaleform无疑是我使用过的最痛苦,最纠结的中间件.我从来没有学过Flash,一直不会所谓的AS脚本.本来我以为需要Scaleform做的工作,仅仅是将其与我们项目中的引擎相结合.这一块工作不难,但这仅仅是个开始,当Scaleform用到具体的游戏项目中时,出现过各种奇葩的问题.下面将吐嘈下我的遭遇:

(1)Scaleform的存在意义
     使用FLASH做游戏界面,可以让界面更为灵活,易操作,易修改。但Scaleform并不是使用Flash的唯一选择.另外一种方式是:其是通过GDI处理Flash界面.将Flash图像通过GDI绘制出来后,保存到一个D3D的纹理结构中,再由引擎的D3D接口进行渲染。Scaleform的优势在于:能够直接调用引擎的D3D接口进行渲染,从而省去了GDI处理的这一步骤,所以能够提高游戏效率。我将在下一篇文章中写一下有关如何通过GDI处理Flash界面.

(2)Scaleform的版本升级
     Scaleform每个新版本都会修改它的一个渲染模块.如果我们项目中直接将它的渲染模块的lib拿来用,也无所谓了.但我们引擎中将所有与d3d相关的接口和资源做了层封装.所以我需要重写它的渲染模块,而它每次版本升级,我都要将渲染模块改一次,十分麻烦.从3版本开始,后来经历了4.0,4.2,它小版本更新的很频繁,我也不记得改过多少次的Scaleform渲染模块.

(3)与其官方的扯皮交流
      当开发碰到问题时,与其官方交流是件很头疼的事情.一般流程是:我先将问题描述一下,对方通常的回复是不明白我的描述,需要个DEMO.于是我改写其官方提供的DEMO,将问题的重现出来.经过漫长的等待后,对方提供解决方案.有时对方还是不清楚我DEMO的意思,我又得再发信息解释一下;有时问题会不了了之.最早之前,官方为我提供了可以发布问题的网站,但后来技术支持过期后,只能通过邮件联系.邮件联系的靠谱性比之前差远了,回复的时间周期也长很多.而且我总觉得和我做邮件联系的人是产品销售,而不是正规的技术支持.

举个最近一个与其官方扯皮的问题:我发现其Text文本框中显示的纹理资源,不能像普通控件中的纹理资源那样做矩阵的剪裁处理.同一个纹理资源,显示在文本框中是一个样子,显示在普通控件中是另外的样子.经过若干封邮件以及电话的扯皮之后,对方终于明白这个Bug了.说是要寻问其国外的开发人员,最终得到的答复是Text文本框里显示纹理资源就是这操行.问题从提出到得到最终答复,过了整整一个月,让我有种想打人的冲动.

(4)渲染的Bug
      Scaleform中碰到最多的Bug是有关渲染方面的.Flash是一种很开放的平台,美术可以做出非常多元化,多样性的Flash界面.总会出现在Adobe Flash播放器上播放正常的swf资源,在Scaleform的播放器上显示不一样.碰到这样的问题,只能求助于它们官方.官方的解决方案要么给我们临时修正的代码,要么提供另外一种制作资源的方式.

当然渲染方面的Bug不全是Scaleform的问题,也有Flash中的一些潜规则导致.但这些问题都会找到我头上,有时我觉得自己很无辜,我又没学过Flash,对Flash也没有丝毫兴趣,我所做的无非是将Scaleform封装了一下,集成到引擎中,所有该抛出的接口都抛出了.在使用过程中碰到什么问题,我真没有解决的道行.

(5)崩溃的Bug
      Scaleform是Autodesk的几款中间件中唯一一个提供源码的.但这代码真不是人看的,记得有个Autodesk的人给我讲,他们之所以对Scaleform提供源码,是因为他们整个公司只有一个主程在搞Scaleform,也只有他能看懂这源码.Scaleform大部分的崩溃都很难重现,而大部分崩溃堆栈都崩在其深深的函数调用中,有时会有深深的递归.这根本没办法查.而将这些崩溃堆栈发给他们官方,基本上不会给我们解决问题.之前使用的Scaleform是4.0版本,因为其后版本的开发环境最低是VS2008,而我们项目的开发环境还是VS2005.后来,没办法只能升级到4.2版本.Scaleform的lib是VS2008编译的,在VS2005中使用,还需要给VS2005安装一个补丁包.升级到4.2版本后,崩溃还算少了些,但也会有.

基本上所有Scaleform的崩溃都是内存原因.内存申请失败是最多的,这个也确实没办法彻底解决.Scaleform还有个潜规则是:flash的更新advance()需要与渲染display()相匹配.每次advance()时会申请一块内存,在display()时释放掉,如果不停的调用advance(),而不调用display(),迟早会崩在内存中.这个问题查了很久,当时发现将电脑锁屏后,过上几个小时解锁一看,游戏崩溃了.

(6)AS3脚本
      Scaleform不是所有AS3的脚本都支持.好在GFX会对其不支持的脚本都会输出LOD,其文档中也记录了所有不支持的脚本.脚本事件方面的坑不仅如此,由于我不懂AS脚本,这里的坑不归我管.此外Scaleform对AS脚本的解析效率比较差.

(7)字体
      字体的显示是个坑,需要确定加载哪个字库,字库的加载顺序如何,字库纹理的管理.开发者可以将某种字库打包成SWF文件,供GFX使用.需要特别注意字库的使用顺序,如果操作系统中有该字库,那么默认将使用系统字库.而我发现在有些机器上,若使用系统字库,渲染的字体会有明显的锯齿感.解决方法是修改GFX源码,调整字库的加载顺序.此外,还碰到个坑是,打包的字库显示的字体有大有小,字库中的某些文字显示不正常等,这与字库资源有关.

(8)多线程加载文件
      资源文件的多线程加载.Flash资源文件可以加载其他的资源,这时为了保证游戏的流畅,通常采用异步加载.这块还算好搞,照它的文档说明做就行.

(9)纹理剪裁
      纹理资源剪裁的实现,即将纹理的指定区域显示在控件上.为了减少纹理文件的数目,将若干小纹理合并成一幅大纹理文件.设置给GFX时,需要设置该纹理的显示区域.这个在它官方文档中没有太详细的说明,只提供了个设置纹理显示的矩阵,至于矩阵参数如何设置,我试了很久才试出来.

(10)鼠标右击
      对鼠标右击事件的响应,我就一直搞不明白为什么客户端说Scaleform的右击事件无影响,调到AS脚本中,就没反映了,我总觉得这是客户端逻辑的问题,我又不懂AS脚本.最终我的解决方法是,修改Scaleform的源码,将左中右三种事件统统设置为左击事件,然后篡改其点击位置的X坐标,使左中右三种事件的X坐标值对3的余数分别为0,1,2.

(11)序列帧动画
     不要在Flash中使用序列帧动画,因为序列帧动画会使Scaleform做像素拷贝处理,性能低下.还有些类似序列帧动画的功能,只有在开启了多线程渲染才能实现.

04-27 02:27