用到的名词解释:

理想设计分辨率:是美术出图采用的设计分辨率。

实际设计分辨率:调整后的理想设计分辨率,是根据理想分辨率和目标屏幕分辨率计算出来的

一.适配目的:

1.美术给的效果图是界面展示的最完美效果,我们做适配就是为了把游戏界面的元素按照效果图的布局方式展示在手机屏幕上。

二.为什么会存在屏幕不适配的问题,解决思路是什么?

美术基于一个固定的设计分辨率来进行设计UI,比如 960x640,而我们的游戏要跑在不同分辨率的手机上,如1920x1080,那么如何把960x640的界面全屏并且完美地显示在1920x1080屏幕上?需要做到一下两点:

1.等比拉伸:把设计好的界面拉伸到屏幕分辨率的大小,如果直接将960x640的界面setContentSize(1920x1080),宽放大1920/960=2倍,高放大1080/640=1.68倍,我们的背景图也要跟着这样缩放,图片scaleX和scaleY不相等的话会变形,所以拉伸界面必须要等比拉伸才行。

2.布局调整:放大后界面内元素的整体布局和效果图一致,如:效果图中靠左显示的按钮在界面变大后也要靠左,

第1点的等比拉伸引擎给我们的解决方案是:

1.固定宽度,就是按照宽度的缩放倍数来做等比拉伸,实际设计分辨率的高度要根据比例计算出来。

2.固定高度,就是按照高度的缩放倍数来做等比拉伸,实际设计分辨率的宽度要根据比例计算出来。

例如我们将960x640适配到1920x1080屏幕上,采用固定宽度,960/h=1920/1080 => h=540

这时候我们的设计分辨率变成了960x540,然后宽和高都放大2倍后,就等于1920x1080了。

其实就是先把理想设计分辨率(960x640)保持其中一个维度不变,改变另一个维度,使得设计分辨率的比例与屏幕分辨率的比例相同,这样就可以做等比拉伸了。

编辑器中有相关设置,设置好后,通过getVisibleSize()接口就得到了实际设计分辨率,canvas的size也会被设置为VisibleSize。

第2点的需要布局调整的界面有以下几种:

1.固定停靠点布局UI物体:界面中的物体位置居上、居下、居左、居右显示。为什么这些需要调整呢?上面的方案中,固定宽度时把理想设计分辨率的高度做了调整,拼界面用的高度是640,显示的高度是540,那么拼好的界面中居顶和居底元素会超出屏幕,所以需要调整。

2.容器拉伸:有的列表容器的高度要求始终覆盖屏幕高度的3/4大小,你的屏幕高度调整了,列表的尺寸也要调整。

按照固定宽度做适配,界面上的物体的x坐标不需要做布局调整,因为理想设计分辨率的宽度没变,同理按照固定高度做适配,界面上的物体的y坐标不需要布局调整。

以上两种情况,引擎给我们提供了Widget(对齐)组件来解决:

三.关于刘海屏的处理:

如图根据算出游戏正文的宽度,我们在canvas上面添加一个g_UIRoot节点作为所有UI界面的根节点,设置g_UIRoot居中于canvas,将g_UIRoot的contentSize的宽设置为游戏正文的宽度即可。

具体实现:

  • 1.IOS苹果手机因为机型类型比较少,所以游戏正文所占屏幕区域的宽高比(safeArea)我们可以直接配置,比如["iPhone Xs"] = 2、["iPhone Xs Max"] = 2。
  • 2.安卓机器机型比较多而杂,无法通过配置写死safeArea,所以通过代码取得,指的一提的是安卓9.0以下的时候没有统一的获取方式,华为 oppo Vivo 小米需要各自厂商不同的接口分别获取,安卓9.0以上可以统一获取。(具体可自行百度或者参考AppActivity.java)
    取得safeArea以后:
    var safeWidth = realHeight * safeArea (游戏正文宽度)
    var safeSize = cc.size(safeWidth,realHeight)
    g_UIRoot.setContentSize(safeSize) (设置contentSize为正文大小)
    如果有的界面不需要适配,需要全屏显示。比如有的背景界面需要在刘海区域显示,就需要将这个界面的contentSize大小为realSize。

