cocos2d 3.0 屏幕适配

1.解决方案

 

先直接给出解决方案,再慢慢解释,当然这个解决方案也不是完全完美的。

//如果是横屏游戏:
glview->setDesignResolutionSize(960, 640, ResolutionPolicy::FIXED_HEIGHT);
//一张960x640的背景显示
	auto visibleSize = Director::getInstance()->getVisibleSize();
	auto Bg = Sprite::create("Bg.png");
	this->addChild(Bg);
	Bg->setPosition(visibleSize.width / 2, visibleSize.height / 2);
	//Bg->setPosition(visibleSize.width / 2, 320);//等价上面的
	Bg->setScaleX(visibleSize.width / 960);

	//右上角显示一个精灵
	auto Spr = Sprite::create("test.png");
	this->addChild(Spr);
	Spr->setPosition(visibleSize.width - 50, visibleSize.height  - 50);
	//因为是固定高度,所以visibleSize.height永远都是640,所以下面的写法也是可以的
	//Spr->setPosition(visibleSize.width - 50, 590);

//如果是竖屏游戏:
glview->setDesignResolutionSize(640, 960, ResolutionPolicy::FIXED_WIDTH);

 

美术出图都按照960×640规格出图。

 

2.开始测试各种适配方式

 

屏幕适配其实应该从Opengles开始讲的,这里跳过了,感兴趣的可以看这篇文章了解一二Android 中使用OpenGL ES进行2D开发(绘制第一个三角形番外篇)》

glview->setDesignResolutionSize(960, 640);先不管第三个参数。setDesignResolutionSize是什么意思呢?就是设置一个固定大小的区域来进行程序布局和美术设计。再通过Opengles进行投射到具体手机屏幕上去,是无视具体手机屏幕大小的。比如手机屏幕分辨率是480×320,Opengles会自动缩小一倍进行投射。手机屏幕分辨率是1920×1280,Opengles会自动放大一倍进行投射。程序和美术这块都不需要改:一套程序坐标,一套美术资源。

 

比如背景图片,只需要一张960×640的就OK了,把它放在(480,320)的中心位置就OK了。

一个精灵假设要放在右上角的位置,把它放在(960,640)的位置就OK了。也根本不需要考虑cocos2d中的visibleSize什么的。

 

现实中,手机分辨率不可能都是960×640的倍数。而我们又要全屏显示,就有了第三个参数来规定具体投射的方式。

cocos2d的ResolutionPolicy现在总共有5种:

enum class ResolutionPolicy
{
    EXACT_FIT,
    NO_BORDER,
    SHOW_ALL,
    FIXED_HEIGHT,
    FIXED_WIDTH
};

 

2.1 EXACT_FIT

 

EXACT_FIT是会完全投射到屏幕全屏的。这样对程序和美术来说是最完美的,但是会有拉伸的现象。

 

 

上面这张是960×540的原图,4个角我加上了参照物,总的是一张图片。

假设目标手机分辨率是1136×500(现实是不存在的),使用EXACT_FIT就是下面的效果:

 

 

其实对于背景的拉伸,还是可以接受的,主要的问题是:精灵也会被拉伸,还有拉伸区域是不可控制的。

EXACT_FIT适用场景:个人小项目,轻微拉伸不影响游戏的展示的游戏。但公司大项目这个基本不可用。

使用EXACT_FIT的时候,visibleSize不管手机分辨率是多少,visibleSize永远都是960×640。

 

2.2 SHOW_ALL

 

先来解释下Show_All.它不会拉伸,但是左右或者上下会有黑边,没有全屏的感觉。

1136×640

 

1024×768

 

Show_ALL 能不能用呢?几乎不能用。虽然它的visibleSize都是960×640。但是黑边的问题,苹果那边是通过不的。这里的黑边是不能用东西来覆盖的。

 

2.3 NO_BORDER

 

NO_BORDER 顾名思义就是没有黑边,且保持宽高比。这样的结果就是,会有部分被裁剪掉。

1136×640

 

手机分辨率比较长的时候,上下不够,会被裁掉,注意看背景下面的参考物。

