Cocos2d适应屏幕分辨率

我使用的版本是cocos2d-2.0-x-2.0.4,cocos2dx-2.0版本对多分辨率适配提供了很好的支持,使用起来比1.0版本要简单些,1.0版本的适配可以参考这篇博文

1. 做2.0版本的适配首先需要了解下面这些知识。

(1)适配策略

2.0版本提供了三种适配策略:

kResolutionNoBorder:超出屏幕的部分会被裁剪,两侧没有黑边,铺满屏幕,按图片原始比例显示,图片不变形。

kResolutionShowAll:整个游戏界面是可见的,会按原始比例进行缩放,图片不变形,但两侧可能会留有黑边,不铺满屏幕。

kResolutionExactFit:整个游戏界面是可见的,图片可能会进行拉伸或者压缩处理,铺满屏幕,图片会变形。

可以根据自己的要求选择。

(2)VisibleSize和VisibleOrigin

getVisibleSize:表示获得视口(可视区域)的大小,如果DesignResolutionSize跟屏幕尺寸一样大,则getVisibleSize等于getWinSize。

getVisibleOrigin:表示可视区域的起点坐标,这在处理相对位置的时候非常有用,确保节点在不同分辨率下的位置一致。

(3)DesignResolutionSize

DesignResolutionSize是一个比较重要的概念,其实2.0版本的适配跟1.0版本原理差不多,都是按比例进行缩放。这个DesignResolutionSize表示设计方案,就是你的游戏完美支持的分辨率方案,一般根据图片资源的尺寸来定,自适配时会按照这个分辨率计算出缩放因子。因此,这个值也应该是动态的,如果是横屏游戏则高度肯定是铺满屏幕的,宽度也要尽可能的铺满屏幕,因此应该选择宽高比最大的作为设计分辨率,下面的demo会给出使用方法。

(4)设置相对位置

在游戏中使用相对位置设置坐标的好处是显而易见的,这样就不需要为每个分辨率都定义一套坐标了。首先得定义一些参考点,引擎的TestCpp例子中就提供了一种方法,以屏幕上可视区域的9个点作为参考点,相当于在该矩形内写一个米字,这9个点分别是:左上、左、左下、下、右下、右、右上、上、中心。

2. 下面来实现一个简单的demo,首先创建一个win32工程,这个就不详述了。

(1)创建一个AppMacros.h文件,定义了一些宏,源码如下:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

#ifndef
__APPMACROS_H__

#define
__APPMACROS_H__

#include
"cocos2d.h"

typedef

struct

tagResource

{

    cocos2d::CCSize
size;

    char

directory[100];

}Resource;

//可用的资源尺寸

static

Resource smallResource  =  { cocos2d::CCSizeMake(480, 320),  
"iphone"

};

static

Resource mediumResource =  { cocos2d::CCSizeMake(1024, 768), 
"ipad"  

};

static

Resource largeResource  =  { cocos2d::CCSizeMake(2048, 1536),
"ipadhd"

};

//设计方案

static

cocos2d::CCSize smallDesignResolutionSize = cocos2d::CCSizeMake(480.0f, 320.0f);

static

cocos2d::CCSize mediumDesignResolutionSize = cocos2d::CCSizeMake(1024.0f, 768.0f);

static

cocos2d::CCSize largeDesignResolutionSize = cocos2d::CCSizeMake(2048.0f, 1536.0f);

//缩放因子,主要给文字标签使用

#define
SCALE_FACTOR  (cocos2d::CCEGLView::sharedOpenGLView()->getDesignResolutionSize().width / smallResource.size.width)

#endif

(2)接下来修改AppDelegate.cpp文件的applicationDidFinishLaunching函数,添加以下代码:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

bool

AppDelegate::applicationDidFinishLaunching()

