Cocos2d-x屏幕适配

资源分辨率,设计分辨率,屏幕分辨率

  • Resources width 以下简写为RW,Resources height 以下简写为RH
  • Design width 以下简写为DW,Design height 以下简写为DH
  • Screen width 以下简写为SW,Screen height 以下简写为SH


接口setContentScaleFactor()和setSearchPaths()控制着第一个转换过程。
而setDesignResolutionSize()控制第二个过程。两个过程结合在一起,影响最终的显示效果。

从资源分辨率到设计分辨率

setSearchPaths()需要根据当前屏幕分辨率做恰当的设置。
setContentScaleFactor()决定了图片显示到屏幕的缩放因子,但是这个接口的参数不是通过资源图片的宽、高比屏幕宽、高得来。Cocos2d-x引擎设计试图屏蔽游戏开发者直接去关注屏幕,所以这个因子是资源宽、高比设计分辨率宽、高。
setContentScaleFactor()通常有两个方式来设置参数。 RH/DH或RW/DW,不同的因子选择有不同的缩放负作用。 先看一张图:

用高度比作为内容缩放因子,保证了背景资源的垂直方向在设计分辨率范围内的全部显示。
用宽度比作为内容缩放因子,保证了背景资源的水平方向在设计分辨率范围内的全部显示。

从设计分辨率到屏幕分辨率

首先,我们通过一张图了解下Cocos2d-X的几种屏幕适配规则:

1. EXACT_FIT将设计尺寸映射到屏幕尺寸,长宽按各自比例拉伸,可能造成图像拉伸变形。
2. SHOW_ALL和NO_BORDER都是长宽等比例拉伸,图像不会被拉伸变形;但可能造成黑边和资源显示不全的问题。
3. FIXED_HEIGHT和FIXED_WIDTH和之前的三种策略不同,EXACT_FIT、SHOW_ALL和NO_BORDER都不会修正设计尺寸,而FIXED_HEIGHT和FIXED_WIDTH在设计阶段就修正设计尺寸,让可视区域就是设计尺寸区域。
4. NO_BORDER是唯一可视区域小于最终设计区域(FIXED_HEIGHT和FIXED_WIDTH会修正传入的设计尺寸)的一种策略。其他几种策略的设计区域等于设计区域。
5. NO_BORDER、FIXED_HEIGHT和FIXED_WIDTH三种策略根据设计或可视区域的改变需要做相应的坐标适配。

FIXED_HEIGHT:
1. 如果屏幕尺寸长高比>资源尺寸长高比,进行坐标偏差纠正,让资源居中显示,左右两边留黑边。
2. 如果屏幕尺寸长高比<资源尺寸长高比,进行坐标偏差纠正,让资源居中显示,左右两边被裁剪无法显示。

所以,屏幕尺寸长高比略小于资源尺寸长高比,显示效果最佳。

源码面前无秘密

