FrameSize:实际上就是设备的原始分辨率,开发环境中可以通过CCEGLView::sharedOpenGLView()->setFrameSize()来设置设备的分辨率大小,当然也可以可以通过CCEGLView::sharedOpenGLView()->getFrameSize()获取得到设备的分辨率
WinSize:开发所设计的分辨率,即setDesignResolutionSize方法中传入的前两个参数,通过CCDirector::sharedDirector()->getWinSize()获取
VisibleSize:一定小于等于WinSize,即在WinSize范围之内,保持FrameSize宽高比的最大显示区域。
VisibleOrigin:在WinSize下被FrameSize截取的区域大小,即设计分辨率中与屏幕左下角对应的点。
第二,cocos2D-x自带的三种适配方案
这里我们将设备的分辨率改为768*1024,开发设计的分辨率为640*960,背景图为大小为640*960,在屏幕居中显示,cocos2d-x默认的适配方案得到的效果:
可以看出由于没有采用合理的适配方法,图像会根据我们设置的位置显示大小,如果图像本身比设备分辨率大,则只显示设备分辨率大小的图像,反之则会留有空余处,如上图的黑边。如我们采用下面三种基本的适配方案又会得到不同的效果
kResolutionExactFit:通过拉伸来填满屏幕,宽高比不同,图片无法等比缩放来填充屏幕,图片会扭曲变形,如图中间的人物原先是正方形的,现在变成了长方形,界面稍复杂,就会看见明显的不协调,这种方式通常不可取。
kResolutionNoBorder:无黑边,宽高等比缩放,但缩放的比例按照宽比和高比中大的来进行。这样出现的结果可能就是有图片的一部分会显示在屏幕的外面。
kResolutionShowAll:全部显示,保证内容在屏幕内显示,同样是宽高等比缩放,但缩放比例取小的进行。按这种方式适配可能会在屏幕上出现黑边,如果打算在黑边出填放别的精灵是无效的,因为等比缩放后,黑边的部分不会进行绘制。假如设计分辨率低于大部分设备分辨率,在忽略黑边的情况下,这种适配方式可以满足大部分设备,而我们后面改进的适配方案就是把留出来的黑边利用上
以上三种适配方式虽然能在一定问题上能解决适配的问题,不过对于现今各式各样、众多分辨率的设备来说,想要一套资源适配所有设备而不做资源的更改是不可能的,这点必须明白。没有一种完美的适配方案,而我们所做的不过是尽量更完善,那如何找到一种行之有效的适配方案呢?在保持图像基本不变形的情况下我们可以对第二种,第三种适配方案进行改进。
根据设备分辨率改变WinSize的大小:
由这个思路,假如我们预设WinSize为(640,960),先计算设备分辨率和设计分辨率的宽比与高比
float scaleX=frameSize.width/designSize.width;
float scaleY=frameSize.height/designSize.height;
在第三种方案基础上进行改进,依旧选择宽高比小的进行缩放,这里选择scaleY,由于第三种方案会产生黑边,而我们又无法利用黑边,所以改进的方案就是把黑边利用上,那如何利用上呢?前面说过,黑边是由于宽高比例不同造成的,这样我们可以反过来思考,让设备分辨率和设计分辨率宽高比一致。所以在这种前提下,我们得到了一种解决办法,假设设备两者的宽高比一致的情况下,WinSize的宽高为多少才合适,在本例中我们需要算出WinSize的宽,计算方法如下:
frameSize.width/scaleY;
将计算出来的宽和我们预设的设计分辨率的高作为传入的WinSize的值,这样我们就能把黑边利用上了
pEGLView->setDesignResolutionSize(frameSize.width/scaleY,designSize.height,kResolutionShowAll);
但运行的结果和kResolutionShowAll似乎一样,这是因为黑边我们虽然已经可以利用了,但没有显示效果,这里我们现在已经可以对黑边进行填充了,效果如下: