原文出处:
https://blog.csdn.net/yixiao3660/article/details/54316348
https://www.jianshu.com/p/0d6787e31112
http://dualface.github.io/blog/2012/08/17/cocos2d-x-2-dot-0-multi-resolution/
cocos2d-x 2.0 提供一个极有价值的新特征: setDesignResolutionSize() 。
这个函数用于指定一个 OpenGL 视图,然后将这个视图映射到设备屏幕上。根据不同的设定,视图会自动缩放显示内容,为 cocos2d-x 自适应多种分辨率提供了基本支持。
不过要真正实现自适应分辨率,从场景设计、美术制作到程序编写,都需要遵循一套规范,才能极大减少工作量。
注意:本文假定游戏是横向显示的。
~
Cocos2d-JS屏幕适配
在Cocos2d-JS中,设计分辨率到设备分辨率的适配方案有5种,分别是:
- cc.ResolutionPolicy.EXACT_FIT
- cc.ResolutionPolicy.SHOW_ALL
- cc.ResolutionPolicy.NO_BORDER
- cc.ResolutionPolicy.FIXED_HEIGHT
- cc.ResolutionPolicy.FIXED_WIDTH
关于这五种设计模式的具体效果网络上已经有非常多的博客介绍了,甚至自己写个代码测试下就知道了,这里就不再赘述。
在Cocos2d-JS中设置适配方案的API是:
// 设置适配模式
cc.view.setResolutionPolicy(cc.ResolutionPolicy.FIXED_HEIGHT);
// 设置设计分辨率尺寸和适配模式
cc.view,setSesignReolutionSize(960, 540, cc.ResolutionPolicy.FIXED_HEIGHT);
// 设置资源分辨率到设计分辨率的缩放比例
cc.director.setContentScaleFactor(1);
Cocos Creator屏幕适配
实现方式
Creator的屏幕适配主要是放在Canvas组件上实现的,所以每当创建一个新的场景时,默认都会有个一个Canvas对象在层级管理器上,游戏内其它的节点都应该放在Canvas节点下,这样才能有效的在web浏览器上进行适配。
Canvas节点
Canvas组件
鼠标点选层级管理器上的Canvas对象,在属性检查器面板上会对应显示对象的组件信息。我们可以看到它默认添加了一个Canvas组件,并且勾选了“Fix Height”选项。
Canvas组件
关于Canvas组件,主要有三个属性:
- Design Resolution:主要设置游戏设计分辨率的尺寸,默认设置宽度960(W)高度640(H)。
- Fit Height:固定高度。
- Fit Width:固定宽度。
EXACT_FIT(非等比拉伸至全屏)
由于EXACT_FIT适配方案是将游戏内容非等比拉伸或缩放至全屏,实际效果通常都无法接受,所以在Creator中被废弃了,无法通过编辑器进行设置。如果非要使用,可以通过代码设置:
// 设置适配模式
cc.view.setResolutionPolicy(cc.ResolutionPolicy.EXACT_FIT);
但是可能会和Canvas冲突,所以可以试试禁用Canvas组件。这样处理后在web平台上可能会有问题,native上应该是可行的。
SHOW_ALL(等比显示整个场景内容)
showAll
在Creator上同时勾选“Fit Height”和“Fit Width”即可开启showAll适配模式。
这个适配方案其实也不是非常常见,我们公司早期都是使用这个方案。它的好处是不管屏幕比例如何,保证整个场景都是可见的,而且等比适配。但是总是在左右两边或者上下两边出现黑边。
NO_BORDER(等比拉伸到全屏)
NO_BORDER
和SHOW_ALL相反,在Creator上同时去除“Fit Height”和“Fit Width”的勾选即可开启noBorder适配模式。
这个适配模式是根据屏幕比例等比拉伸画面,有两种结果:
- 当高度拉满,宽度超出屏幕的时候,裁切宽度。
- 当宽度拉满,高度超出屏幕的时候,裁切高度。
它的好处是没有黑边,缺点是在不同的屏幕比例上,不能缺点到底是宽度裁切还是高度裁切。所以进行场景设计的时候有挺大局限性。
FIXED_HEIGHT(等比拉伸高度到全屏)
FIXED_HEIGHT
由于手机屏幕的局限性,通常游戏设置为横屏的,在横屏模式下,通常设置适配方案为固定高度,所以这也是Creator默认的视频方案。
在Creator中,只勾选Canvas组件的“Fit Height”即可开启fixedHeight适配模式。
它的好处是可以实现全屏,拉伸或者缩放高度为屏幕高度,宽度进行裁切。
FIXED_WIDTH(等比拉伸宽度到全屏)
FIXED_WIDTH
在Creator中,只勾选Canvas组件的“Fit Width”即可开启fixedWidth适配模式。
它的好处是可以实现全屏,拉伸或者缩放宽度为屏幕宽度,高度进行裁切。在竖屏模式下,通常设置适配方案为固定宽度。
明确自适应多种分辨率的需求
要让游戏在不同分辨率下都获得良好的用户体验,应该满足这几个要求:
- 背景图填满整个画面,不出现黑边;
- 背景图的主要内容都显示在屏幕上,尽可能少的裁剪图片(减少超出屏幕可视区域的部分);
- 如果背景图需要放大,尽可能减小放大的比例,避免放大后出现明显的模糊;
- 用户界面的文字标签、按钮在任何分辨率下都应该完整显示,并且容易交互。
上述需求实际上可以分解为两部分:
- 如何制作满足多种分辨率的背景图;
- 如何定位用户界面元素(标签、按钮等)。
~
制作适合多种分辨率的背景图
在开始制作背景图前,我们看看市面上各种设备(480 像素分辨率的老设备 2012 的游戏应该可以无视了)常见的像素分辨率(resolution in pixels):
Device | Width | Height |
---|---|---|
iPad | 1024px | 768px |
New iPad | 2048px | 1536px |
iPhone | 960px | 640px |
Android Phone 1 | 800px | 480px |
Android Phone 2 | 854px | 480px |
Android Phone 3 | 1280px | 720px |
Android Pad 1 | 1024px | 600px |
Android Pad 2 | 1280px | 800px |
经过几个游戏的实践,我们确定了几个背景图的分辨率:
-
2048px * 1536px
专门针对 New iPad,设计师的原稿也是这个尺寸。
-
960px * 720px
这个分辨率针对 iPhone 和 iPad 设备。在 iPhone 上 1:1 显示,上下各剪裁掉 40px。而在 iPad 上按 1.067 放大显示,正好填满整个屏幕,并且用户看不到模糊。从 2048px 的原稿导出 PNG 时,按照 0.469 比例缩小正好就是 960px * 720px。
-
854px * 480px
市面上的 Android 手机,854px * 480px 和 800px * 480px 是最常见的两种分辨率。2048px 的原稿按照 0.417 比例缩小,然后裁减掉上下多余部分就可以得到需要的 PNG 图片。
-
1280px * 800px
应付高分辨率的 Android 手机和平板设备,在各种分辨率下都可以获得很好的显示效果。2048px 的原稿按照 0.625 比例缩小,然后裁减掉上下多余部分就可以得到需要的 PNG 图片。
对于美术来说,背景图都按照 2048px * 1536px 的尺寸绘制。然后用脚本配合 ImageMagick 就可以自动导出四种分辨率的背景图片。
如果需要最大程度减小游戏的下载体积,那么可以只使用 960px * 720px 的素材。并且参考本文后面示例程序的做法,用一套素材应付各种不同的分辨率。
唯一需要注意的问题就是:确保画面中的主要内容在各种设备上都位于屏幕的可视区域中。
下面几个图展示 2048px 原稿在不同设备上的可视区域:
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
Photoshop 源文件下载地址: multires.psd
~
制作适合各种分辨率的用户界面元素
相比背景图,界面元素的制作只需要考虑一点:必须能够放置在最小的可视区域中。如下图界面底部有一排按钮,这些按钮在各种分辨率下都能完整显示:
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
在导出界面元素的 PNG 图片时,仍然使用脚本文件和 ImageMagick 按照特定比例自动缩放。
~
在各种分辨率的屏幕上定位界面元素
准备好了美术素材,接下来的挑战就是如何在不同分辨率的设备中定位界面元素。
为了解决这个问题,我们做了大量的尝试,最终找到一种可行的解决方案,而且使用起来非常简单。
虚拟分辨率
为了简化程序的开发,我们使用一个统一的虚拟坐标系来映射设备的屏幕。经过几个产品的实践,证明将屏幕宽度设定为 960pt 是很合理的。
特别注意:在讨论虚拟坐标系时,一律使用 pt(Point)作为单位,而不是 px(Pixel)。
下面的表格整理了各种设备分辨率与 960pt 宽度虚拟分辨率的对应关系:
Device | Width | Height | Virtual Width | Virutal Height | Scale |
---|---|---|---|---|---|
iPad | 1024px | 768px | 960pt | 720pt | 1.066666667 |
New iPad | 2048px | 1536px | 960pt | 720pt | 2.133333333 |
iPhone | 960px | 640px | 960pt | 640pt | 1.0 |
Android Phone 1 | 800px | 480px | 960pt | 576pt | 0.833333333 |
Android Phone 2 | 854px | 480px | 960pt | 540pt | 0.889583333 |
Android Phone 3 | 1280px | 720px | 960pt | 540pt | 1.333333333 |
Android Pad 1 | 1024px | 600px | 960pt | 562pt | 1.066666667 |
Android Pad 2 | 1280px | 800px | 960pt | 600pt | 1.333333333 |
根据参考点定位界面元素
在游戏初始化时,引擎就会根据设备的实际分辨率,自动设定好对应的虚拟分辨率,并且确定屏幕上的几个参考点:
Position | Value |
---|---|
left | 0pt |
right | 959pt |
top | 虚拟分辨率的高度 - 1 |
bottom | 0pt |
center x | 480pt |
center y | 虚拟分辨率的高度 / 2 |
有了参考点,定位界面元素就很简单了。例如一个按钮的原点(按钮图片中心点)相对于屏幕左侧 40pt,相对于屏幕底部 30pt。那么在不同分辨率的设备上,这个按钮和屏幕左下角的距离都是差不多的。
只要确保所有界面元素都使用参考点来定位,那么就绝不会出现在设备屏幕上看不到界面元素的情况。
~
示例程序
为了方便大家进行测试,本文的示例工程已经编译成 Windows 可执行文件。运行时可以用下列命令行启动以便测试不同分辨率:
命令行参数
|
|
或者双击 test_multires.cmd 直接查看不同分辨率的运行效果。
其他:
- 示例程序只包含按照 960px * 720px 制作的素材。
- 示例程序可执行文件以及源代码下载:multires.demo1.win32.zip
~
补充说明
本文前面描述了如何创建适合不同分辨率的图片,但最后的示例程序并没有考虑这一点,而是用一套素材就搞定了多种分辨率。实际上,我个人推荐使用一套素材适应多种分辨率,最多再为 New iPad 单独准备一套素材,这样可以显著减少工作量。
如果一定要按照不同分辨率使用不同的素材,那么在显示图片时需要调用 setScale() 调整图片的缩放比例。这样做的原因是 setDesignResolutionSize() 设置虚拟分辨率后,会指定一个全局的缩放比例,所有的图片即便是 scale = 100%,也会自动缩放。所以当图片尺寸和虚拟分辨率不一致时,我们就需要手动调整图片缩放比例了。
假设设备分辨率是 1280px * 720px,虚拟分辨率是 960pt * 540pt,背景图是 1280px * 800px。要确保背景图 1:1 显示在屏幕上,参考如下代码:
让图片按 1:1 显示在屏幕上
|
|
~
-EOF-