cocos2d-x自制工具09:复活!x2屏幕适配方案

简介:

适配屏幕的方案主要看游戏类型,游戏类型决定了是否需要滚屏。不同的游戏类型,决定了不同屏幕适配方案。


对于市面上大量存在的卡牌,单屏休闲益智类游戏,往往拼的是速度。但是恼人的屏幕适配问题,一直困扰了很多企业。


之前简单收集了一下市面上的各种分辨率。

480X800  现在最主流的中高端安卓智能机的分辨率,包括 windows phone也是这个分辨率

480X854  这个是WFVGA,是480X800的加长版


540X960  HTC的高端机很喜欢用这个分辨率也就是qHD了

640X960 最经典的iphone所使用的分辨率

1136X640  iphone5的分辨率

1280X720  传说中的HD,也是现在各品牌主流旗舰机型的分辨率,而且屏幕都很大。

1280X800  现在只有三星的9220的5.3英寸巨屏用了这以分辨率


1024x768    iPad1分辨率 iPad2分辨率 iPad mini分辨率

2048×1536  iPad3分辨率 iPad4分辨率 iPad Air分辨率 iPad mini 2分辨率


1920x1080 Nexus5分辨率


这么多分辨率,很头痛。这种情况下,我们一般使用的是固定一个分辨率,然后缩放的方式。Cocos2d-x引擎内置了很多这种分辨率适配方案。主要使用这个函数:

1
void  CCEGLViewProtocol::setDesignResolutionSize( float  width,  float  height, ResolutionPolicy resolutionPolicy)


ResolutionPolicy的参数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
enum  ResolutionPolicy
{
     // The entire application is visible in the specified area without trying to preserve the original aspect ratio.
     // Distortion can occur, and the application may appear stretched or compressed.
     kResolutionExactFit,
     // The entire application fills the specified area, without distortion but possibly with some cropping,
     // while maintaining the original aspect ratio of the application.
     kResolutionNoBorder,
     // The entire application is visible in the specified area without distortion while maintaining the original
     // aspect ratio of the application. Borders can appear on two sides of the application.
     kResolutionShowAll,
     // The application takes the height of the design resolution size and modifies the width of the internal
     // canvas so that it fits the aspect ratio of the device
     // no distortion will occur however you must make sure your application works on different
     // aspect ratios
     kResolutionFixedHeight,
     // The application takes the width of the design resolution size and modifies the height of the internal
     // canvas so that it fits the aspect ratio of the device
     // no distortion will occur however you must make sure your application works on different
     // aspect ratios
     kResolutionFixedWidth,
     kResolutionUnKnown,
};


这些参数的含义,很多文章都分析过了,我们简单说一下:

kResolutionShowAll

等比例拉伸,直到宽度或高度达到屏幕的尺寸,但是:如果游戏的设计分辨率比率和设备的屏幕分辨率比率不同,最后会出现黑边。结论:无法使用,黑边出现不符合很多渠道和应用商店的规范。

kResolutionExactFit

非等比例拉伸,图像拉伸到整个屏幕。但是:如果游戏的设计分辨率比率和设备的屏幕分辨率比率不同,最后游戏画面失真。结论:可以使用,但是效果很差。

kResolutionNoBorder

等比例拉伸,直到宽度或高度达到屏幕尺寸,且保证在另一方向上不会出现黑边。但是,他只是简单的拉伸处理,对于座标偏移没有控制,造成最后代码中要手动计算座标VisibleSize 和 VisibleOrigin,这不符合正常的开发习惯。结论:可以使用,但是座标计算很繁琐。


由于上面的种种问题,引擎团队最后又增加了两个新参数

kResolutionFixedHeight和kResolutionFixedWidth,这两个参数作用和kResolutionNoBorder类似,但是内部座标经过了处理,不像kResolutionNoBorder那么麻烦。


我们的方案就基于这两个参数。

该方案的前提与目的:

我们的目标是重建当初的x2的那种适配方式,有两套资源,一套SD,一套HD。在此基础上,做到座标系通用,UI资源通用。仅仅是图片的清晰度不同。这是对于中小团队来说最快速的适配方案。