{

    //
initialize director

    CCDirector
*pDirector = CCDirector::sharedDirector();

    CCEGLView
*pEGLView = CCEGLView::sharedOpenGLView();

    pDirector->setOpenGLView(pEGLView);

    CCSize
frameSize = pEGLView->getFrameSize();

    float

ratio = frameSize.width / frameSize.height;

    float

ratio1 = largeDesignResolutionSize.width / largeDesignResolutionSize.height;

    float

ratio2 = mediumDesignResolutionSize.width / mediumDesignResolutionSize.height;

    float

ratio3 = smallDesignResolutionSize.width / smallDesignResolutionSize.height;

    float

d1 =
abs(ratio
- ratio1);

    float

d2 =
abs(ratio
- ratio2);

    float

d3 =
abs(ratio
- ratio3);

    std::map<float,
CCSize> designSize;

    designSize[d1]
= largeDesignResolutionSize;

    designSize[d2]
= mediumDesignResolutionSize;

    designSize[d3]
= smallDesignResolutionSize;

    std::map<float,
CCSize>::reverse_iterator iter = designSize.rbegin();

    //得到key最大的,因此我这里是横屏,所以以高度为基准,为了确保缩放后宽度能全屏,所以选取宽高比最大的为设计方案

    CCSize
designResolutionSize = iter->second;

    //pEGLView->setDesignResolutionSize(designResolutionSize.width,
designResolutionSize.height, kResolutionNoBorder);

    pEGLView->setDesignResolutionSize(designResolutionSize.width,
designResolutionSize.height, kResolutionShowAll);

    //pEGLView->setDesignResolutionSize(designResolutionSize.width,
designResolutionSize.height, kResolutionExactFit);

    if

(frameSize.height > mediumResource.size.height)

    {

        CCFileUtils::sharedFileUtils()->setResourceDirectory(largeResource.directory);

        pDirector->setContentScaleFactor(largeResource.size.height/designResolutionSize.height);

    }

    else

if

(frameSize.height > smallResource.size.height)

    {

        CCFileUtils::sharedFileUtils()->setResourceDirectory(mediumResource.directory);

        pDirector->setContentScaleFactor(mediumResource.size.height/designResolutionSize.height);

    }

    else

    {

        CCFileUtils::sharedFileUtils()->setResourceDirectory(smallResource.directory);

        pDirector->setContentScaleFactor(smallResource.size.height/designResolutionSize.height);

    }

    pDirector->setDisplayStats(true);

    pDirector->setAnimationInterval(1.0
/ 60);

    CCScene
*pScene = HelloWorld::scene();

    pDirector->runWithScene(pScene);

    return

true
;

}

(3)创建VisibleRect.h和VisibleRect.cpp文件,封装了获取那9个点坐标的函数,比较简单。代码如下:

VisibleRect.h


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

#ifndef
__VISIBLERECT_H__

#define
__VISIBLERECT_H__

#include
"cocos2d.h"

USING_NS_CC;

class

VisibleRect

{

public:

    static

CCRect getVisibleRect();

    static

CCPoint left();

    static

CCPoint right();

    static

CCPoint top();

    static

CCPoint bottom();

    static

CCPoint center();

    static

CCPoint leftTop();

    static

CCPoint rightTop();

    static

CCPoint leftBottom();

    static

CCPoint rightBottom();

private:

    static

void

lazyInit();

    static

CCRect s_visibleRect;

};

#endif

VisibleRect.cpp


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

#include
"VisibleRect.h"

CCRect
VisibleRect::s_visibleRect;

void

VisibleRect::lazyInit()

{

    if

(s_visibleRect.size.width == 0.0f && s_visibleRect.size.height == 0.0f)

    {

        CCEGLView*
pEGLView = CCEGLView::sharedOpenGLView();

        s_visibleRect.origin
= pEGLView->getVisibleOrigin();

        s_visibleRect.size
= pEGLView->getVisibleSize();

    }

}

CCRect
VisibleRect::getVisibleRect()

{

    lazyInit();

    return

CCRectMake(s_visibleRect.origin.x, s_visibleRect.origin.y, s_visibleRect.size.width, s_visibleRect.size.height);

}

CCPoint
VisibleRect::left()

{

    lazyInit();

    return

ccp(s_visibleRect.origin.x, s_visibleRect.origin.y + s_visibleRect.size.height/2);

}

CCPoint
VisibleRect::right()

{

    lazyInit();

    return

ccp(s_visibleRect.origin.x+s_visibleRect.size.width, s_visibleRect.origin.y + s_visibleRect.size.height/2);

}

CCPoint
VisibleRect::top()

{

    lazyInit();

    return

ccp(s_visibleRect.origin.x + s_visibleRect.size.width/2, s_visibleRect.origin.y + s_visibleRect.size.height);

}

CCPoint
VisibleRect::bottom()

