Egret是个好东西,整套workflow用下来,特别顺手,对于移动端游戏的开发来说,选择Egret无疑是个不二的选择。
当然,小学语文课上老师就教过一种写作手法,欲扬先抑,笔者今天倒过来,来说说Egret的若干局限性。
笔者从接触Egret到现在用Egret作为主职开发工具,已经整整一年时间了,有些嘈已经吐过了,但有些嘈还在咽着。当然,哪个工具框架没有局限性呢,但是这些局限性还是要让Egret初学者明了一下。
•1.3D旋转
3D旋转虽然已经脱离了Egret这个2D引擎的范畴了,但是,让我们这些怀念flash的rotationX,rotationY,rotationZ这三个属性的人来说,在实现某些酷炫效果上,无疑是大打折扣的啊。其实早在去年7月份时,笔者就已经跟Egret官方沟通过,沟通结果是不会支持3D旋转。
此时,有些有经验的开发者就会说:可以用scaleX和scaleY来实现3D的上下左右的旋转。其实笔者一直都是用这种方法来实现假的3D旋转的,但是,这并不是真正意义上的3D旋转,3D旋转是会产生透视效果的,即近大远小。
笔者就纳闷,为何要不支持3D旋转呢,对于OpenGL和WebGL来说,应该是原生就支持的;对于Canvas2D来说,可以通过矩阵来实现,然后想问,为何Egret实现了skew(斜切),却不实现perspective(透视)。其实是有原因的,因为Canvas2D的transform是能操作一个3*3的矩阵,然而3*3的矩阵并不能实现透视的转换,少了Z轴,所以这是由Html5的Canvas2D间接导致Egret的局限的局限。
•2.渲染
因为Egret不仅仅是一款Html5游戏引擎,实则是一款js游戏引擎,现能支持3个平台(Html5/Android/iOS),如果不理解可以去笔者的另一篇博文里看看(Egret随笔-Egret浅入浅出),里面阐述了一下Egret的机制。真因为这是一款多平台的引擎,所以它牺牲了很多性能方面的东西,这个牺牲就表现在js代码和native代码的比率上,这个比率越大,那么游戏的性能就会越差(提现在卡或者不卡上,通俗讲法)。看过Egret浅入浅出的话,你就会知道Egret的机制其实就是为底层抽象出了很多context来供js调用,这种抽象带来了好处也带来了坏处。
一个好处是能直接适配目前所持有Canvas2D环境,因为Canvas2D所提供的渲染很基础,并没有很强的封装;还有一个好处是方便了Egret对其js代码方面的维护,直接把引擎源码一发布就能得到最快捷的更新。
然而坏处就是前面所说的比率上升了很多,Egret为了是3平台上能发布相似度达到最大程度的效果,这样,js代码率就会很高,导致一些很核心且运行率十分高的代码段都需要用js来实现,且不说V8引擎有多牛掰,总是要翻译一次的吧。
正因为如此,使得native连跑个物理引擎都会费劲,因为js版本的物理引擎在移动端运行的效率都很低下。
个人建议是部分能学习一下cocos2d-x的做法,把某些核心的东西,开发者基本不会去动的代码,在native上封装到native代码上,这样的话native上能达到更高的渲染体验,(反正native模板不也是随着Egret主版本更新的嘛!)。
•3.跨平台背后的不平等
笔者目前所在的公司,要求把游戏做3平台导出并同步上线。本来笔者觉得这个应该挺简单的呢,用Egret官方的support模板一套就好了,可是项目做深了,你就会发现其实并没有那么简单,为此笔者学习了Android和iOS的开发(比较基础的现学现用的那种程度),就是为了满足上头给的需求,比如接入facebook社交、ga分析、flurry分析、admob广告之类的很多功能,这些功能的实现当然不是为了说Egret的局限性,其实上述这些对于每一种跨平台游戏引擎来说都是一样的,都要借助本地代码来实现。
笔者在开发过程中,也和Egret官方的开发者聊了很多,才知道Egret对于3平台的重视程度是有优先级的:Html5>Android>iOS。因为Html5是直接参与代码编写和调试的项目,且是目前市场占有率最高的发布形式,所以首先要保证它的正确性,而后因为Android的设备比率比iOS高很多,所以iOS被落在很后面,在某些实现上也是比较滞后和不重视。果然,笔者在开发过程中,发现问题从多到少正好是iOS>Android>Html5。
举个例子吧,其实对于iOS方面的问题,Egret官方的某开发者已经被笔者问烦了,bug有点多,都是某开发者直接给hotfix版本给笔者的。但是对于iOS上的Graphics代码,一个基础的图形模块,在2.0.x开始就坏了,笔者测试了很多次,发现x、y参数会失效,导致所有由Graphics绘制的可视对象都叠在屏幕的左上角,最后某开发者直接说这事他们内部另一某开发者在重构Graphics模块给弄坏了,那笔者也只能认了。他也给了暂时的解决方案,就是改用像素图来代替,然而由于平台差异,在iOS和浏览器里,直接把一张很小的图拉伸到很大,它会做一次线性插值像素填充,说得通俗点就是图失真了,比如你给了一张1*1的红色(0xFF0000)的图片,要拉伸到3*1大小,那么,它会这样“帮你”填充像素:0x000000, 0x800000,0xFF0000,而不是三个都是0xFF0000,所以没办法,只能用九宫格来填充。
再举个例子,是热更新的不统一,虽然现在都给出“差不多”一致的热更新方案,但是明显在iOS和Android上的实现程度是不一样的,所以为了达到一致性,笔者一直采用自己实现的热更方式,就是为了让他们调用同一个接口。
对iOS的不公平待遇,是令笔者最恼火一个局限,Egret做的完整的产品,既然已经推出了iOS平台的支持,就应该好好地做好这方面的服务,不能因为用户群少而对它不平等待遇。在我们开发者来说,我们做的产品,是信得过Egret才选择了它,所以希望Egret官方能重视这一点。
•4.位图操作
Egret没有为开发者提供位图方面的操作api,这个问题是很多开发提及的,但Egret就真的没提供。这些开发者应该很多都是从Flash转过来的,钟情于BitmapData类,但是Egret的BitmapData类仅仅是一堆数据,它在web和native以不同形式存在着,然而这堆数据提供的接口差异比较大,难以整合。还有就是如果用js来操纵这对数据,那效率想必是很低下的,一般这种封装都是在底层通过c/c++来直接操纵的,所以不提供js位图操作接口。
如果你是在是钟情于Flash的BitmapData类,那建议你看一下Egret的源码,自己实现一下,当然这种方法仅在web发布有效。
•5.多语言开发
对于一个游戏引擎来说,怎么能少了多语言开发呢,难道不打算推向国际了么?在笔者目前的开发中,就是要多语言开发的,只是Egret目前还在国内市场打拼,并没有对多语言提供什么便捷操作,所以目前为止,开发者需要手动进行多语言操作。
多语言开发其实并不难,至少比多平台开发简单。语言差异主要体现在了文字和部分文化上,对于文化差异,我只能忽略了,但是文字部分还是需要翻译的。
多语言在程序中体现无非就是文本和图片了,笔者模仿Android的多语言控制,降所有的语言相关文本全部收集到语言包(lang.json)中,并放在resource目录,然后翻译一份国语版,命名为resource_zh,或者日语版resource_jp,然后修改egret tools的源码,在publish命令中添加-lang命令,命令参数为语言字符串,然后将resource自动拷贝到发布目录。然而,这只能用在Html5版里,对于Android和iOS是行不通的,因为涉及到version control的东西,牵扯太多东西了,所以最然并没有什么卵用。
希望Egret早日把多语言开发并入主分支吧。
•6......
想到再说。
•结尾
对于Egret的局限性,也只是笔者站在自己立场所提出的,随着你的Egret的深入了解,你肯定会发现更多。当然,Egret团队会虚心接纳你的意见或者建议,我们都能更好得为Egret的发展而提供一点点帮助。