CocosCreator屏幕适配
CocosCreator通过以下几个部分完成多分辨率适配解决方案:
Canvas(画布) 组件随时获得设备屏幕的实际分辨率并对场景中所有渲染元素进行适当的缩放。
Widget(对齐挂件) 放置在渲染元素上,能够根据需要将元素对齐父节点的不同参考位置。
Label(文字) 组件内置了提供各种动态文字排版模式的功能,当文字的约束框由于 Widget 对齐要求发生变化时,文字会根据需要呈现完美的排版效果。
Sliced Sprite(九宫格精灵图) 则提供了可任意指定尺寸的图像,同样可以满足各式各样的对齐要求,在任何屏幕分辨率上都显示高精度的图像。
对于分辨率的概念我们经常会了解到的是设计分辨率和屏幕分辨率
设计分辨率 是内容生产者在制作场景时使用的分辨率蓝本,也就是美术人员或开发人员设计ui时使用的分辨率模版。
屏幕分辨率 是游戏在设备上运行时的实际屏幕显示分辨率,也就是游戏运行时我们所看到的实时分辨率。
而我们所说的屏幕适配,就是把设计分辨率适配到实时分辨率上,避免穿帮。
通常设计分辨率会采用市场目标群体中使用率最高的设备的屏幕分辨率,比如目前安卓设备中 800 x 480
和 1280 x 720
两种屏幕分辨率,或 iOS 设备中 1136 x 640
和 960 x 640
两种屏幕分辨率。当然也可能是web端常用到1080 x 1920等。
这样当美术或策划使用设计分辨率设置好场景后,就可以自动适配最主要的目标人群设备。
不过如果需要做适配,设计分辨率的意义不是很大,但是不能太离谱。
当设计分辨率和屏幕分辨率出现差异时,也就是我们要解决的问题,适配屏幕分辨率。
假设我们的设计分辨率为 800 x 480
,美术制作了一个同样分辨率大小的背景图像

假如设计分辨率和屏幕分辨率宽高比相同,比如以上图为例,设计分辨率800 x 480。屏幕分辨率是 1600 x 960,那么将背景图像放大 1600/800 = 2 倍 就可以完美适配屏幕。
这种只针对于适配需求比较简单的情况。
虽然cocosCreator官方提供了允许出现黑边,和不出现黑边但也不提供分别缩放 x 和 y 轴缩放率(图像可能会拉伸)的适配情况,实际开发中基本不会考虑,谁不想做的更好呢。
于是把适配宽高的方案变通一下,让它在不同分辨率下既不出现黑边,也不会裁剪元素,不拉伸元素,保证ui元素的基本布局。
假设屏幕分辨率是 1920 x 960
,宽屏适配,同样在下图中以红色方框表示设备屏幕可见区域。我们使用 Canvas 组件提供的 适配宽度(Fit Width
)模式,将设计分辨率的宽度自动撑满屏幕宽度,也就是将场景放大 1920/800 = 2.4 倍。

但是在设计分辨率宽高比较小时,使用这种模式会裁剪掉屏幕上下一部分背景图
如果我们在这种情况下考虑去判断高度缩放比例:也就是1920/bgheigt(or设计分辨率的高度) = gamescale,然后动态设置场景缩放。这样没有黑边了,但相对的屏幕宽度的两边可能会有元素被裁减。这里就可以通过wedit组件来适配边距。
原理就是,通过宽高比适配宽度有黑边时就动态设置x轴方向的缩放,适配高度有黑边时就动态设置Y轴方向的缩放,
cocosCreator提供了web端动态获取横竖屏切换的监听方法
cc.view.setResizeCallback(this.onResize.bind(this));
这样就可以在onresize中动态设置分辨率适配
cc.view.setDesignResolutionSize(1350, 750, cc.ResolutionPolicy.FIXED_WIDTH);
或
cc.view.setDesignResolutionSize(1350, 750, cc.ResolutionPolicy.FIXED_HEIGHT);
贴个实例代码:
当获取到屏幕切换的回调onResize,该回调可以考虑在初始化的时候调用一次:
onResize() {
let vsize = cc.view.getFrameSize();
if (vsize.width > vsize.height) {
//横屏动态适配
let th = 750;
let tw = 750 * vsize.width / vsize.height;
if (tw < 1350) {
cc.view.setDesignResolutionSize(1350, 750, cc.ResolutionPolicy.FIXED_WIDTH);
} else {
cc.view.setDesignResolutionSize(1350, 750, cc.ResolutionPolicy.FIXED_HEIGHT);
}
if (cc.winSize.width > 1334) {
GameConfig.gameScale = cc.winSize.width / 1334;
}
} else {
//竖屏动态适配
let tw = 750;
let th = 750 * vsize.height / vsize.width;
if (th < 1440) {
cc.view.setDesignResolutionSize(750, 1440,cc.ResolutionPolicy.FIXED_HEIGHT);
} else {
cc.view.setDesignResolutionSize(750, 1440, cc.ResolutionPolicy.FIXED_WIDTH);
}
if (cc.winSize.height > 1334) {
GameConfig.gameScale = cc.winSize.height / 1334;
}
}
//这里就可以根据GameConfig.gameScale来适配屏幕的缩放了
//另外还可以自定义添加回调去设置横竖屏适配
/*
let viewWay = cc.winSize.width > cc.winSize.height ? Direction.Horizontal : Direction.Vertical;
ObserverClass.publish(EventType.winResize, viewWay);
*/
}
对于手机端,可能需要各系统sdk提供的屏幕切换接口了。当前如果是只适配竖屏或只适配横屏就可以直接套用。