{

    lazyInit();

    return

ccp(s_visibleRect.origin.x + s_visibleRect.size.width/2, s_visibleRect.origin.y);

}

CCPoint
VisibleRect::center()

{

    lazyInit();

    return

ccp(s_visibleRect.origin.x + s_visibleRect.size.width/2, s_visibleRect.origin.y + s_visibleRect.size.height/2);

}

CCPoint
VisibleRect::leftTop()

{

    lazyInit();

    return

ccp(s_visibleRect.origin.x, s_visibleRect.origin.y + s_visibleRect.size.height);

}

CCPoint
VisibleRect::rightTop()

{

    lazyInit();

    return

ccp(s_visibleRect.origin.x + s_visibleRect.size.width, s_visibleRect.origin.y + s_visibleRect.size.height);

}

CCPoint
VisibleRect::leftBottom()

{

    lazyInit();

    return

s_visibleRect.origin;

}

CCPoint
VisibleRect::rightBottom()

{

    lazyInit();

    return

ccp(s_visibleRect.origin.x + s_visibleRect.size.width, s_visibleRect.origin.y);

}

(4)修改HelloWorldScene.cpp的init函数,使用相对位置设置坐标。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

bool

HelloWorld::init()

{

    if

( !CCLayer::init() )

    {

        return

false
;

    }

    CCMenuItemImage
*pCloseItem = CCMenuItemImage::create(

                                        "CloseNormal.png",

                                        "CloseSelected.png",

                                        this,

                                        menu_selector(HelloWorld::menuCloseCallback));

    pCloseItem->setPosition(ccpAdd(VisibleRect::rightBottom(),

                                ccp(-pCloseItem->getContentSize().width/2,
pCloseItem->getContentSize().height/2)));

    CCMenu*
pMenu = CCMenu::create(pCloseItem, NULL);

    pMenu->setPosition(CCPointZero);

    this->addChild(pMenu,
1);

    CCLabelTTF*
pLabel = CCLabelTTF::create(
"Hello
World"
,
"Arial",
SCALE_FACTOR * 24);

    pLabel->setPosition(ccpAdd(VisibleRect::top(),

                            ccp(0,
-pLabel->getContentSize().height)));

    this->addChild(pLabel,
1);

    CCSprite*
pSprite = CCSprite::create(
"HelloWorld.png");

    pSprite->setPosition(VisibleRect::center());

    this->addChild(pSprite,
0);

    CCSprite
*pLogoSprite = CCSprite::create(
"icon.png");

    pLogoSprite->setAnchorPoint(
ccp(0, 0.5) );

    pLogoSprite->setPosition(ccpAdd(VisibleRect::left(),
ccp(50, 0)));

    this->addChild(pLogoSprite,
0);

    return

true
;

}

(5)创建窗口,main.cpp的主要内容:


1

2

3

4

5

6

7

8

9

10

11

12

AppDelegate
app;

CCEGLView*
eglView = CCEGLView::sharedOpenGLView();

    //eglView->setFrameSize(2048,
1536);

    //eglView->setFrameSize(480,
320);

    //eglView->setFrameSize(800,
480);

    //eglView->setFrameSize(1024,
768);

    //eglView->setFrameSize(1280,
800);

    eglView->setFrameSize(1280,
768);

    //eglView->setFrameSize(960,
640);

    eglView->setFrameZoomFactor(0.5f);

int

ret = CCApplication::sharedApplication()->run();

OK,到此为止,代码部分已经完成了,下面看看在各种分辨率和不同策略下的效果图:

1. kResolutionShowAll策略

(1)2048×1536

(2)1024×768

(3)480×320

(4)800×480

(5)1280×800

(6)960×640

2. kResolutionExactFit策略

1280×768分辨率

3. kResolutionNoBorder策略

1280×768分辨率

时间: 2024-08-02 07:39:04

Cocos2d适应屏幕分辨率的相关文章

NGUI之UIRoot屏幕分辨率自适应

来自:http://blog.csdn.net/oneRain88/article/details/11713299 NGUI在Unity3D游戏开发中非常常用,而NGUI对于每一个UI场景,都是以一个UIRoot为UI游戏对象树的根的,那么这个UIRoot是起什么作用的呢? 先简单看一下UIRoot中的基本属性 UIRoot游戏对象的属性只有4个,分别是缩放规则,手动高度,最小高度和最大高度 而正是这4个属性,将影响整个UI场景中整体的缩放比例,当设置好这4个属性之后,UIRoot游戏对象的相

