cocos creator屏幕适配的一些知识点
一. cocos creator 提供的几种适配策略
EXACT_FIT:
整个应用程序在指定区域可见,无需尝试保留原始纵横比。可能会出现失真,应用程序会被拉伸或压缩。也就是说设计分辨率的长和宽不会等比缩放,它们会各自进行缩放,设计分辨率的宽会用 “屏幕宽/设计分辨率宽” 作为缩放因子,设计分辨率的高会用 “屏幕高/设计分辨率高” 作为缩放因子。(2.0版本这个策略有问题,等修复)
NO_BORDER:
整个应用程序填充指定区域,没有失真,但可能会有一些裁剪,同时保持原样应用程序的纵横比。这个是等比进行缩放设计分辨率,取 “屏幕宽/设计分辨率宽” “屏幕高/设计分辨率高” 中较大的一个作为缩放因子,比如:“屏幕宽/设计分辨率宽”是2,“屏幕高/设计分辨率高”是1,那么取2作为缩放因子,这个时候高放大两倍,自然超出屏幕之外看不见了。
SHOW_ALL:
整个应用程序在指定区域可见而不失真,同时保持原样应用程序的纵横比。边界可以出现在应用程序的两侧。这个是等比进行缩放设计分辨率,取 “屏幕宽/设计分辨率宽” “屏幕高/设计分辨率高” 中较小的一个作为缩放因子,比如上述的那个例子,取1作为缩放因子,宽只放大一倍,明显不够,虽然整个应用程序都能看到,但会有黑边。
FIXED_HEIGHT:
应用程序采用设计分辨率大小的高度并修改内部的宽度画布使其适合设备的纵横比,不会发生失真。这个是等比进行缩放设计分辨率,保持设计分辨率的高度不变,根据屏幕分辨率改变设计分辨率的宽度,这个时候设计分辨率和屏幕分辨率一样了,再进行等比缩放。
FIXED_WIDTH:
这个和 FIXED_HEIGHT 类似,唯一不同的是它是保持的宽度不变。
是否等比缩放 | 宽的缩放比例 | 高的缩放比例 | 是否改变设计分辨率 | |
EXACT_FIT | 否 | 屏幕宽/设计宽 | 屏幕高/设计高 | 否 |
NO_BORDER | 是 | 较大的比 | 较大的比 | 否 |
SHOW_ALL | 是 | 较小的比 | 较小的比 | 否 |
FIXED_HEIGHT | 是 | 随便取,因为两个比一样 | 随便取,因为两个比一样 | 是 |
FIXED_WIDTH | 是 | 随便取,因为两个比一样 | 随便取,因为两个比一样 | 是 |
二. cocos提供的几个获取View的函数
cc.view.getDesignResolutionSize()
获取的是你在编辑器中设计的分辨率,也就是canvas 组件下设置的设计分辨率。
cc.view.getFrameSize()
获取各种手机、pad上的屏幕分辨率,也就是硬件分辨率。
cc.view.getVisibleSizeInPixel()
获取的是 visibleSize 的基础上乘以各种适配策略下的缩放比例后的分辨率。
cc.view.getVisibleSize()
官方文档上说返回视图窗口可见区域尺寸,经过输出对比发现,这个可见区域尺寸实际上是指设计分辨率,不过它返回的是经过各种适配策略后的设计分辨率,在EXACT_FIT,NO_BORDER,SHOW_ALL中因为不改变设计分辨率,所以和cc.view.getDesignResolutionSize()返回的结果一样。但在FIXED_HEIGHT,FIXED_WIDTH中改变了设计分辨率,所以返回的是修改后的设计分辨率。
后续通过查看creator源码也证实了这一点,以下是源码解释:
1 /**
2 * !#en
3 * Returns the visible area size of the view port.
4 * !#zh 返回视图窗口可见区域尺寸。
5 * @method getVisibleSize
6 * @return {Size}
7 */
8 getVisibleSize: function () {
9 return cc.size(this._visibleRect.width,this._visibleRect.height);
10 },
getVisibleSize()返回的是this._visbleRect的值,我们来找找this._visbleRect在哪进行赋值
1 cc.js.mixin(View.prototype, {
2 init () {
3 .........
4
5 var w = cc.game.canvas.width, h = cc.game.canvas.height;
6 this._designResolutionSize.width = w;
7 this._designResolutionSize.height = h;
8 this._originalDesignResolutionSize.width = w;
9 this._originalDesignResolutionSize.height = h;
10 this._viewportRect.width = w;
11 this._viewportRect.height = h;
12 this._visibleRect.width = w;
13 this._visibleRect.height = h;
14
15 cc.winSize.width = this._visibleRect.width;
16 cc.winSize.height = this._visibleRect.height;
17 ......
18 },
19 ........
20 }
可以看到在这里给一些保持分辨率的对象赋了同一个值,那就是cc.game.canvas里面的值,这个值代表的是屏幕分辨率,因为后续进行适配策略是用的也是这个值,这就奇怪了,都一样了还怎么比较,每个函数返回的值也应该一样呀,所以一定有一个地方改变了它们,继续找。
1 setDesignResolutionSize: function (width, height, resolutionPolicy) {
2 .........
8 this.setResolutionPolicy(resolutionPolicy);
9 var policy = this._resolutionPolicy;
10 if (policy) {
11 policy.preApply(this);
12 }
13
14 ..........28
29 this._originalDesignResolutionSize.width = this._designResolutionSize.width = width;
30 this._originalDesignResolutionSize.height = this._designResolutionSize.height = height;
31
32 var result = policy.apply(this, this._designResolutionSize);
33
34 if(result.scale && result.scale.length === 2){
35 this._scaleX = result.scale[0];
36 this._scaleY = result.scale[1];
37 }
38
39 if(result.viewport){
40 var vp = this._viewportRect,
41 vb = this._visibleRect,
42 rv = result.viewport;
43
44 vp.x = rv.x;
45 vp.y = rv.y;
46 vp.width = rv.width;
47 vp.height = rv.height;
48
49 vb.x = 0;
50 vb.y = 0;
51 vb.width = rv.width / this._scaleX;
52 vb.height = rv.height / this._scaleY;
53 }
54
55 policy.postApply(this);
56 cc.winSize.width = this._visibleRect.width;
57 cc.winSize.height = this._visibleRect.height;
58 ........64 },
我们直接来看setDesignResolutionSize()这个函数,它是通过设置设计分辨率和匹配模式来进行游戏画面的屏幕适配。所以它必然会改变相应的值。可以看到第29,30行把我们传进来的设计分辨率赋值给了this._originalDesignResolutionSize和this._designResolutionSize,改变了它们的值。那么什么时候改变this._visbleRect的值呢,我们看39行到52行,很明显就是在这里改变的。vb.width = rv.width / this._scaleX; vb.height = rv.height / this._scaleY;
那么凭什么说this._visbleRect是适配策略后到设计分辨率呢,我们来看看result.viewport里面是什么东西,var result = policy.apply(this, this._designResolutionSize);policy是一个适配策略的实例,它根据你传入的适配策略来决定调用哪个适配策略的方法,类似于c++中的多态。然后我们来看看每个适配策略做了什么,这里主要就拿SHOW_ALL和FIXED_HEIGHT来加以说明:
1 var ShowAll = cc.Class({
2 name: "ShowAll",
3 extends: cc.ContentStrategy,
4 apply: function (view, designedResolution) {
5 var containerW = cc.game.canvas.width, containerH = cc.game.canvas.height,
6 designW = designedResolution.width, designH = designedResolution.height,
7 scaleX = containerW / designW, scaleY = containerH / designH, scale = 0,
8 contentW, contentH;
9
10 scaleX < scaleY ? (scale = scaleX, contentW = containerW, contentH = designH * scale)
11 : (scale = scaleY, contentW = designW * scale, contentH = containerH);
12
13 return this._buildResult(containerW, containerH, contentW, contentH, scale, scale);
14 }
15 });
16
17 var FixedHeight = cc.Class({
18 name: "FixedHeight",
19 extends: cc.ContentStrategy,
20 apply: function (view, designedResolution) {
21 var containerW = cc.game.canvas.width, containerH = cc.game.canvas.height,
22 designH = designedResolution.height, scale = containerH / designH,
23 contentW = containerW, contentH = containerH;
24
25 return this._buildResult(containerW, containerH, contentW, contentH, scale, scale);
26 }
27 });
可以看到它们都继承于cc.ContentStrategy。在apply函数中返回值来自于this._buildResult()函数,我们来看这个函数:
1 _buildResult: function (containerW, containerH, contentW, contentH, scaleX, scaleY) {
2 // Makes content fit better the canvas
3 Math.abs(containerW - contentW) < 2 && (contentW = containerW);
4 Math.abs(containerH - contentH) < 2 && (contentH = containerH);
5
6 var viewport = cc.rect((containerW - contentW) / 2, (containerH - contentH) / 2, contentW, contentH);
7
8 // Translate the content
9 if (cc.game.renderType === cc.game.RENDER_TYPE_CANVAS){
10 //TODO: modify something for setTransform
11 //cc.game._renderContext.translate(viewport.x, viewport.y + contentH);
12 }
13
14 this._result.scale = [scaleX, scaleY];
15 this._result.viewport = viewport;
16 return this._result;
17 },
主要来看this._result中的viewport的值,它的width是contentW,height是contentH。到这里,一切都清楚了。我们假设屏幕分辨率的宽高是Pw和Ph,设计分辨率的宽高是Sw和Sh。
那么在SHOW_ALL中:假设Pw/Sw更小,contentW=Pw,contentH=Sh*(Pw/Sw),在进行this._visbleRect赋值时,width = Pw/(Pw/Sw) = Sw,height = (Sh*(Pw/Sw))/(Pw/Sw) = Sh,所以设计分辨率没有改变。
在FIXED_HEIGHT中:contentW=Pw,contentH=Ph,scale = Ph/Sh,在进行this._visbleRect赋值时,width = Pw/(Ph/Sh) = Sh*(Pw/Ph),height = Ph/(Ph/Sh) = Sh,所以设计分辨率是改变的。
从上述代码还发现cc.winSize和cc.view.getVisibleSize()的返回值是一样的,二者可以通用。
在进行屏幕适配时主要用到cc.view.getDesignResolutionSize()和cc.view.getFrameSize()两个函数。
cocos creator屏幕适配的一些知识点的更多相关文章
- kbengine_js_plugins 在Cocos Creator中适配
kbengine_js_plugins 改动(2017/7/6) 由于Cocos Creator使用严格模式的js,而原本的kbengine_js_plugins是非严格模式的,因此为了兼容和方 便C ...
- cocos creator游戏适配这事
在想cocos适配之前,我们想想网页是怎么适配的.浏览器有各种规格,网页的一般做法是:背景图片铺满,网页内容保持在背景图片上居中,就实现了适应或者适配.css一般这样: .bg{ height:582 ...
- Cocos Creator iPhoneX适配的解决办法
研究了5个小时的iPhoneX适配. 从catalog,storyboard,safearea等一系列文章中发现.如果我们想完全撑满全屏.那直接建一个storyboard就好了.但撑满全屏后,流海就是 ...
- Cocos Creator实现的《点我+1》
一.前言 在学习Cocos中,需要一些东西来练手,于是前段时间就开发仿照一款公司之前的产品<点我+1>来做,仿照过程中,所有的算法逻辑都是自己研究的,并没有参考公司代码,也没有使用公司的美 ...
- Cocos Creator代码编辑环境配置
1,可以使用较为适合js的webstorm,亦可以采用VS: 2,若需要webstorm,在下载之后,在文件,设置内外部编辑器选用webstorm.exe,即可: 3,Visual Studio Co ...
- 屏幕适配 部分知识点总结,CSDN小冰原创
/** * 作者:David Zheng on 2015/11/7 15:38 * * 网站:http://www.93sec.cc * * 微博:http://weibo.com/mcxiaob ...
- 麒麟子Cocos Creator实用技巧
大家好,我是麒麟子, 开源棋牌<幼麟棋牌-四川麻将>(泄漏版叫 <达达麻将>)作者,成都幼麟科技创始人. 自09年进入游戏行业以来,不知不觉已经度过了十个春秋. 曾经我也血气方 ...
- cocos creator主程入门教程(一)—— 初识creator
五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 我们在cocos creator新建一个Hello TypeScript项目,都会有一个assets/S ...
- Cocos2dx开发之屏幕适配
由于各种智能手机的屏幕大小都不一致,会出现同一张图片资源在不同的设备分辨率下显示不一样的问题.为避免这样的情况,需要Cocos引擎能提供多分辨率的支持,也就是说要求实现这样的效果 — 开发者不需要考虑 ...
随机推荐
- WebApi OAuth2身份认证
一.什么是OAuth OAuth是一个关于授权(Authorization)的开放网络标准,目前的版本是2.0版.注意是Authorization(授权),而不是Authentication(认证). ...
- fabric1.4 网络操作
建立第一个网络 进入对应目录 $ cd fabric-samples/first-network 在first-network目录下有两个自动化脚本byfn.sh和eyfn.sh, 这两个脚本的启动顺 ...
- AMQP 概论
AMQP 是应用层协议的一个开放标准,为面向消息的中间件设计.基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制.目标是实现一种在全行业广泛使用的标准消 ...
- HTML-CSS-JS Prettify 代码格式化插件
前提:已经安装 node.js.安装插件 HTML-CSS-JS Prettify,修改node路径,即可通过单击右键 HTML-CSS-JS Prettify 中的 Prettify Code 使用 ...
- jzoj1497. 景点中心
Description 话说宁波市的中小学生在镇海中学参加计算机程序设计比赛,比赛之余,他们在镇海中学的各个景点参观.镇海中学共有n个景点,每个景点均有若干学生正在参观.这n个景点以自然数1至n编号, ...
- oracle之三rman 备份
rman 备份 7.1 归档方式下rman备份常用语法: 7.1.1 backup 备份 1)备份全库:1.1 RMAN> backup database format='/u01/myrman ...
- mysql数据库常见问题修改(待补充)
1.修改mysql最大连接数的方法:临时修改:1.使用命令show variables 来查看当前最大连接数 show variables like '%max_connections%'; 使用命令 ...
- 痞子衡嵌入式:IAR在线调试时设不同复位类型可能会导致i.MXRT下调试现象不一致(J-Link / CMSIS-DAP)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是IAR在线调试时设不同复位类型可能会导致i.MXRT下调试现象不一致. 做Cortex-M内核MCU嵌入式软件开发,可用的集成开发环境( ...
- Linux驱动之GPIO子系统和pinctrl子系统
前期知识 1.如何编写一个简单的Linux驱动(一)--驱动的基本框架 2.如何编写一个简单的Linux驱动(二)--设备操作集file_operations 3.如何编写一个简单的Lin ...
- openstack核心组件——horizon Web管理界面(10)
一.horizon 介绍: 理解 horizon Horizon 为 Openstack 提供一个 WEB 前端的管理界面 (UI 服务 )通过 Horizone 所提供的 DashBoard 服务 ...