需求:由于各个设备的分辨率和尺寸并不一样,所以需要一套适配系统去很好的针对不同的设备分辨率或尺寸进行适配,以给玩家一个很好的游戏体验。
目前的主流适配方案
目前,针对不同设备的适配,主流的方案通常包括以下几种:
-
响应式设计(Responsive Design):
-
响应式设计是一种流行的Web设计方法,通过使用CSS媒体查询等技术,使网站能够根据用户的设备(如手机、平板、桌面电脑)自动调整布局和样式。
-
这种方法可以使网站在不同设备上呈现出最佳的用户体验,但在游戏开发中的应用相对较少。
-
-
流式布局(Fluid Layout):
-
流式布局是一种设计方法,其中元素的宽度是相对于父容器的百分比,而不是固定像素值。这样可以使布局在不同屏幕尺寸下自动调整。
-
在游戏开发中,可以通过使用相对单位(如百分比)和布局技巧来实现流式布局,以适应不同设备的屏幕尺寸。
-
-
断点布局(Breakpoint Layout):
-
断点布局是一种设计方法,通过在特定屏幕宽度处设置断点(breakpoint),在不同屏幕尺寸下应用不同的布局和样式。
-
在游戏开发中,可以根据设备的屏幕宽度设置断点,针对不同尺寸的设备应用不同的布局和适配方案。
-
-
自适应设计(Adaptive Design):
-
自适应设计是一种根据设备特性和屏幕尺寸调整布局和功能的设计方法。可以根据设备的特征(如分辨率、屏幕尺寸等)提供不同的用户体验。
-
在游戏开发中,可以根据设备的特性动态调整游戏界面的布局、分辨率和功能,以提供最佳的用户体验。
-
Cocos Creator提供的适配方案
分辨率适配:
Cocos Creator支持多种分辨率适配策略,其通过以下几个部分完成多分辨率适配解决方案:
-
Canvas(画布) 组件随时获得设备屏幕的实际分辨率并对场景中所有渲染元素进行适当的缩放。
-
Widget(对齐挂件) 放置在渲染元素上,能够根据需要将元素对齐父节点的不同参考位置。
-
Label(文字) 组件内置了提供各种动态文字排版模式的功能,当文字的约束框由于 Widget 对齐要求发生变化时,文字会根据需要呈现完美的排版效果。
-
Sliced Sprite(九宫格精灵图) 则提供了可任意指定尺寸的图像,同样可以满足各式各样的对齐要求,在任何屏幕分辨率上都显示高精度的图像。
详细介绍可阅读该部分的官方文档:多分辨率适配方案 | Cocos Creator
多分辨率资源管理:
-
可以使用Cocos Creator的资源管理系统,为不同分辨率的设备提供对应的资源,确保游戏在不同设备上显示效果良好。
-
可以通过预加载资源或动态加载资源的方式,根据设备分辨率来加载适合的资源。
代码适配:
-
可以通过编写灵活的代码逻辑,根据设备的特性动态调整游戏界面的布局和功能。
-
可以使用条件判断、设备信息查询等方式,在运行时根据设备的不同特性进行适配处理。
Cocos creator在cc.sys中提供了丰富的关于获取用户设备信息的一系列API,包括获取手机型号、屏幕分辨率、是否是IPad、本地存储等;
具体可查看该官方文档:Cocos Creator 2.4 API - sys
自定义的适配方案
目前在游戏开发中所使用的主要适配方案是自适应设计。
主要是通过大量使用Canvas、Widget和Label组件来完成分辨率的适配,同时利用脚本获取用户屏幕分辨率或设备型号来完成需要动态加载的界面的适配。因为如果只是使用Cocos Creator的组件,是完全无法解决问题的,这时由于Canvas的局限性所致的,具体不详细说明了,所以需要使用到自定义的适配方案。以设计尺寸为1334x750为例。
由于我们的游戏设计尺寸就是1334x750,也就是宽高比1.778(16:9),所以只要屏幕尺寸为16:9的手机,都是可以完美的适配,即所有UI的位置和设计时的位置相比不会产生任何变动,虽然目前很多的手机都是16:9,但是19:9的手机也有很多,目前对于宽高比大于16:9的做法有两种·,1是采用一张比较宽的背景图(w:1624),2是在某些类中单独做了判断,针对屏幕尺寸大于1334的设备进行了设置尺寸处理,但是通用的还是采用第一种做法。主要的问题就是在宽高比小于16:9的机型上适配上有很大的问题,虽然目前这种机型占比非常小,但是依旧是存在的。原因是由于子物体的相对位置虽然随着根节点的位置变动(尺寸改变所导致)而变动,但是子物体的尺寸并没有产生任何改变,这就导致UI看起来会挤在一起。
下面讲述搭建一个自适应界面的详细流程:
-
搭建游戏主界面(需要勾选Canvas的Fit Height)
-
为一些层级添加widget
-
添加适配方法以适配不同尺寸的手机
TypeScript
protected fitScreen(): void {
this.node.setContentSize(cc.winSize);//设置根节点尺寸为屏幕尺寸
const designSize = 1334/750;//设计尺寸
const realSize = cc.winSize.width/cc.winSize.height;//实际尺寸
if (this.nodeAlert && realSize<designSize)
{
this.nodeAlert.setScale(realSize/designSize); //设置子节点的缩放
}
}
层级构建如下;
node对应根节点(CommonAlert),nodeAlert对应子节点(Alert),内容则放在子节点下。
首先是设置界面的尺寸等于屏幕尺寸,然后是计算设计尺寸和实际尺寸,如果实际尺寸比值比设计尺寸小,就需要缩放界面,而这个缩放的值,我是以设计尺寸为基准,求出的缩放值,即realSize/designSize = scale / 1(scale为所求缩放值)。