cocos2d-x(新版本,姑且以2.1.4为准)跨平台屏幕分辨率适配

时间:2023-02-08 23:15:49

最近开始研究cocos2D-x游戏开发,开发工具为mac10.8.1+xcode4.6.1,本文作为学习新知识的开篇(仅供自己学习只用,如有问题请指正)

-----------------------------------------------------------------------------------------------------------------------------------------------

首先遇到的问题就是屏幕适配问题,本来开发ios应用时只有几个设备需要适配,由于是跨平台开发,又多了众多型号的安卓设备,突然感觉没了方向。查阅资料好,倍感欣喜,在新的cocos2D-x中已经解决了此问题,而且超级方便,似乎有点像苹果自己的方法

首先看一下问题的根源:


新建一个带工程,跑起来是这样的:



cocos2d-x(新版本,姑且以2.1.4为准)跨平台屏幕分辨率适配


窗口尺寸为480x320,背景图片原始大小就是480x320,正好铺满屏幕。

现在,将模拟分辨率为960x640的屏幕,看看程序会是什么样子。
运行效果:
cocos2d-x(新版本,姑且以2.1.4为准)跨平台屏幕分辨率适配

背景图尺寸是480x320,在960x640屏幕下自然就填不满,很合理~
问题由此产生;

解决方案:
1,使用不同的资源适配不同的屏幕,可以通过判断屏幕的分辨率来设置加载不同目录的资源。
2,使用一套资源,在不同的分辨率下匹配屏幕进行缩放。

先说方案一,既然要为不同分辨率使用不同资源,那就再做一张图案一样的背景图,尺寸为960x640,
用于分辨率为960x640的屏幕。在工程Resources目录下新建两个目录:
cocos2d-x(新版本,姑且以2.1.4为准)跨平台屏幕分辨率适配

"iphone"目录存放480x320的背景图和按钮图标,"iphone-retina"存放960x640的背景图和按钮图标。
这两个目录名字随意,再看到AppDelegate.cpp,修改代码如下:
cocos2d-x(新版本,姑且以2.1.4为准)跨平台屏幕分辨率适配


再运行程序:

cocos2d-x(新版本,姑且以2.1.4为准)跨平台屏幕分辨率适配


问题解决,但是面对全世界那么多的移动设备,那么多的分辨率,显然这种方法不现实
现在来用第2种方法,其实就是官方的方法

现在还是只有一套480x320的背景图和按钮图片,怎么改呢?AppDelegate.cpp里修改:


bool AppDelegate::applicationDidFinishLaunching()

{

    // initialize director

    CCDirector *pDirector = CCDirector::sharedDirector();

    pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());


    // turn on display FPS

    pDirector->setDisplayStats(false);


    // set FPS. the default value is 1.0/60 if you don't call this

    pDirector->setAnimationInterval(1.0 / 60);

    //适配

    CCEGLView::sharedOpenGLView()-> setDesignResolutionSize(480, 320, kResolutionExactFit);------只加这一句

    // create a scene. it's an autorelease object

    CCScene *pScene = StartScene::scene();


    // run

    pDirector->runWithScene(pScene);


    return true;

}


再次运行,
cocos2d-x(新版本,姑且以2.1.4为准)跨平台屏幕分辨率适配

分析:
designResolutionSize是一个新的概念,它让一切与坐标,尺寸相关的数据彻底摆脱了屏幕分辨率的羁绊,或者说
由框架层来帮开发者完成转换,开发者需要的只是设置designResolutionSize。告诉框架你在什么样尺寸的场景下
做的资源,比如此例,背景图原始尺寸480x320

 跟踪pEGLView->setDesignResolutionSize(480, 320, kResolutionNoBorder);
可以发现,框架是获取了实际分辨率和开发者designResolutionSize的比例,渲染的时候把图片按照这个比例来缩放绘制。
拿本例来说,屏幕960x640,designResolutionSize为480x320,缩放比例为2,那么原始大小480x320的背景图,在绘制
时就会x2来绘制,也就是实际绘制成了960x640的大小,这样就填满窗口了!

pEGLView->setDesignResolutionSize(480, 320, kResolutionNoBorder);第三个参数,找到定义:



enum ResolutionPolicy

{

    // The entire application is visible in the specified area without trying to preserve the original aspect ratio.

    // Distortion can occur, and the application may appear stretched or compressed.

    kResolutionExactFit,

    // The entire application fills the specified area, without distortion but possibly with some cropping,

    // while maintaining the original aspect ratio of the application.

    kResolutionNoBorder,

    // The entire application is visible in the specified area without distortion while maintaining the original

    // aspect ratio of the application. Borders can appear on two sides of the application.

    kResolutionShowAll,

    // The application takes the height of the design resolution size and modifies the width of the internal

    // canvas so that it fits the aspect ratio of the device

    // no distortion will occur however you must make sure your application works on different

    // aspect ratios

    kResolutionFixedHeight,

    // The application takes the width of the design resolution size and modifies the height of the internal

    // canvas so that it fits the aspect ratio of the device

    // no distortion will occur however you must make sure your application works on different

    // aspect ratios

    kResolutionFixedWidth,


    kResolutionUnKnown,

};

kResolutionExactFit:会靠拉伸来填满屏幕,本例来说背景图会变形来填充屏幕,因为1024:768=1.3, 480:320=1.5,宽高比不同,图片也就无法等比缩放来填满屏幕,只能变形了。
kResolutionNoBorder: 看不到黑边,实际就是宽高等比缩放,但缩放比例取宽比和高比之中大的那一个。
kResolutionShowAll:全部显示,可以理解为保证内容都显示在屏幕之内,实际也是宽高等比缩放,但缩放比例取宽比和高比之中小的那一个。


setPosition()的变化
这里传入的参数不是像素,也和传统的point有不同,它指的是在designResolutionSize参照下的坐标。
比如设计分辨率为480x320,设置一个sprite的位置为240,160,在480x320分辨率下会发现它在屏幕正中,
模拟其他分辨率,960x640,1024x768,会发现它依然在屏幕中心,这就可了解240,160这个值跟实际屏幕分辨率已经无关了,
只和designResolutionSize有关,其实更像是ios应用开发,不管是否retain,就按照(320,480)设计


使用kResolutionNoBorder策略时要注意的
CCSize szVisible = CCDirector::sharedDirector()->getVisibleSize();
CCPoint posVisible = CCDirector::sharedDirector()->getVisibleOrigin();
使用该策略时,因为标准背景图可能会超出屏幕,所以设置位置时需要已一个可视矩形为基准。
可以这样理解,szVisible就是你在实际设备上能看到的有效区域的宽高,posVisible就是这个有效区域的起始坐标,和szVisible构成一个可视矩形,一般来说这个可视矩形是设计分辨率下可视矩形的子集。

----------------------转自网络,经过自己精简修改而成