首先介绍一篇很好的帖子,详细解释了各种size
http://www.360doc.com/content/13/0601/12/110467_289667212.shtml
其次:
Cocos2d-x中图片显示到屏幕有下面两个逻辑过程,两个过程结合在一起,影响了最终的显示效果。
1、资源布局到设计分辨率
2、设计分辨率布局到屏幕
其中设计分辨率是指我们在config文件中设置的CONFIG_SCREEN_WIDTH 和 CONFIG_SCREEN_HEIGHT,它相当于一个参考分辨率。只有确定了我们的参考分辨率,才能得到我们的图片资源的缩放比例。
在第一个过程中,我们需要通过以下函数来完成相应的转换:
cc.Director:getInstance():setContentScaleFactor(value)
setContentScaleFactor方法决定了图片资源显示到屏幕的缩放因子,顾名思义就是决定了整个游戏内容放大或者缩小的比例系数。
它的参数由(背景图片资源宽高/设计分辨率宽高)得到,而不是通过(背景图片资源宽高/屏幕宽高)得来。这样也就避开了游戏开发者去直接关注移动设备的实际屏幕。
setContentScaleFactor通常会用两个方式来设置参数,不同的设置方法会有不同的缩放负作用。
1、用(资源高/设计分辨率高)的高度比作为参数,也就是内容的缩放因子,这样保证了背景资源的垂直方向在设计分辨率范围内的全部显示,但在水平方向上可能会溢出屏蔽或留有黑边。
2、用(资源宽/设计分辨率宽)的宽度比作为内容缩放因子,保证了背景资源的水平方向在设计分辨率范围内的全部显示,但在垂直方向上可能会超出屏蔽范围或留有黑边。
第二个过程中,我们需要通过以下函数接口完成转换:
setDesignResolutionSize(width, height, cc.ResolutionPolicy)
setDesignResolutionSize方法会在display.lua中被调用,所以这里我们不用管它,只需要注意它的参数设置就好。
其中参数 width 和 height 指的是设计分辨率的宽、高,cc.ResolutionPolicy 是分辨率适配策略,它们分别由config.lua文件中的 CONFIG_SCREEN_WIDTH、CONFIG_SCREEN_HEIGHT 和 CONFIG_SCREEN_AUTOSCALE来设置。
Quick中CONFIG_SCREEN_AUTOSCALE的值有三种情况:
- FIXED_WIDTH:保持传入的设计分辨率宽度不变,根据屏幕分辨率修正设计分辨率的高度。
- FIXED_HEIGHT:保持传入的设计分辨率高度不变,根据屏幕分辨率修正设计分辨率的宽度。
- FILL_ALL:保证了设计区域总有一个方向铺满屏幕,另一个方向可能超出屏幕或留有黑边。
以上两个过程相辅相成,它们相互影响,所以做好分辨率适配必须确保两步坚固。
说到这里我不得不提的是,在做分辨率适配的时候,常有人忽略以上的第一个过程,因此作为小白的我还是会经常遇到那么一些人问:为什么我的分辨率适配护好了还是有黑边,还是有问题?
对此我要说:请设置内容缩放因子。
如果要做横屏的游戏,建议还是要做到让背景图在高度方向上全部显示,所以显然地,如果高度方向上全部显示,那么在宽度方向上必然会做出一些牺牲(要么被裁减,要么留黑边(留黑边的问题可以通过将图片宽度做得更宽一点来解决))。
要实现这上述目标,需要保证各过程都是在宽度方向上裁减。所以我们给出了以下的实现过程:
1、首先我们选择 1136 x 640 的图片资源,这样宽高比够大,能确保在某些极端的分辨率下也能完整不留黑边的显示整个游戏画面。
2、接着打开src/config.lua
,设置配置信息,如下:
1
2
3
4
|
CONFIG_SCREEN_ORIENTATION =
"landscape"
CONFIG_SCREEN_WIDTH = 480
CONFIG_SCREEN_HEIGHT = 320
CONFIG_SCREEN_AUTOSCALE =
"FIXED_HEIGHT"
|
因为是横屏游戏,所以我们选择了 FIXED_HEIGHT 作为适配模式——让 Y 轴方向能完全显示在屏幕上。
此外:
影响游戏的两个因素屏幕大小(分辨率)、宽高比,屏幕大小从小屏的480×320手机到大屏甚至平板的2048×1536,如果用低分辨率的素材图在高分辨率的设备上就会图像模糊,如果用高分辨率的素材在低分辨率设备上时增加系统负担,所有一般我们采取多套不同分辨率素材进行匹配,这个问题还算容易解决。但是宽高比就麻烦的多,手机有3:2,16:9 标准宽屏等。宽高比会造成游戏不按比例的压缩或者拉伸造成游戏上的元素显示、位置等发生变异甚至导致游戏无法使用,所以宽高比造成的问题比屏幕大小要严重的多。
那宽高比是否也可以像分辨率一样采用多套宽高比的素材解决?肯定可以!但是如果不同的宽高比结合不同的分辨率这样得提供多少套的素材啊?并且新的宽高比的手机在不断的新出来为了每出一款手机就做一套素材这样的成本太大。
在cocos2d-x-3.3/tests目录下有一个名为cpp-empty-test示例工程,用Microsoft Visual Studio 2012打开proj.win32下的工程,可以看到它对于这个问题的解决方案,参考其中的AppMacros.h、AppDelegate.cpp、Resources目录下的素材。
结合上面介绍,总结如下:
1、屏幕大小(分辨率)解决方案
按照上面的思路提供多套的素材,一般游戏做法提供低、中、高、超高四套不同的分辨率的素材,低的应付一般小屏手机、中的应付高分辨率手机、高的应付平板、超高的应付高清平板或者电视之类的设备。四套素材分4个文件夹放置到项目Resources文件下比如叫iphone、iphonehd、ipad、ipadhd。在设备载入游戏时,判断当前设备的分辨率然后选择不同文件夹下的素材进行载入以适应不同分辨率的设备。
2、宽高比解决方案
为了适应设备各种屏幕宽高比,在 Cocos2dx中,提供了相应的解决方案,以方便我们在设计游戏时,能够更好的适应不同的屏幕。Cocos2dx提供了ResolutionPolicy(分辨率策略),通过给GLView设置不同ResolutionPolicy来解决这个问题。
ResolutionPolicy的五种类型:
1、EXACT_FIT
2、NO_BORDER
3、SHOW_ALL
4、FIXED_HEIGHT
5、FIXED_WIDTH
具体的步骤是:
1、先制作iphone、iphonehd两套素材,然后拷贝到项目的Resources文件下,我们这款游戏的目标是手机类的设备,所以就只提供了两套分辨率的素材,如果需要对更高分辨率的设备进行支持那么需要提供更多套的素材。个人建议如果你的游戏需要支持平板,那么建议单独出个HD版,虽然通过代码和素材的适配能同时支持手机和平板设备,但是这样的实现还是有一定的限制,会一定程度上降低某类设备的可玩性。
2、
新建AppMacros.h文件,把cpp-empty-test示例工程下同名的文件代码直接拷贝过来进行修改,只需要保留两种不同的分辨率代码即可:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#define DESIGN_RESOLUTION_480X320 0
#define DESIGN_RESOLUTION_960X640 1
/* If you want to switch design resolution, change next line */
#define TARGET_DESIGN_RESOLUTION_SIZE DESIGN_RESOLUTION_960X640
typedef
struct
tagResource
{
cocos2d::Size size;
char
directory[100];
}Resource;
static
Resource smallResource = { cocos2d::Size(480, 320),
"iphone"
};
static
Resource mediumResource = { cocos2d::Size(960, 640),
"iphonehd"
};
#if (TARGET_DESIGN_RESOLUTION_SIZE == DESIGN_RESOLUTION_480X320)
static
cocos2d::Size designResolutionSize = cocos2d::Size(480, 320);
#elif (TARGET_DESIGN_RESOLUTION_SIZE == DESIGN_RESOLUTION_960X640)
static
cocos2d::Size designResolutionSize = cocos2d::Size(960, 640);
#else
#error unknown target design resolution!
#endif
// The font size 24 is designed for small resolution, so we should change it to fit for current design resolution
#define TITLE_FONT_SIZE (cocos2d::Director::getInstance()->getOpenGLView()->getDesignResolutionSize().width / smallResource.size.width * 24)
3、
打开AppDelegate.cpp文件,添加对AppMacros.h的引用,然后applicationDidFinishLaunching方
法里添加对当前设备屏幕分辨率进行判断然后设置不同的图片素材:
#include <vector>
#include <string>
#include "AppMacros.h"
……
//获取当前设备屏幕尺寸
Size frameSize = glview->getFrameSize();
vector<string> searchPath;
//如果屏幕尺寸宽>smallResource素材尺寸宽
if
(frameSize.width > smallResource.size.width)
{
//使用mediumResource目录下的素材
searchPath.push_back(mediumResource.directory);
float
scale=mediumResource.size.width/designResolutionSize.width;
director->setContentScaleFactor(scale);
}
else
{
//使用smallResource目录下的素材
searchPath.push_back(smallResource.directory);
float
scale=smallResource.size.width/designResolutionSize.width;
director->setContentScaleFactor(scale);
}
// 设置素材路径目录
FileUtils::getInstance()->setSearchPaths(searchPath);
……
通过这段代码,我们解决了低分辨率手机和高分辨率手机的图片素材适配问题。如何测试效果呢? 分别找个低分辨率的的手机和高分辨率的手机?这样太麻烦了,其实只需要一行代码就可以直接在 调试时模拟不同分辨率的手机效果,在applicationDidFinishLaunching方法中添加一行glview->setF rameSize(960,440);代码即可实现,当游戏开发完成时删除本行代码。
|