一. 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. 网络协议HTTP、TCP/IP、Socket

    网络协议HTTP.TCP/IP.Socket 网络七层由下往上分别为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层.  其中物理层.数据链路层和网络层通常被称作媒体层,是网络工程师所研究的 ...

  2. 阿里面试:dubbo的服务引用过程

    点赞再看,养成习惯,微信搜一搜[三太子敖丙]关注这个喜欢写情怀的程序员. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的系 ...

  3. Mybatis源码学习第六天(核心流程分析)之Executor分析

    今Executor这个类,Mybatis虽然表面是SqlSession做的增删改查,其实底层统一调用的是Executor这个接口 在这里贴一下Mybatis查询体系结构图 Executor组件分析 E ...

  4. 关于h5游戏开发,你想了解的一切都在这儿!

    ​2020年,受疫情影响,线下产业红利褪去,线上迎来的新一轮的高峰.众多商家纷纷抓住了转型时机,开启了流量争夺战.H5游戏定制无疑是今年引流的大热门.如何开发一款有趣.有爆点.用户爱买单的好游戏呢? ...

  5. CSS的坑

    如何触发 bfc 规则 浮动元素:float 除 none 以外的值 绝对定位元素:position (absolute.fixed) display 为 inline-block.table-cel ...

  6. Oracle数据库之体系结构

    Oracle数据库管理系统中的3个重要的概念:实例(Instance).数据库(Database)和数据库服务器(Database Server). 实例:是后台进程和内存结构的集合,是Oracle数 ...

  7. 设计模式也可以这么简单(7年开发老鸟PS注释总结)

    设计模式是对大家实际工作中写的各种代码进行高层次抽象的总结,其中最出名的当属 Gang of Four (GoF) 的分类了,他们将设计模式分类为 23 种经典的模式,根据用途我们又可以分为三大类,分 ...

  8. oracle之二数据库审计

    数据库审计audit(PPT-I-320-334) 13.1 审计的功能:监控特定用户在database 的action(操作) 13.2 审计种类: 1)标准数据库审计(语句审计.权限审计.对象审计 ...

  9. Win10环境下Hadoop(单节点伪分布式)的安装与配置--bug(yarn的8088端口打不开+)

    一.本文思路 [1].配置java环境–JDK12(Hadoop的底层实现语言是java,hadoop运行需要JDK环境) [2].安装Hadoop 1.解压hadop 2.配置hadoop环境变量 ...

  10. 配置静态 IP、网卡命名规范

    一.网卡命名规范(设备类型 + 设备位置 + 数字) 设备类型: 格式 描述 en 以太网(Ethernet) ib 无限宽带(InfiniBand) sl 串列线路互联网协议(slip:Serial ...