visibleSize width:960

visibleSize height:540.8450927734375  //不到640

 

1024×768

 

IPad分辨率比较高的时候,左右不够,会被裁掉,注意看背景左边的参考物。

visibleSize width:853.3333129882812  //不到960

visibleSize height:640

使用NO_BORDER会导致visible一直变化,且会被裁掉。

 

2.4 FIXED_HEIGHT

 

FIXED_HEIGHT和FIXED_WIDTH是类似的,就讲个FIXED_HEIGHTFIXED_HEIGHT和FIXED_WIDTH是较高cocos2d版本才有的。这个解决方案是固定一个方向上的值,且固定比例。这样会导致部分覆盖不到或者部分被裁掉,要程序进行动态适配。

1136×640

 

图7

 

visibleSize width:1136 //会根据手机屏幕分辨率进行变化

visibleSize height:640 //永远固定是640

1024×768

visibleSize width:854 //会根据手机屏幕分辨率进行变化

visibleSize height:640 //永远固定是640

 

图7虽然这里的效果看起来跟SHOW_ALL的一样,但是是完全不一样的,通过看visibleSize就知道了。这里的黑边我们是可以通过手动拉伸背景来覆盖的。有人就问了,拉伸背景不就跟EXACT_FIT的一样了?不一样的!EXACT_FIT是拉伸整个区域,场景放置的精灵也是会被拉伸的。FIXED_HEIGHT就不会拉伸精灵了。

精灵放置的位置就有讲究了,在纵向,完全可以使用魔鬼数字,320肯定是垂直居中的。横向就要斟酌了,比如要把一个精灵放在右上角就要考虑visibleSize了。

setPosition(visibleSize.width – 50, 640  – 50);

下面是简单拉伸背景的效果,加上一个精灵。

 

var visibleSize = cc.Director.getInstance().getVisibleSize();
        var scaleRate = visibleSize.width / 960;

        var bg = cc.Sprite.create("res/bg.jpg");
        this.addChild(bg);
        bg.setPosition(visibleSize.width / 2, visibleSize.height / 2);
        bg.setScaleX(scaleRate);
        var sp = cc.Sprite.create("res/menu1.png");
        this.addChild(sp);
        sp.setPosition(100 * scaleRate,320);

1136×640

 

1024×768

其他安卓的分辨率就不列出来了。

 

3.讲讲资源适配

 

我们知道一套图片你想要同时适配960×640, 2048×1536或者将来的IPhone6 Plus 1920×1080,是很困难的。主要的问题是,如果你都是一套960×640的图片,那么在高分辨率下就不清楚了。如果你是一套1920×1280的图,那么在低分辨率的手机上运行比较卡。上面例子都是使用了960×640的分辨率作为设计分辨率,可以考虑将来手机分辨率就都比较高的时候上升点,比如上升到1248×832。

 

还有个问题是屏幕高宽比的问题,IPad是1024/768 即1.33 这个比例都比960/640 的1.5的要低,而IPhone5,IPhone6的屏幕高宽比例上升到1.775。在加上Android的屏幕高宽比。可以考虑未来使用1.6的比例。比如1248×780作为设计分辨率。然后IPad上要格外小心要特殊处理,横向,个别UI要进行缩小适配。

没有两全其美的做法,要不准备2套资源,这样游戏包会比较大。现在一般都准备一套低分辨率的资源,其实在高分辨上看起来也不会太差。当然如果你的游戏是IPad游戏,那就要好好斟酌。

 

3.还准备了了一个exe可以玩耍

 

可以下载程序自己调试着玩下。http://www.waitingfy.com/?attachment_id=1314

exe在\runtime\win32\PrebuiltRuntimeJs.exe  Win7应该可以打开,XP应该不行。

在Config.json中的init_cfg可以调整设备的分辨率。

main.js中可以调整DesignResolutionSize和适配方式。

app.js可以改背景等位置。项目是cocos2d js方便调试,但原理是一样的。

多玩玩才能理解。

http://www.waitingfy.com/archives/1304

1304

Leave a Reply

Name and Email Address are required fields.
Your email will not be published or shared with third parties.