转自: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 自适应多种分辨率的更多相关文章

  1. #region 自适应屏幕分辨率

            #region 自适应屏幕分辨率 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]        public ...

  2. Unity3D NGUI自适应屏幕分辨率(2014/4/17更新)

    原地址:http://blog.csdn.net/asd237241291/article/details/8126619 原创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅 本文链接地址: ...

  3. delphi 窗体自适应屏幕分辨率

    delphi 窗体自适应屏幕分辨率 这是个困惑我很长时间的问题,到今天终于得到解决了. 话说Delphi有个很强的窗体设计器,这一点让VC粉丝垂涎三尺而不可得.但是,Delphi里设计的窗体并没有自动 ...

  4. H5自适应屏幕分辨率大小

    说明: ①:H5自适应不同分辨率的设备,其实主要就一句 <meta name="viewport" content="width=device-width,init ...

  5. web前端响应式布局,自适应全部分辨率

    写phpd的我. 近期公司要弄个app关键是没有web开发,而我有比較闲,那就扛枪上阵吧. 响应式布局,web端的?php我一直都是用tp框架,对于web首先想到的是bootstrap框架.仅仅是简单 ...

  6. 高屋建瓴 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 ...

  7. android 图片大小适配,如何在不同屏幕上适配图片,如何设置可以自适应不同分辨率?

    android 图片大小适配,如何在不同屏幕上适配图片,如何设置可以自适应不同分辨率? Android为了适应不同的分辨率,需要将不同的图片放到不同的drawable目录下,分辨率的匹配规则如下:dr ...

  8. 【转】cocos2d-x 2.0版本 自适应屏幕分辨率

    http://codingnow.cn/cocos2d-x/975.html 我使用的版本是cocos2d-2.0-x-2.0.4,cocos2dx-2.0版本对多分辨率适配提供了很好的支持,使用起来 ...

  9. 如何让Android字体自适应屏幕分辨率

    在不同的分辨率下,Android字体大小怎么自适应分辨率的变化? 假设需要适应320x240,480x320分辨率.在res目录下新建文件夹values-320x240, values-480x320 ...

随机推荐

  1. [转载]如何打一手好Log

    如果项目上过线的话,那你一定知道Log是多么重要. 为什么说Log重要呢?因为上线项目不允许你调试,你只能通过Log来分析问题.这时打一手好Log的重要性绝不亚于写一手好代码.项目出问题时,你要能拿出 ...

  2. PHP漏洞全解(四)-xss跨站脚本攻击

    本文主要介绍针对PHP网站的xss跨站脚本攻击.跨站脚本攻击是通过在网页中加入恶意代码,当访问者浏览网页时恶意代码会被执行或者通过给管理员发信息 的方式诱使管理员浏览,从而获得管理员权限,控制整个网站 ...

  3. 1089-Duplicate Removal

    描述 The company Al's Chocolate Mangos has a web site where visitors can guess how many chocolate cove ...

  4. push 栈顶sp=sp-2 可以把立着的栈,向左侧倒下,那么形态就和反汇编时,内存的形态是一样的。小偏移的字节在前, 大的偏移字节在后

    push  栈顶sp=sp-2 可以把立着的栈,向左侧倒下,那么形态就和反汇编时,内存的形态是一样的.小偏移的字节在前, 大的偏移字节在后. 1 2 3 4 5 1 2 3 4 5

  5. 详解浏览器缓存机制与Apache设置缓存

    一.详解浏览器缓存机制 对于,如何说明缓存机制,在网络上找到了两张图,个人认为思路是比较清晰的.总结时,上图. 这里需要注意的有两点: 1.Last-Modified.Etag是响应头里的数据 2.I ...

  6. Java集合类之向量Vector

    package com.test; import java.util.*; public class Demo7_3 { public static void main(String[] args) ...

  7. 点点滴滴-NET下的常用框架

    刘冬的博客:http://www.cnblogs.com/GoodHelper/category/214139.html (Spring.net和Nhibernate) Kyo-yo  : http: ...

  8. URAL1635. Mnemonics and Palindromes(DP)

    链接 先初始化一下所有的回文串 再O(n*n)DP 输出路径dfs 刚开始存所有回文 ME了 后来发现用不着 改了改了OK了 数据还挺强 #include <iostream> #incl ...

  9. ADDED_TO_STAGE 多次被调用

    var mca:MovieClip=new MCA(); mca.addEventListener(Event.ADDED_TO_STAGE,addStageEvent); function addS ...

  10. String对象不可改变的特性

    1. 声明String对象 String s = "abcd"; 图1 2. 将一个字符串变量赋值给另一个String变量 String s2 = s; 图2 3. 字符串连接 s ...