webapp开发——‘手机屏幕分辨率’与‘浏览器分辨率’不要混淆

关于webApp响应式设计遇到的问题,分享给大家,最近在做一个手机webApp,因为我手机是”米3“,屏幕截图大小是1080宽,所以css样式用@media screen and(min-width:1080px){  …… },来判断屏幕最小宽度是1080px的手机web显示什么样的样式,结果却不能正常显示我所指定的css样式,最后在网上查了一下,发现分辨率的范围不对. css代码如下: @media screen and (min-width:1080px){ ...............

Ubuntu 更改屏幕分辨率

安装完Ubuntu后发现分辨率不合适,平时习惯了看小一点的文字,所以搜了一下修改屏幕分辨率的命令,具体操作如下: 1.先用 xrandr 命令查看一下当前系统支持的分辨率 [email protected]:~$ xrandr Screen 0: minimum 320 x 200, current 1024 x 768, maximum 8192 x 8192 VGA-1 connected primary 1024x768+0+0 (normal left inverted right x

VirtualBox中Ubuntu 14.04屏幕分辨率不能设置的问题

VirtualBox中Ubuntu 14.04屏幕分辨率不能设置的问题 ??在VirtualBOx虚拟机中Ubuntu 14.04设置屏幕分辨率,怎么点都没反应. 方法一:安装与你的Ubuntu-Guest版本最接近的VirtualBox Guest Additions版本,如下: sudo apt-get install virtualbox-guest-dkms 1 1 ??安装完所需要的包后,重启VirtualBox,便可以以合适的分辨率显示. ??如果运行的是MAC OSX,使用以下命令

屏幕分辨率(QQVGA、QVGA、VGA、XGA、WXGA、WUXGA和WSXGA+)

TFT屏幕 TFT ( Thin Film Transistor 薄膜晶体管) ,是有源矩阵类型液晶显示器(AM-LCD)中的一种,TFT在液晶的背部设置特殊光管,能够“主动的”对屏幕上的各个独立的象素进行控制,这也就是所谓 的主动矩阵TFT(aCTive matrix TFT)的来历,这样能够大大的提高反应时间,一般TFT的反映时间比較快约80ms,而STN则为200ms假设要提高就会有闪烁现象发生.并且因为 TFT是主动式矩阵LCD可让液晶的排列方式具有记忆性,不会在电流消失后立即恢复原状.

[HTML5]手机屏幕分辨率和浏览器分辨率

在使用CSS3的中有如下类似代码 Html代码 @media screen and (max-width:480px){ -- } 意思是在最大宽度为480px的设备上应用{}里面的样式.这里的width,注意是手机浏览器的分辨率,而不是手机设备的屏幕分辨率.比如苹果4的手机屏幕分辨率是960x640.而其自带的Safari浏览器的分辨率是320*480.我们可以通过如下代码检测所用的浏览器的分辨率: Js代码 $("#info").html("(您的浏览器的分辨率为:&qu

webapp开发——————手机屏幕分辨率和浏览器分辨率不要混淆

关于webApp响应式设计遇到的问题,分享给大家,最近在做一个手机webApp,因为我手机是"米3",屏幕截图大小是1080宽,所以css样式用@media screen and(min-width:1080px){  ...... },来判断屏幕最小宽度是1080px的手机web显示什么样的样式,结果却不能正常显示我所指定的css样式,最后在网上查了一下,发现分辨率的范围不对. css代码如下: @media screen and (min-width:1080px){ ......

jQuery Easy UI (适应屏幕分辨率大小)布局(Layout)

一.jQuery Easy UI (适应屏幕分辨率大小)布局(Layout) 1.首先应用的是jquery-easyui-1.4 版本(版本不同,兼容性不同) 2.实现整个页面的布局( layout: north,south,west,east, center) 3.首先整个页面布局适应屏幕的分辨率大小 4.然后内容区域进行布局,也要适应屏幕分辨率大小 5.部分代码: 1 <body> 2 <div class="easyui-layout" fit="tr

C# 代码调整屏幕分辨率

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Runtime.InteropServices;namespace 解决分辨率{    public partial cl