下面贴核心代码,修改AppDelegate::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
     CCSize frameSize = pEGLView->getFrameSize();
     if  (frameSize.width ==  640  && frameSize.height ==  960 )
     {
         //标准分辨率,不做调整
     }
     else  if  (frameSize.width ==  640  && frameSize.height ==  1136 )
     {
         //标准分辨率,不做调整
     }
     else
     {
         CCSize winSize;
#ifdef HD_PORT_SCHEME
         if  (frameSize.width*frameSize.height>= 2073600 ) { //1080p分辨率
             //HD资源
             winSize=CCSize( 1280 1920 );
             pDirector->setContentScaleFactor( 2 );
         }
         else {
             //SD资源
             winSize=CCSize( 640 , 960 );
         }
# else
         //SD资源
         winSize=CCSize( 640 , 960 );
#endif
                                                                                                                                                                                                                                                        
         //WHR宽高比 width height ratio
         float winSizeWHR = winSize.width / winSize.height ;
         float frameSizeWHR = frameSize.width / frameSize.height;
                                                                                                                                                                                                                                                        
         if  (winSizeWHR > frameSizeWHR)
             pEGLView->setDesignResolutionSize(winSize.width, winSize.height, kResolutionFixedWidth);
         else
             pEGLView->setDesignResolutionSize(winSize.width, winSize.height, kResolutionFixedHeight);
     }



说明:

1.我们以960x640作为标准分辨率

2.以1080p判断作为基准,来判断是否启用HD资源。

3.判断宽高比,以决定缩放方向

4.HD_PORT_SCHEME宏来决定是否启用HD适配方案,如果关闭,则全部设备上都是SD资源的低清方案。


其他注意事项:

1.如果启用HD方案,在高清设备上,场景根节点需要放大setScale(2)

2.如果启用HD方案,触摸时的座标点需要处理,经过换算变成960x640下的。好在这种代码很少在触摸回调时增加一下即可。

3.理论上,所有的工具输出的资源都支持这种方式来做适配。也就是说,对于程序,策划来说只用一套SD资源开发即可。美术先出HD图,然后缩成SD提供给开发用。


题外话:对于很多复杂的游戏,UI和场景应该是彻底分开来做的,因为这两个需求不同,清晰度要求和资源提供也可能有很大差别,但是引擎本身似乎没有考虑这一点。有些分支是做了的,把UI和场景拆成两个节点,这是不错的设计。


最后,本来还想做个详细的例子,但是最新版引擎3.0beta2的工程模板老出问题,新建工程在win8上面始终无法打开,等稳定一下再补吧。




 本文转自 老G 51CTO博客,原文链接:http://blog.51cto.com/goldlion/1361420,如需转载请自行联系原作者


相关文章
Cocos2dx-x tiledmap缝隙问题分析以及解决方案
Cocos2dx-x tiledmap缝隙问题分析以及解决方案
189 0
|
4月前
|
定位技术 API 开发者
【Godot引擎开发】简单基础,外加一个小游戏DEMO
【Godot引擎开发】简单基础,外加一个小游戏DEMO
|
4月前
微信小游戏制作工具关于游戏屏幕适配,看这篇就够了!
微信小游戏制作工具关于游戏屏幕适配,看这篇就够了!
82 0
|
11月前
|
Java
手把手一步一步教你使用Java开发一个大型街机动作闯关类游戏08控制sprite移动
手把手一步一步教你使用Java开发一个大型街机动作闯关类游戏08控制sprite移动
106 0
|
11月前
|
Java
手把手一步一步教你使用Java开发一个大型街机动作闯关类游戏06加载游戏背景
手把手一步一步教你使用Java开发一个大型街机动作闯关类游戏06加载游戏背景
103 0
|
监控 API iOS开发
iOS触动精灵模拟触控类外挂原理分析
一、外挂功能: 类似于模拟按键,该类型外挂主要用于通过图像识别,利用luac脚本对图像进行识别。而后再通过私有api实现触屏操作的功能。     二、外挂特征 外挂安装后,会有下面三个主要程序,touchsprite,tsevent,tsdeamon. 其中,touchsprite 为gui的界面程序,其主要功能为提供交互界面由用户选择加载的脚本。(脚本保存在/Us
4139 0

热门文章

最新文章