Cocos2d-x 2.0 自适应多种分辨率
转自:http://dualface.github.io/blog/2012/08/17/cocos2d-x-2-dot-0-multi-resolution/
cocos2d-x 2.0 提供一个极有价值的新特征: setDesignResolutionSize() 。
这个函数用于指定一个 OpenGL 视图,然后将这个视图映射到设备屏幕上。根据不同的设定,视图会自动缩放显示内容,为 cocos2d-x 自适应多种分辨率提供了基本支持。
不过要真正实现自适应分辨率,从场景设计、美术制作到程序编写,都需要遵循一套规范,才能极大减少工作量。
注意:本文假定游戏是横向显示的。
明确自适应多种分辨率的需求
要让游戏在不同分辨率下都获得良好的用户体验,应该满足这几个要求:
- 背景图填满整个画面,不出现黑边;
- 背景图的主要内容都显示在屏幕上,尽可能少的裁剪图片(减少超出屏幕可视区域的部分);
- 如果背景图需要放大,尽可能减小放大的比例,避免放大后出现明显的模糊;
- 用户界面的文字标签、按钮在任何分辨率下都应该完整显示,并且容易交互。
上述需求实际上可以分解为两部分:
- 如何制作满足多种分辨率的背景图;
- 如何定位用户界面元素(标签、按钮等)。
制作适合多种分辨率的背景图
在开始制作背景图前,我们看看市面上各种设备(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 原稿在不同设备上的可视区域:







制作适合各种分辨率的用户界面元素
相比背景图,界面元素的制作只需要考虑一点:必须能够放置在最小的可视区域中。如下图界面底部有一排按钮,这些按钮在各种分辨率下都能完整显示:

在导出界面元素的 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 可执行文件。运行时可以用下列命令行启动以便测试不同分辨率:
命令行参数
# 如果没有指定命令行参数,则默认使用 960px * 640px 的屏幕分辨率。
multires.demo1.win32.exe
或者双击 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 显示在屏幕上
const CCSize& winSize = CCDirector::sharedDirector()->getWinSize();
float scale = CCEGLView::sharedOpenGLView().getScaleX();
CCSprite* bg = CCSprite::create("bg.jpg")
bg->setPosition(ccp(winSize.width / , winSize.height / ));
bg->setScale(1.0f / scale); // 这里重置图片缩放比例,确保图片按 1:1 显示在屏幕上
addChild(bg);
-EOF-
Cocos2d-x 2.0 自适应多种分辨率的更多相关文章
- #region 自适应屏幕分辨率
#region 自适应屏幕分辨率 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public ...
- Unity3D NGUI自适应屏幕分辨率(2014/4/17更新)
原地址:http://blog.csdn.net/asd237241291/article/details/8126619 原创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅 本文链接地址: ...
- delphi 窗体自适应屏幕分辨率
delphi 窗体自适应屏幕分辨率 这是个困惑我很长时间的问题,到今天终于得到解决了. 话说Delphi有个很强的窗体设计器,这一点让VC粉丝垂涎三尺而不可得.但是,Delphi里设计的窗体并没有自动 ...
- H5自适应屏幕分辨率大小
说明: ①:H5自适应不同分辨率的设备,其实主要就一句 <meta name="viewport" content="width=device-width,init ...
- web前端响应式布局,自适应全部分辨率
写phpd的我. 近期公司要弄个app关键是没有web开发,而我有比較闲,那就扛枪上阵吧. 响应式布局,web端的?php我一直都是用tp框架,对于web首先想到的是bootstrap框架.仅仅是简单 ...
- 高屋建瓴 cocos2d-x-3.0架构设计 Cocos2d (v.3.0) rendering pipeline roadmap(原文)
Cocos2d (v.3.0) rendering pipeline roadmap Why (the vision) The way currently Cocos2d does rendering ...
- android 图片大小适配,如何在不同屏幕上适配图片,如何设置可以自适应不同分辨率?
android 图片大小适配,如何在不同屏幕上适配图片,如何设置可以自适应不同分辨率? Android为了适应不同的分辨率,需要将不同的图片放到不同的drawable目录下,分辨率的匹配规则如下:dr ...
- 【转】cocos2d-x 2.0版本 自适应屏幕分辨率
http://codingnow.cn/cocos2d-x/975.html 我使用的版本是cocos2d-2.0-x-2.0.4,cocos2dx-2.0版本对多分辨率适配提供了很好的支持,使用起来 ...
- 如何让Android字体自适应屏幕分辨率
在不同的分辨率下,Android字体大小怎么自适应分辨率的变化? 假设需要适应320x240,480x320分辨率.在res目录下新建文件夹values-320x240, values-480x320 ...
随机推荐
- shell中的内建命令, 函数和外部命令
转自shell中的内建命令, 函数和外部命令 Shell识别三种基本命令:内建命令.Shell函数以及外部命令: (1)内建命令就是由Shell本身所执行的命令. 有些命令是由于其必要性才内建的 ...
- javascript技巧合集
转http://www.blogjava.net/zhaochengming/archive/2010/04/09/317837.html http://www.cnblogs.com/fxgachi ...
- SQL分组查询GroupBy
一.分组查询1.使用group by进行分组查询在使用group by关键字时,在select列表中可以指定的项目是有限制的,select语句中仅许以下几项:〉被分组的列〉为每个分组返回一个值得表达式 ...
- [状压dp]HDOJ4539 郑厂长系列故事——排兵布阵
中文题,题意不再赘述 对于“?”这一格,它所能攻击到的(曼哈顿距离为2的) 前方的 即“√”的四个位置 那么与此格有关的即它前方两行(即状压这两行) 首先预处理每行能满足的: i 和(i<< ...
- STL--自定义类型的排序
STL的排序太坑了,尤其是在VS2010上重载sort函数的第三个比较参数的时候. invalid operator < 这个错在写多关键字排序的时候就没有停止过. 本来想查书解决,结果各种重载 ...
- GridView 根据要求显示指定值
最近在写一个小项目用来练手恢复一下功力的,在Users表中有一个用户字段是状态,我使用"0"表示启用,“1”表示禁用, 存到数据库中, 由于之前有一段时间没写代码了,所以有点生疏了 ...
- Android EditText如何去除边框添加下划线
(一)问题 之前的自定义EditText只能显示高度不超过屏幕高度的文本内容,继续增加内容会出现如下问题: (二)原因分析 下部(超出屏幕高度的部分)没有继续画线,也就是说横线没有画够,那么一定是循环 ...
- ORA-28001: the password has expired
大早上正式库提示: Oracle提示错误消息ORA-28001: the password has expired 解决办法: 1.利用SYSDBA权限登陆: 2.查看账户信息:select user ...
- bzoj3262
三维裸的做法是一维排序,剩下树套树,可我好像还没写过树套树先说cdq分治吧,先对一维排序,相当于原来修改询问里的时间线在这上面分治.划分,计算前半部分对后半部分的影响,显然可以按第二维的顺序维护树状数 ...
- BZOJ_1609_[Usaco2008_Feb]_Eating_Together_麻烦的聚餐_(动态规划,LIS)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1609 给出一串由1,2,3组成的数,求最少需要改动多少个数,使其成为不降或不升序列. 分析 法 ...