一. 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屏幕适配的一些知识点的更多相关文章

  1. kbengine_js_plugins 在Cocos Creator中适配

    kbengine_js_plugins 改动(2017/7/6) 由于Cocos Creator使用严格模式的js,而原本的kbengine_js_plugins是非严格模式的,因此为了兼容和方 便C ...

  2. cocos creator游戏适配这事

    在想cocos适配之前,我们想想网页是怎么适配的.浏览器有各种规格,网页的一般做法是:背景图片铺满,网页内容保持在背景图片上居中,就实现了适应或者适配.css一般这样: .bg{ height:582 ...

  3. Cocos Creator iPhoneX适配的解决办法

    研究了5个小时的iPhoneX适配. 从catalog,storyboard,safearea等一系列文章中发现.如果我们想完全撑满全屏.那直接建一个storyboard就好了.但撑满全屏后,流海就是 ...

  4. Cocos Creator实现的《点我+1》

    一.前言 在学习Cocos中,需要一些东西来练手,于是前段时间就开发仿照一款公司之前的产品<点我+1>来做,仿照过程中,所有的算法逻辑都是自己研究的,并没有参考公司代码,也没有使用公司的美 ...

  5. Cocos Creator代码编辑环境配置

    1,可以使用较为适合js的webstorm,亦可以采用VS: 2,若需要webstorm,在下载之后,在文件,设置内外部编辑器选用webstorm.exe,即可: 3,Visual Studio Co ...

  6. 屏幕适配 部分知识点总结,CSDN小冰原创

    /** * 作者:David Zheng on 2015/11/7 15:38 * *  网站:http://www.93sec.cc * *  微博:http://weibo.com/mcxiaob ...

  7. 麒麟子Cocos Creator实用技巧

    大家好,我是麒麟子, 开源棋牌<幼麟棋牌-四川麻将>(泄漏版叫 <达达麻将>)作者,成都幼麟科技创始人. 自09年进入游戏行业以来,不知不觉已经度过了十个春秋. 曾经我也血气方 ...

  8. cocos creator主程入门教程(一)—— 初识creator

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 我们在cocos creator新建一个Hello TypeScript项目,都会有一个assets/S ...

  9. Cocos2dx开发之屏幕适配

    由于各种智能手机的屏幕大小都不一致,会出现同一张图片资源在不同的设备分辨率下显示不一样的问题.为避免这样的情况,需要Cocos引擎能提供多分辨率的支持,也就是说要求实现这样的效果 — 开发者不需要考虑 ...

随机推荐

  1. BootStrap-select插件动态添加option无法显示

    问题描述: 在使用bootstrap-select插件时出现下拉框无法显示动态追加的option,经过查看element元素发现,select标签已经append进去了所需的option选项,但是页面 ...

  2. 剑指 Offer 55 - I. 二叉树的深度

    题目描述 输入一棵二叉树的根节点,求该树的深度.从根节点到叶节点依次经过的节点(含根.叶节点)形成树的一条路径,最长路径的长度为树的深度. 例如: 给定二叉树 [3,9,20,null,null,15 ...

  3. 用笛卡尔积来创建一千六百万大表 整体19分钟 大表建成两分钟 设置id13分钟

    昨天拙文中讲述了用自增方式创建一千六百万大表的方案,这回讨论的是用笛卡儿积,实践证明这种方案更快. 2020年3月15日08点58分实验开始 创建仅有四千数据的tb_4thousand1表: SQL& ...

  4. Java自定义异常的用法

    package day162020072701.day1601; /** * @author liuwenlong * @create 2020-07-27 09:25:44 */ @Suppress ...

  5. [LeetCode] 17. 电话号码的字母组合(回溯)

    题目 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合. 给出数字到字母的映射如下(与电话按键相同).注意 1 不对应任何字母. 示例: 输入:"23" 输出:[& ...

  6. Prometheus Metrics 设计的最佳实践和应用实例,看这篇够了!

    Prometheus 是一个开源的监控解决方案,部署简单易使用,难点在于如何设计符合特定需求的 Metrics 去全面高效地反映系统实时状态,以助力故障问题的发现与定位.本文即基于最佳实践的 Metr ...

  7. HTTP 【值得你看个究竟】

    我是一名程序员,我的主要编程语言是 Python,我更是一名 Web 开发人员,所以我必须要了解 HTTP,所以本篇文章就来带你从 HTTP 入门到进阶,看完让你有一种恍然大悟.醍醐灌顶的感觉. 认识 ...

  8. 分布式系统监视zabbix-安装

    zabbix概述 Zabbix是什么 Zabbix 是由Alexei Vladishev创建,目前由Zabbix SIA在持续开发和支持. Zabbix 是一个企业级的分布式开源监控方案. Zabbi ...

  9. matlab数据插值

    由图可见采样点前段比较稀疏,比较有规律,后段比较密集,比较复杂 这里的spline是三次样条插值 随着次数的增高,曲线在两端震荡的越来越剧烈 用上其他插值的方法 线性插值 最近点插值 分段三次米勒插值 ...

  10. Mac使用Charles给iPhone抓包流程

    目录 需求 步骤 1. Mac打开共享Wifi 2. iPhone连接刚刚的WIFI 3. 找到Mac的局域网ip 4. 配置代理 需求 有时候手机接口出问题了,不知道从哪里下手,Charles就是非 ...