[转]quick-cocos2d-x 多分辨率适配详解
多种分辨率的适配一直都是一个蛋疼的问题,各家公司可能都有自己的一套方案。今天我为大家介绍的是我们在多款游戏里实践后的解决方案,相对来说成本和实现难度都较低,效果也很不错。
多种分辨率适配的原理
因为横屏和竖屏的原理完全相同,所以本文先以竖屏为例,后文再说明横屏的处理。
制作一张 640×960 像素的图片,并传入设备查看:
- 查看时将图片缩放到合适大小,确保图片左右两边正好填满整个屏幕。
- 在不同分辨率的设备上,这张图片的显示效果差异体现在图片上下是否能够填满屏幕。
例如在 480×800 的设备上,这张 640×960 图片会被缩小为 480×720 像素来显示,左右填满屏幕,上下出现黑边。
在一些常见分辨率中,图片的显示效果:
缩放比例 = 屏幕像素宽度 / 图片像素宽度
- 屏幕尺寸 _640x960 像素,缩放比例 100%,正好填满整个屏幕
- 屏幕尺寸 640×1136 像素,缩放比例 100%,上下有黑边
- 屏幕尺寸 _480x800 像素,缩放比例 _75%,图片缩放后尺寸 _480x720 像素,上下有黑边
- 屏幕尺寸 _480x854 像素,缩放比例 _75%,图片缩放后尺寸 _480x720 像素,上下有黑边
- 屏幕尺寸 768×1024 像素,缩放比例 120%,图片缩放后尺寸 768×1152 像素,无黑边,但图像上下有裁剪(超出屏幕无法显示)
上下有黑边是肯定不好看的。那要保证填满屏幕,我们只需要将图片做得更大一点就可以了。图片高度的计算:
图片高度 = 屏幕像素高度 / (屏幕像素宽度 / 图片像素宽度)
按照这个公式,上述分辨率,图片的高度应该是:
- 屏幕尺寸 _640x960 像素,图像高度 960 像素
- 屏幕尺寸 640×1136 像素,图像高度 1136 像素
- 屏幕尺寸 _480x800 像素,图像高度 1066.67 像素
- 屏幕尺寸 _480x854 像素,图像高度 1138.67 像素
- 屏幕尺寸 768×1024 像素,图像高度 853.3 像素
其中最大值是 1138.67,考虑制作方便,高度取值 1140。也就是说 640×1140 的图片可以完全填满上述各种分辨率的屏幕。
在游戏里我们也可以借鉴这种方式。不管屏幕多大,反正我把游戏场景的宽度都给定死,就是 640。那么在不同设备上,要处理的问题就是场景高度的变化。以此为基础,适配多种分辨率的原理就很简单了:
- 游戏场景的宽度固定。
- 根据屏幕分辨率计算出游戏场景的高度。
- 使用较大的背景图,确保任何分辨率下都可以填满屏幕。
- 根据场景高度来定位显示内容。
虚拟分辨率
为了和设备屏幕分辨率区别开,我将游戏里使用的分辨率称为“虚拟分辨率”。
在“虚拟分辨率”中,坐标系的尺寸是“点”。后文称为“Point,缩写为 pt”。
根据前面计算图片高度的公式,在不同设备上,虚拟分辨率的宽度是固定的,而高度则不同。在 quick-cocos2d-x 里要实现这个虚拟分辨率的自动计算,只需要使用“FIXED_WIDTH”屏幕缩放策略。
打开 config.lua 文件,指定以下代码即可:
CONFIG_SCREEN_WIDTH = 640
CONFIG_SCREEN_HEIGHT = 960
CONFIG_SCREEN_AUTOSCALE = "FIXED_WIDTH"
CONFIG_SCREEN_WIDTH
和CONFIG_SCREEN_HEIGHT
定义了一个“虚拟分辨率”的参考值。- 游戏引擎根据参考值和
CONFIG_SCREEN_AUTOSCALE
设置,最终计算出在设备上使用的“虚拟分辨率”。
我们在 quick-cocos2d-x 启动时可以看到如下信息:
# CONFIG_SCREEN_AUTOSCALE = FIXED_WIDTH
# CONFIG_SCREEN_WIDTH = 640.00
# CONFIG_SCREEN_HEIGHT = 1066.67
此处的 CONFIG_SCREEN_HEIGHT
就由引擎做了调整,不再是 config.lua 里指定的参考值。最终,CONFIG_SCREEN_WIDTH
和 CONFIG_SCREEN_HEIGHT
就是游戏场景的虚拟分辨率尺寸。
内容的定位
quick-cocos2d-x 在引擎初始化的时候就算好了一些特定的坐标值,我们在游戏里可以用这些坐标值当做“参考点”来定位我们的内容。
# display.width = 640.00
# display.height = 1066.67
# display.cx = 320.00
# display.cy = 533.33
# display.left = 0.00
# display.right = 640.00
# display.top = 1066.67
# display.bottom = 0.00
display.width
,display.height
是虚拟分辨率的尺寸display.cx
,display.cy
是屏幕中心的坐标display.left
,display.right
,display.top
,display.bottom
是屏幕四个角的坐标
有了这些“参考点”,定位内容就很简单了。
例如要在屏幕右上角放置一个按钮图片,用以下代码即可:
local x = display.right - 100 -- 图片中心在屏幕右边往左 100pt
local y = display.top - 100 -- 图片中心在屏幕顶部往下 100pt
local sprite = display.newSprite("Button.png") -- 创建 sprite 对象用于显示图片
sprite:setPosition(x, y) -- 设置这个 sprite 对象的坐标
要在屏幕上显示一张背景图,确保图片中心和屏幕中心重叠:
local bg = display.newSprite("Background.png")
bg:setPosition(display.cx, display.cy)
所以只要合理使用“参考点”,我们游戏里的所有内容都能做到自动适应任何分辨率。
可视区域
前面在用内容填充屏幕时,有一个问题就是不同设备上,同一张图片能够被用户看到的内容是不同的。在 640×1136 这样的设备上,用户可以看到全部内容。而在 768×1024 这样的设备,上下被裁剪掉的内容就比较多。
能够被用户看到的内容区域,就是场景的可视区域。这个区域正好就是“虚拟分辨率”的尺寸。
由于不同设备的可视区域高度有变化,我们在设计 UI 时,就要考虑到最小可视区域问题。按照 FIXED_WIDTH 的算法,目前市面上的所有设备里,最小可视区域应该就是 iPad 了,其“虚拟分辨率”只有 640×853。
但如果死板的把 UI 局限在最小可视区域中,不同设备上的体验就不好,因为上下太多屏幕空间被浪费了。所以在 UI 设计时,就要让一些内容是“动态尺寸”的。
例如下面的界面中,底部的工具栏是固定高度,蓝色区域的高度则是根据虚拟分辨率计算的:
local toolbarHeight = 130 -- 工具栏高度 130
local padding = 50 -- 所有的留白 50
-- 计算出内容区域的高度
local contentHeight = display.height - toolbarHeight - padding
由于 quick-cocos2d-x 支持“九宫格”图片,所以这类高度不确定的区域,制作起来没有任何难度,稍稍练习一下就能掌握。
美术素材的准备
在理解原理后,最后一个难点就是美术素材的制作了。
美术素材主要有两类:背景图、场景元素。
对于背景图,设计师按照 1536×2280 来制作,原因是:
- 640×960 的参考虚拟分辨率,背景图最大尺寸是 640×1140,翻倍后是 1280×2280。
- 考虑到可能会为 iPad 单独做优化,所以图片宽度放大到 1536。因为 Retina iPad 的屏幕分辨率是 1536×2048。
背景图制作时,也要考虑到最小可视区域问题,确保背景的主要内容在不同分辨率下都能够被看到。如果是比较复杂的背景,也可以分为多层叠加。
例如一张背景是由远景和近处的人物构成。那么可以将远景和人物分为两张图。远景屏幕居中显示,人物则以程序进行定位,确保任何分辨率下,人物的头部都能完整显示的。这样可以取得很好的显示效果。
场景元素的制作要麻烦一些。首先,确保最小可视区域中,能够容纳一个场景的所有内容。其次,在更大屏幕上,一些场景元素(主要是 UI)要可以拉伸。基本原则是按照 640×960 翻倍,也就是 1280×1920 的尺寸来制作。一些需要拉伸的元素则做成九宫格,或者多张图的拼接。
设计师按照 1280×1920 的分辨率制作出效果图,开发人员再根据实际情况,对部分元素进行相对定位。
设计师的图像按照 100% 尺寸导出后,还需要用 Texture Packer 等工具做进一步处理。这里的处理除了打包,最主要的就是将图像缩小为 50%。这样 1536×2280 的背景图就变成了 768×1140;1280×1920 的场景就变成了 640×960。
最终,我们仅用一套素材,就适应了所有设备。并且为 Retina iPad 和其他超高分辨率设备留下了优化的空间。
针对 iPad 的优化
由于 iPad 的屏幕宽度超过了 640,所以整个场景都会被放大一点。这样带来了两个问题:
- 有一些轻微的模糊。
- 场景上下的内容被裁剪较多。
要解决这个问题有两种方案:
- 以 768×1024 为参考虚拟分辨率。
- 单独为 iPad 设置虚拟分辨率。
第一种方法最简单。只要按照前文所述,重新计算出新的图片尺寸,并以此为基础让美术制作就可以了。不过缺点也很突出:
- 图片的尺寸大大增加。背景图需要制作为 1536×2728,场景元素的参考分辨率是 1536×2048。这直接导致最终生成的图片尺寸变大,占用的内存增多。光是背景图,就要增加 20%。
- 只有在 iPad 上才是不缩放显示,在其他所有设备上,场景都会缩小后显示。这对于一些文字内容,在手机上阅读起来就比较困难。虽然可以放大字体,但因为缩放的存在,字体也无法做到特别清晰。
考虑到手机用户远远多过 iPad 用户,我们的游戏还是以手机用户的体验为优先考虑。所以我们采用第二种方式来优化 iPad 体验。
在游戏启动时,检测到如果是 iPad,则使用 768×1024 的虚拟分辨率。这样做比较麻烦的地方就是程序要做不少调整,确保场景元素在 640x???? 和 768×1024 两种虚拟分辨率下都可以正常显示。
从实践看,熟练的开发人员一周左右就可以做好一款休闲游戏(大概就是天天爱消除那种复杂度)的 iPad 优化。美术素材方面,除了极少数 UI 元素要做一些调整或为 iPad 单独制作一份外,其他素材都可以继续沿用。对开发成本的影响极小。
要让游戏在 iPad 上启动时使用 iPad 的分辨率设置,应该在 config.lua 中加入以下代码:
CONFIG_AUTOSCALE_CALLBACK = function(w, h, deviceModel)
if (w == 768 and h == 1024)
or (w == 1536 and h == 2048) then
-- iPad
CONFIG_SCREEN_WIDTH = 768
CONFIG_SCREEN_HEIGHT = 1024
return 1.0, 1.0
end
end
上述判断如果是在 iPad 上启动游戏,则使用 768/1024 作为参考分辨率,并且内容缩放为 100%,确保图像完全没有模糊。
针对超高分辨率设备的优化
Retina 显示屏幕的 iPad 和一些高端 Android 手机或平板,都提供了极高的分辨率。在这些设备上要获得最好的显示效果,就必须使用超高分辨率的素材。这也是本文前面提到美术素材制作时,为什么要求极高的分辨率。
不过因为超高分辨率的素材,游戏体积几乎是翻倍增加,这非常不利于游戏的传播。所以比较实际的做法还是单独出一个版本供用户下载,或者游戏启动后检测到超高分辨率设备,再提醒用户下载资源。
这些设备的优化对程序没什么影响,因为虚拟分辨率仍然是 640×960 为基准。只需要在程序启动时,用以下代码通知引擎使用了超高分辨率的素材:
CCDirector:sharedDirector():setContentScaleFactor(2)
处理横屏
横屏的处理其实相当简单,就是把“FIXED_WIDTH”换成“FIXED_HEIGHT”。这样虚拟分辨率里,高度就变成固定的了,而宽度根据设备发生变化。至于美术素材的制作、内容定位,和竖屏的方法完全一样。
总结
这一套方案,我们已经用在好几个游戏里面了。不管是从成本、最终效果上看,都很不错。
对于时间、预算都很紧张的小团队来说,连 iPad 优化那一步都可以放到后续版本来做。首先把大量手机用户的需求满足后,再来优化 iPad 体验。
最后,本文所述方案也完全可以用在原版 cocos2d-x 中。因为原版 cocos2d-x 也具有 FIXED_WIDTH 和 FIXED_HEIGHT 两种屏幕适配策略。
[转]quick-cocos2d-x 多分辨率适配详解的更多相关文章
- cocos2d-x 多分辨率适配详解(转载),以前北京团队设计的游戏,也是用这套方案
http://blog.csdn.net/kyo7552/article/details/17163487 多种分辨率的适配一直都是一个蛋疼的问题,各家公司可能都有自己的一套方案.今天我为大家介绍的是 ...
- android屏幕适配详解
android屏幕适配详解 官方地址:http://developer.android.com/guide/practices/screens_support.html 一.关于布局适配建议 1.不要 ...
- iOS10 SiriKit QQ适配详解
原文连接 1. 概述 苹果在 iOS10 开放了 SiriKit 接口给第三方应用.目前,QQ已经率先适配了 Siri 的发消息和打电话功能.这意味着在 iOS10 中你可以直接告诉 Siri 让它帮 ...
- 【腾讯Bugly干货分享】iOS10 SiriKit QQ适配详解
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57ece0331288fb4d31137da6 1. 概述 苹果在iOS10开放 ...
- Cocos2D研究院之CCNode详解(三)
http://www.xuanyusong.com/archives/950 上一章我们了解了cocos2d的项目路径以及工作原理,这次作者要真刀真枪地讲解代码了,咱们先来看看cocos2d最常用.也 ...
- 【转】Android hdpi ldpi mdpi xhdpi xxhdpi适配详解
1.了解几个概念(1)分辨率.分辨率就是手机屏幕的像素点数,一般描述成屏幕的“宽×高”,安卓手机屏幕常见的分辨率有480×800.720×1280.1080×1920等.720×1280表示此屏幕在宽 ...
- Android hdpi ldpi mdpi xhdpi xxhdpi适配详解
设计稿计算: x/2.5=1080/3x=900y/2.5=1920/3y=1600 http://blog.csdn.net/lantiankongmo/article/details/505491 ...
- webapp新体验Rem实现移动端网页适配详解资源
本来想写一篇,webapp使用Rem的问题,查了一下相关rem的介绍之后,发现很多平台已经解释的很清楚了,图文并茂,于是我便想将其解释资源整理一些,方便以后自己查阅. 腾讯ISUX:web app变革 ...
- Android屏幕像素密度适配详解
讲到像素密度,我们先要搞明白什么是像素密度,像素密度的字面上的意思为手机屏幕上一定尺寸区域内像素的个数.在Android开发中, 我们一般会使用每英寸像素密度(dpi)这样一个单位来表示手机屏幕的像素 ...
随机推荐
- android6.0锁屏界面接收新通知处理流程
灭屏状态下,接收新信息,屏幕会半亮显示通知流程: 1,应用构造notification后,传给NotificationManager,而后进入NotificationManagerService处理. ...
- css3之景深
perspective属性:(目前仅仅支持-webkit-perspective属性,视点距离) 值:number perspective-origin属性:(视点位置) 值:number% numb ...
- memcached总结
Memcached说明文档 Memcached是什么? Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数 ...
- 深入理解c#(第三版)(文摘)
第一部分 基础知识 第1章 C#开发的进化史 1.3 1.3.1 表示未知的价格 public decimal? Price { get; private set; } new ProductWith ...
- 我对C#的理解
C#里面所有东西都可以看作对象.接口,类,枚举等等. 类是最常用的,可以继承别的接口,类等,就会自动拥有别人的功能. 接口是类的概要.给别人看的协议,好像一个人对外做出的承诺. 抽象类是实现了部分承诺 ...
- Access 2003下载地址和密钥
电驴下载链接:ed2k://|file|sc_access_2003.iso|645523456|63AA6C30D609FDC22D056C4B424283F9|/ 安装SN: HH74C-P8F7 ...
- angular+requirejs前端整合
requirejs或者seajs我相信在前端的开发工作中经常使用到,而angular,这个强大的web前端框架很多公司也在引入.本文主要记录自己在工作学习中如何对angular跟requirejs进行 ...
- 绿色ip扫描工具
ip扫描,可以扫描一下自己的局域网有多少设备在线,有没有在蹭网.优点在于:短小精悍,快速,不用安装. 其实,我自己也写过一个但是没有这个精致,感兴趣的可以一起讨论. 下载地址:32位 64位 我的淘宝 ...
- input文本框去除单击时的边框的方法
前端开发写的input文本框标签后单击时可以看到有边框,去除边框的方法: input{ outline:medium; }
- vim中输入tab符
今天在写Makefile时各种出错.后来发现是all:的下一行,make前面必须是tab符,不能是空格. 但是vim中只要按tab就会自动转换成4个空格.平时编程需要,也不便把这个设置取消. 查了下, ...