引擎内部实现等比拉伸的代码:

​//固定高度,缩放因子的计算,只要设计分辨率的宽高比和屏幕宽高比相同则scaleX==scaleYclass FixedHeight extends ContentStrategy {constructor(...args) {super(...args);this.name = 'FixedHeight';}apply(_view, designedResolution) {const windowSize = _screen.screen.windowSize;const containerW = windowSize.width;const containerH = windowSize.height;const designH = designedResolution.height;const scale = containerH / designH;//按照高度的缩放倍数来做等比拉伸const contentW = containerW;const contentH = containerH;return this._buildResult(containerW, containerH, contentW, contentH, scale, scale);}}//固定宽度,缩放因子的计算,只要设计分辨率的宽高比和屏幕宽高比相同则scaleX==scaleYclass FixedWidth extends ContentStrategy {constructor(...args) {super(...args);this.name = 'FixedWidth';}apply(_view, designedResolution) {const windowSize = _screen.screen.windowSize;const containerW = windowSize.width;const containerH = windowSize.height;const designW = designedResolution.width;const scale = containerW / designW;const contentW = containerW;const contentH = containerH;return this._buildResult(containerW, containerH, contentW, contentH, scale, scale);}} // Alias: Strategy to scale the content's size to container's size, non proportional/** 等比拉伸代码,根据实际设计分辨率和屏幕尺寸来设置渲染视口的大小* @zh 通过设置设计分辨率和匹配模式来进行游戏画面的屏幕适配。* @param width 实际设计分辨率的宽度.例子中的960* @param height 实际设计分辨率的高度.例子中的540* @param resolutionPolicy 我们在编辑器勾选的固定宽、高*/setDesignResolutionSize(width, height, resolutionPolicy) {// Defensive codeif (!(width > 0 && height > 0)) {(0, _debug.errorID)(2200);return;}//设置适配策略,就是前面说的固定宽、高this._updateResolutionPolicy(resolutionPolicy);const policy = this._resolutionPolicy;if (policy) {policy.preApply(this);}this._designResolutionSize.width = width;this._designResolutionSize.height = height;const result = policy.apply(this, this._designResolutionSize);if (result.scale && result.scale.length === 2) {this._scaleX = result.scale[0];this._scaleY = result.scale[1];}//只要设计分辨率的宽高比和屏幕宽高比相同则这里的this._scaleX和this._scaleY相等if (result.viewport) {const vp = this._viewportRect;const vb = this._visibleRect;const rv = result.viewport;vp.x = rv.x;vp.y = rv.y;vp.width = rv.width;vp.height = rv.height;vb.x = 0;vb.y = 0;vb.width = rv.width / this._scaleX; vb.height = rv.height / this._scaleY;}policy.postApply(this);localWinSize.width = this._visibleRect.width;localWinSize.height = this._visibleRect.height;if (_visibleRect.default) {_visibleRect.default.init(this._visibleRect);}this.emit('design-resolution-changed');}​

