一、在屏幕尺寸和分辨率变化不一的情况下,UI如何做机型适配?
UI是应用的门户,相对来说IOS分辨率较为简单,但考虑到retina与非retina,iphone与ipad,ipadmini,则IOS的分辨率也要支持4种,而Android机型是典型的碎片化,屏幕从小到3.5寸大到到6.5寸都有手机,再加上的android平板,其分辨率屏幕组合多达几十种。
UI做机型适配,需要很多的取舍,事实上第一个取舍就是:我们不需要真正地支持所有的机型的所有分辨率,而相反,我们把主力放在支持市场占有率Top15以内的机型。从目前国内手机品牌型号占有率来看,这几乎只有两三个牌子:三星、小米和华为。在切掉了大部分碎片机型的时候,我们手上的分辨率还是很多,从而无论在人力或是时间成本上,我们都是不可能完成所有的分辨率的资源。所以UI设计还得有进一步的优化。
UI的核心功能是:交互,同时对于富UI的游戏来说,它还要好看,所以本着这两个主要目标,又要配合所有的屏幕,我们考虑过两个极端的方案,但最终选择的是把两者结合:
方案一是简单粗暴的缩放:即在不同分辨率不同机型上对UI进行缩放,使之占满全屏。但这个方案一提出来就立刻被自己否决了,简单缩放的问题在于:在手机上好好的UI,在平板电脑上惨不忍睹,按钮其大无比,操作十分不舒服,同时由于UI资源的图片大小精度不够,还会出现大片大片的马赛克,也非常难看。
方案二则是力求效果上的完美:一套UI资源,为每个分辨率的屏幕做一套UI布局,布局时可以适当的缩放原始资源,这个方案能达到最好的UI效果,但一种分辨率一种布局缺点是工作量还是太大,时间和人力成本过高。
我们最终采用的方案三则是结合了方案一和二的优点,但同时也牺牲了一定的美感:
美术制作一套UI图片资源,但按分辨率区间把屏幕分为:低、中、高三档,每一档对应若干组分辨率的机型,然后为低、中、高分区制作不到的布局(Layout),在具体的布局区间内,这个布局文件会自动根据分辨率进行等比缩放,并进行居中,两边无UI处留黑。这样做的结果是用多套布局适配到所有的分辨率,同时提供可接受的操作感和外观。
二、图片存储格式选择,JPG?PNG?ETC!
国内市面上的手游,很多都是PNG或JPG格式的纹理,但这两者最终加载到内存显存时,都必须解码成原始像素,其大小就可能是磁盘空间的数倍甚至十几倍,这样的大小对美术制作资源的限制势必更大,稍有不慎就会导致内存占用过大,从而导致程序无故闪退(俗称OOMKill).
我们考虑了大部分常用的纹理格式,但最终的选择是基于KTX格式的ETC:
1.PNG,无损压缩,压缩比也不错,缺点:需要加载时解码,占用内存大
2.JPG,有损压缩,优势是压缩比高,缺点:有损,加载时需要解码,占用内存大
3.TGA无压缩格式,优势是无解码,加载速度快,缺点是磁盘占用空间大,占用内存大
4.PVR,优点是支持的编码格式最完善,工具和库均最为完善,,示例和文档也较为齐全,缺点是它的库大而全
5.KTX,优点是支持ETC1和ETC2编码,格式和ktx库均很简单,且库还是有Kronos官方提供的。(虽然它的etc编解码用的是爱立信实验室的实现)
最终我们选择ktx的理由是因为它的库足够简单,而且有OpenglES官方组织撑腰。当然这些只是图片格式的选择,具体的编码器选用的是ETC1,选择ETC1的原因为:
1.硬件加速的解码格式,为OpenglES2.2标准所支持,这就意味着Android2.2以后的手机都支持etc1
2.比肩DXT的图片压缩方式,其压缩后的图片只有原图的1/6,但效果却比占原图1/2大小的16位图片要好出实在不止一倍,甚至在大部分情况下,看不出和压缩前原图的区别。
需要注意的是ETC1本身也是有损压缩,且并不支持Alpha通道,而对于2D游戏来说,基本上就没有几张图是不带Alpha的,所以我们又折回来,扩展了cocos2dx引擎,为它加上了双ETC纹理以支持Alpha。
在不远的将来,在OpenglES3.0普及之后,ETC2势必成为未来手游的最主流纹理图片格式,因为它不但将支持更丰富的图片格式,带alpha支持和单通道纹理的支持(单通道可以用来做alpha、光照、mask等等),同时它提供更多的压缩方式以提高纹理压缩质量。
随带说一句,美术的图片大小我们要求做成2的幂,不足大小的碎图需要进行接合成一张大图,然后里面的小图引用则通过修改纹理坐标来实现,这图小图拼大的做法有个学名,叫AltasTexture,不知怎么翻译为好。
虽然OpenglES2.2标准里明确规定了可以支持非2的幂的纹理,但碎图片一方面可能会导致在GPU里被拉成2的幂,从而多吃内存,更重要的是它会导致渲染过程中频繁地切换纹理(glBindTexture),增加不必要的cpu\GPU同步次数,从而大大降低渲染效率。另外,对我们来说,选择2的幂做为制作限制,还有一个必要的原因:etc压缩算法针对的是4x4的像素块,所以纹理的大小是2的幂且大于2的情况下,自然就能满足此要求。且事实上一般游戏项目里也不太可能存在小于4x4的图片资源(mipmap低阶除外)。
三、2D动画,逐帧导出VS碎图拼帧
应该说在2D动画制作这一点上,Cocostudio对Flash动画导出表面上显得风风光光,极大的增加了资源重用,但实际上却是乏善可呈,它逐帧导出的flash动画,无异于给手游团队挖了一个大坑,就等着你跳。
设想一下,为每帧渲染出一张单独图片的后果是什么,假定游戏在战斗过程中一共可能出场10个角色,每个角色可能有4个动画,每个动画给它30帧,每帧的大小为260*150,按cocostudio的整法,这些动画每个会被导出成一张AltasTexture,大小大约为1024*1024,而1024*1024的图片(rgba),在内存中的图像大小可以达到4M,光这几个角色加动画,其内存占用就可以达到160M=10人*4动画*4M,这还不算它上技能特效、UI,和其它逻辑层的内存占用,而如果你每个动画还带有4个方向,那么恭喜你,这个数字还要再大4倍,实际上就即便是160M这个数字,也足以让这个游戏在很多低端手机上无故地因为内存用尽而闪退。
事实上,如果你仔细观察一下逐帧导出的动画,你就会发现这种导出方式有多浪费,图(1)展示了一个15帧的角色抓耳挠腮的动作。
图(1)
这个角色可以很自然的分割为头,背,双上臂,双前臂,双手掌,弯曲的双前臂,弯曲的双上臂。只需要把这些小图片组装成一个完整的人(单帧),再由帧组合成动画就可以了。这样资源占用比逐帧渲染要小得多。事实上图(1)所示的动画,仅仅如图(2)中所有部件组成的35个动画中的一个而已。
(图2)
在内存受限的手机上,拼装动画是唯一可行的优化方案,至于这个动画帧怎么去拼,则至少有两种方式:
第一种方式是纯粹的把图切碎,每帧使用小图拼出不同的大图来,这种拼碎帧的方式要求美术有较好的图片拆分能力,并且有耐心去拼接。缺点是有较大的美术工作量,比较费时。优点则是资源量小,任何相要的效果,只要肯花时间,都是可以做出来的。这一种自由拼图方式的动画,cocostudio是不提供支持的。所以如果要做,需要自己制作相关的动画制作工具、数据存储格式和加载渲染库。
而第二种拼装方式则2D骨骼动画,2D骨骼动画在Cocostudio里提供了里支持,具体也是把每一帧切成不同的块,进行拼装,所不同的是它的图块依附于骨骼,图片本身不做任何变换,且不同的帧所接受的图片数目也要和第一帧相同。2D骨骼动画简化了动画制作过程,同时可以在制作动作类游戏的时候加上诸如反向动力学等计算。但它的缺点却是一般来说,效果要比第一种拼装方式要粗糙一些,PVZ2的动画就都是使用的2D骨骼动画。
原文链接:https://www.f2er.com/cocos2dx/343814.html