class CC_DLL GLView : public Ref
{/*** Get the frame size of EGL view.* In general, it returns the screen size since the EGL view is a fullscreen view.** @return The frame size of EGL view.*/const Size& GLView::getFrameSize() const{return _screenSize;}/*** Set the frame size of EGL view.** @param width The width of the fram size.* @param height The height of the fram size.*/void GLView::setFrameSize(float width, float height){_screenSize = Size(width, height);}/*** Get the visible area size of opengl viewport.** @return The visible area size of opengl viewport.*/Size GLView::getVisibleSize() const{if (_resolutionPolicy == ResolutionPolicy::NO_BORDER){return Size(_screenSize.width/_scaleX, _screenSize.height/_scaleY);}else {return _designResolutionSize;}}/*** Get the visible origin point of opengl viewport.** @return The visible origin point of opengl viewport.*/Vec2 GLView::getVisibleOrigin() const{if (_resolutionPolicy == ResolutionPolicy::NO_BORDER){return Vec2((_designResolutionSize.width - _screenSize.width/_scaleX)/2, (_designResolutionSize.height - _screenSize.height/_scaleY)/2);}else {return Vec2::ZERO;}}/*** Set the design resolution size.* @param width Design resolution width.* @param height Design resolution height.* @param resolutionPolicy The resolution policy desired, you may choose:*                         [1] EXACT_FIT Fill screen by stretch-to-fit: if the design resolution ratio of width to height is different from the screen resolution ratio, your game view will be stretched.*                         [2] NO_BORDER Full screen without black border: if the design resolution ratio of width to height is different from the screen resolution ratio, two areas of your game view will be cut.*                         [3] SHOW_ALL  Full screen with black border: if the design resolution ratio of width to height is different from the screen resolution ratio, two black borders will be shown.*/void GLView::setDesignResolutionSize(float width, float height, ResolutionPolicy resolutionPolicy){CCASSERT(resolutionPolicy != ResolutionPolicy::UNKNOWN, "should set resolutionPolicy");if (width == 0.0f || height == 0.0f){return;}_designResolutionSize.setSize(width, height);_resolutionPolicy = resolutionPolicy;updateDesignResolutionSize();}void GLView::updateDesignResolutionSize(){if (_screenSize.width > 0 && _screenSize.height > 0&& _designResolutionSize.width > 0 && _designResolutionSize.height > 0){_scaleX = (float)_screenSize.width / _designResolutionSize.width;_scaleY = (float)_screenSize.height / _designResolutionSize.height;if (_resolutionPolicy == ResolutionPolicy::NO_BORDER){_scaleX = _scaleY = MAX(_scaleX, _scaleY);}else if (_resolutionPolicy == ResolutionPolicy::SHOW_ALL){_scaleX = _scaleY = MIN(_scaleX, _scaleY);}else if ( _resolutionPolicy == ResolutionPolicy::FIXED_HEIGHT) {_scaleX = _scaleY;_designResolutionSize.width = ceilf(_screenSize.width/_scaleX);}else if ( _resolutionPolicy == ResolutionPolicy::FIXED_WIDTH) {_scaleY = _scaleX;_designResolutionSize.height = ceilf(_screenSize.height/_scaleY);}// calculate the rect of viewportfloat viewPortW = _designResolutionSize.width * _scaleX;float viewPortH = _designResolutionSize.height * _scaleY;_viewPortRect.setRect((_screenSize.width - viewPortW) / 2, (_screenSize.height - viewPortH) / 2, viewPortW, viewPortH);// reset director's member variables to fit visible rectauto director = Director::getInstance();director->_winSizeInPoints = getDesignResolutionSize();director->_isStatusLabelUpdated = true;director->setProjection(director->getProjection());// Github issue #16139// A default viewport is needed in order to display the FPS,// since the FPS are rendered in the Director, and there is no viewport there.// Everything, including the FPS should renderer in the Scene.glViewport(0, 0, _screenSize.width, _screenSize.height);}}};

设置/获取屏幕的大小(主要是desktop系统上设置,也用于调试各屏幕适配的情况是否符合我们的预期等):
void GLView:: setFrameSize(float width, float height)
const Size& GLView::getFrameSize() const

设置/获取设计尺寸大小(相当于我们设定了我们的创作区域大小、最终如何显示到屏幕上,通过ResolutionPolicy指定。
注意:SHOW_ALL、EXACT_FIT、NO_BORDER三种策略的设计分辨率都是传入值,内部不做修正。FIXED_HEIGHT和FIXED_WIDTH都是会在内部修正传入设计分辨率,以保证屏幕分辨率到设计分辨率无拉伸铺满屏幕,所以通过getDesignResolutionSize()获取的值可能与传入的值不一致。
void GLView:: setDesignResolutionSize(float width, float height, ResolutionPolicy resolutionPolicy)
const Size& GLView::getDesignResolutionSize() const

获取可视区域的大小和原点,即我们设定的setDesignResolutionSize大小有多少是可以被显示的。由于适配策略NO_BORDER,有可能设计区域有部分最终无法在屏幕上显示,所以这里需要计算,可视原点也可能不是(0,0)。还有由于我们通过setDesignResolutionSize设置的设计尺寸大小,FIXED_HEIGHT、FIXED_WIDTH因为需要裁剪,所以这里的可视区域大小也是经过裁剪后的大小。
Size GLView::getVisibleSize() const
Vec2 Director::getVisibleOrigin() const

这里获取的WinSize,即setDesignResolutionSize设置后经过计算裁剪(可能)的_designResolutionSize。
const Size& Director::getWinSize(void) const

Cocos2d-x屏幕适配相关推荐

  1. cocos2d 屏幕適配_Cocos2d-x 3.1 一步步做屏幕适配

    本文并不想讲关于屏幕适配的概念或者大道理,如果还不了解cocos2d-x屏幕适配的,请先看这篇文章:http://www.cocoachina.com/gamedev/cocos/2014/0516/ ...

  2. cocos2d 屏幕適配_cocos2d-x 2.x屏幕适配基础

    一开始我就忽略了屏幕适配的问题,现在才发现它是多么的重要.通过实践才领悟了其基础概念,而屏幕适配的策略是建立在其上的,有很多,但我还没有认真研究.这里仅把自己对屏幕适配基础知识进行一个梳理. 关于屏幕 ...

  3. cocos2d 屏幕適配_cocos2d-x 屏幕适配新解

    转自:http://blog.leafsoar.com/archives/2013/05-10-19.html 为了适应移动终端的各种分辨率大小,各种屏幕宽高比,在 cocos2d-x(当前稳定版:2 ...

  4. cocos2dx的屏幕适配

    1.版本 cocos3.9 2.屏幕适配 cocos有5种屏幕适配策略. EXACT_ALL:非等比缩放,使画面充满整个屏幕,但会变形. NO_BORDER:等比缩放,也会使画面充满整个屏幕,不会变形 ...

  5. Cocos2D-X屏幕适配新解

    为了适应移动终端的各种分辨率大小,各种屏幕宽高比,在 Cocos2D-X(当前稳定版:2.0.4) 中,提供了相应的解决方案,以方便我们在设计游戏时,能够更好的适应不同的环境. 而在设计游戏之初,决定 ...

  6. cocos2d-x 屏幕适配原理分析

    cocos2d-x作为著名的cocos2d游戏开发框架的C++实现者,最近一年发展迅猛.越来越多的app使用它实现快速多平台部署,从最初的ios,android,win32等到新近的html5,实现移 ...

  7. Cocos2d-x 屏幕适配新解(比较全面比较详细)

    黑米GameDev街区 『 不要让任何事情成为你不去学习的理由!』 -Himi Home About Himi Himi's Book 街区须知 资源/技术群 订阅本站 主页 > Cocos2d ...

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

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

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

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

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

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

最新文章

  1. kafka异步推送设置重试_一篇文章了解 Kafka 幂等性的原理及实践
  2. 图解Detour安装及简单使用实例(Win7+VC6)
  3. 程序员买房与程序员转型
  4. numpy 读取txt为array 一行搞定
  5. linux内外部命令,Shell、内外部命令――Linux基本命令(2)
  6. Live Writer首段缩进和全角空格设置
  7. 出租广告Java代码_Spring cloud 查询返回广告创意实例代码
  8. OIBH杯第三次普及组模拟赛T1 立体井字棋
  9. Ubuntu/Debian安装护眼软件f.lux indicator applet
  10. 史上最详细Lip-reading with Hierarchical Pyramidal Convolution and Self-Attention文章记录
  11. allegro 04_B class和subclass介绍
  12. GPU深度发掘 -- GPGPU数学基础教程
  13. GoogleEarth二次开发平台指南(1) ---如何将谷歌地球嵌入到自定义的窗体中
  14. 玩战塔英雄不显示服务器,王者荣耀的这个问题,国家点名了仍没有改正过来!战塔英雄就没有...
  15. LinkButton的样式设置(背景图片问题)
  16. 华为数通笔记-IPV6基础
  17. 静态时序分析-时序违例解决方法
  18. 解决 Office 2007/2010/2013 安装错误:1402
  19. 《C#零基础入门之百识百例》(九十一)预处理器指令 -- 代码示例
  20. IDL考前复习(六) image函数keywords

热门文章

  1. QT软件开发之基础控件--2.4.5 plainTextEdit文本编辑器
  2. 软件安装管家(目录及教程)
  3. CSA研讨会 | 研讨零信任SASE安全架构,吉利控股首谈其部署方案
  4. oracle中嵌套函数,Oracle的嵌套函数语法
  5. python-嵌套函数讲解
  6. qt 点击按钮不抬起,按钮无法点击
  7. Python: 读写Excel(openpyxl / win32com.client)
  8. JVM系列(三):程序计数器(PC寄存器)
  9. 【python脚本系列】MIDI文件128种音色码表
  10. 《iTOP-3568开发板快速测试手册》第7章 Yocto系统外设功能测试(2)