cocos2dx屏幕适配

首先介绍一篇很好的帖子,详细解释了各种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"
对于 CONFIG_SCREEN_WIDTH 和 CONFIG_SCREEN_HEIGHT 的配置,其实我觉得只要配置好 CONFIG_SCREEN_AUTOSCALE 和内容缩放因子,那就不会有什么问题。

因为是横屏游戏,所以我们选择了 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);代码即可实现,当游戏开发完成时删除本行代码。

1
2
3
4
5
6
if (!glview) {
         glview = GLViewImpl::create( "DefendTheGirl" );
         //设置模拟器分辨率大小
         glview->setFrameSize(960,440);
         director->setOpenGLView(glview);
  }











宽高比适配:
第一步: 按照上面解决方案的做法,在AppDelegate.cpp的applicationDidFinishLaunching方法中, 添加如下代码:
glview->setDesignResolutionSize(designResolutionSize.width, designResolutionSi
ze.height,ResolutionPolicy::FIXED_HEIGHT);




EXACT_FIT: 会拉伸素材进行显示,充满整个屏幕,最简单最粗暴,但是可能会出现图像变形。结论
:看游戏截图效果确实像描述的一样出现了图像变形,无论手机屏幕是何种宽高比的,里面是素材
一律按照填满手机屏幕的宽高比对素材进行拉伸变形,我想这个方法肯定不可取。
NO_BORDER:短边占满屏幕,另外一侧超出屏幕,一部分画面在屏幕外,无法显示。
对于NO_BORDER解释:短边占满屏幕,另外一侧超出屏幕,一部分画面在屏幕外,无法显示。这里说的短边并不是指素材本身宽和高中短的那边,而是素材宽和手机宽进行比较,素材高和手机高进行比较,那个差值小就算是短边,比如第一种尺寸的时候,宽差值=|素材的宽960px-手机屏幕宽960px|=0,高差值=|素材的高640px-手机屏幕宽440px|=200,所以短边是素材的宽。我想这个方法宽高适应和设备的宽高比有关,也就是哪个是短边不一定由设备决定。

SHOW_ALL: 保持原比例,让一边占满屏幕,另外一侧黑边
结论:这个方式好像看起来相对合理点,画面肯定保持原来素材的比例不会拉伸变形等,但是比较遗憾的是手机的左右两边或者上下两边会出现黑色的空白区除非素材的宽高比恰好和手机的宽高比相同。我想这个方式对我们这个游戏来说也可选,但是有黑边不是最佳的用户体验,但是用这个方式最简单可以在任何设备中保持游戏真实的画面。
FIXED_HEIGHT:NO_BORDER类似,但是指定高占满屏幕,宽部分超出屏幕外,无法显示。
结论:这个方式好像和NO_BORDER有点像,上面两种尺寸屏幕测试结果均表现为素材高占满手机屏幕的高,而宽要不超出屏幕要不小于屏幕,素材仍旧维持本身的宽高比,同时游戏背景上的人物位置有一定的偏移,这个方式对我们这个游戏来说也不是很合适。
FIXED_WIDTH: NO_BORDER类似,但是指定宽占满屏幕,高部分超出屏幕外,无法显示。
结论:这个方式好像和NO_BORDER有点像,上面两种尺寸屏幕测试结果均表现为素材宽占满手机屏幕的宽,而高要不超出屏幕要不小于屏幕,素材仍旧维持本身的宽高比,同时游戏背景上的人物位置有一定的偏移。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值