CocosCreator3.x屏幕适配相关推荐

  1. iOS开发之绝对布局和相对布局(屏幕适配)

    在IOS的UI设计中也有绝对定位和相对定位,和我们的web前端的绝对定位和相对定位有所不同但又有相似之处.下面会结合两个小demo来学习一下我们IOS开发中UI的绝对定位和相对定位.在前面的博客中所用 ...

  2. 关于IOS的屏幕适配(iPhone)——资源适配

    IOS的屏幕适配几乎不需要大量的代码操作,更多的时间我们只是动动鼠标选择一下就搞定.可以苹果在这方面做的还是比较人性的,解放了开发者. 首先来说说Iphone这几种屏(由于最近做的是iPhone AP ...

  3. Android屏幕适配框架-(今日头条终极适配方案)

    2019独角兽企业重金招聘Python工程师标准>>> 在Android开发中,屏幕适配是一个非常头痛的问题,因而为了去进行屏幕适配,作为程序员,是呕心沥血,历经磨难,哈哈 我们之前 ...

  4. 【转】Android中dp,px,sp概念梳理以及如何做到屏幕适配

    2019独角兽企业重金招聘Python工程师标准>>> 首先来看一下他们的基本概念: px   :是屏幕的像素点 dp   :一个基于density的抽象单位,如果一个160dpi的 ...

  5. Android 屏幕适配从未如斯简单(8月10日最终更新版)

    前言 一个月前看了今日头条新的屏幕适配方案,这是传送门,对此不禁拍案叫绝,为此我想把这种方案融入到我工具类中直接一行代码即可适配,如今最新 1.19.0 版 AndroidUtilCode 已有其最新 ...

  6. 再谈移动端Web屏幕适配

    一个多月前水了一篇移动web屏幕适配方案,当时噼里啪啦的写了一通,自我感觉甚是良好.不过最近又有一些新的想法,和之前的有一些不同. 先说一下淘宝的方案,感觉现在好多的适配方案都是受了它的影响,上周六看 ...

  7. android屏幕适配的目的,Android 不同分辨率下屏幕适配的实战方案与经验总结

    Android 开发中,屏幕适配是一大考点,几乎每一场面试,都不会落下这个问题,这个问题说简单也简单,说难也难,当然对于有过真实的适配经验的人来说,这个根本不算什么问题,从坑里爬过的人,自然知道这其中 ...

  8. 鸿洋android屏幕适配四部曲-传送门

    鸿洋android屏幕适配四部曲-传送门 两分钟理解Android中PX.DP.SP的区别 https://blog.csdn.net/donkor_/article/details/77680042 ...

  9. 移动Web怎么做屏幕适配

    壹 | Fisrt 移动端适配的是什么? 我们讨论的是网页适配多种尺寸屏幕,让网页效果看起来和设计师的设计稿一样.说白了就是同一套代码在不同分辨率的手机上跑时,页面元素间的间距,留白,以及图片大小会随 ...

最新文章

  1. Window10下Ubuntu20.04子系统下安装cuda
  2. python电脑配置要求-1.安装python3.5及电脑环境变量的配置
  3. 爱奇艺大数据生态的实时化建设
  4. MIT Kimera阅读笔记
  5. 原型模式 java 深浅_JAVA设计模式---原型模式--浅客隆和深克隆
  6. 学习Apache Camel –实时索引推文
  7. USACO 06JAN 牛的舞会 洛谷2863
  8. 聊聊云计算:为什么构建网站时常会用到负载均衡
  9. 深入理解计算机系统(原书第三版)系列 第一章 计算机系统漫游
  10. docker源码编译 linux_oracle linux 6 docker 安装(包括编译git源码)
  11. 下载并搭建VauditDemo
  12. java 状态模式的实现与应用
  13. VFP9 连接mysql代码示例
  14. 新一代同步控制器和触摸屏组合在压延机上的应用
  15. Word删除空白页的方法
  16. 谨慎解决:找不到指定的模块(Exception from HRESULT:0X8007007E)
  17. 如何展现两极化数据,Excel柱状断层图不二之选
  18. 高通FastCV简介
  19. win10安装steam有损计算机,win10系统steam磁盘写入错误怎么办 steam磁盘写入错误的解决教程...
  20. 运营技巧|要如何提升用户留存率?

热门文章

  1. 【读书笔记】TableauFineBi 学习小记
  2. 中毒解决方法(http://www.xn--******.com)
  3. A2B车载音频总线-车机音频麦克风阵列测试
  4. Swift vs. Kotlin 漫谈之扩展篇
  5. 课时11:列表:一个打了激素的数组2
  6. 记win10安装cupy的cuda版本成功踩得坑!!!血泪教训!!
  7. (Java实现) 细胞
  8. 无法打开这个应用,查看Microsoft store, 了解有关Nahimic的详细信息
  9. [xueqi]吃着榨菜,轻松搞下漏洞百出的湾湾站
  10. 【C语言每日一练——第1练:字母大小写转换】