屏幕适配_CocosCreator游戏开发之屏幕适配

本文档介绍了CocosCreator游戏开发中的屏幕适配方法,包括设计分辨率通常采用1334*750,动态选择fit_height或fit_width以适应不同宽高比的屏幕,修改引擎源码来实现适配,以及使用Widget组件和背景图缩放处理刘海屏等。作者分享了个人的适配方案,并提到避免改动源码以降低升级成本。
摘要由CSDN通过智能技术生成

屏幕适配文档

cocos creator 适配方案:https://docs.cocos.com/creator/manual/zh/ui/multi-resolution.html

设计分辨率

设计分辨率一般使用1334*750的尺寸 宽高比为1.778

我的解决方案

  1. 根据屏幕分辨率与设计分辨率的宽高比的不同动态选择fit_height 还是 fit_width,这需要修改引擎源码ee185cf74b219a49edd0d246b23f2101.png
     applySettings: function () {
var frameSize = cc.view.getFrameSize();
var designRes = this._designResolution;
var oldRatio = frameSize.width/frameSize.height;
var newRatio = designRes.width/designRes.height;
cc.log('newRatio ',newRatio,' oldRatio ',oldRatio)
cc.log('frameSize ',frameSize,' designRes ',designRes)
var ResolutionPolicy = cc.ResolutionPolicy;
var policy;
if (this.fitHeight && this.fitWidth) {
policy = ResolutionPolicy.SHOW_ALL;
}
else if (!this.fitHeight && !this.fitWidth) {
policy = ResolutionPolicy.NO_BORDER;
}
else if (this.fitWidth) {
if(newRatio < oldRatio){
policy = ResolutionPolicy.FIXED_HEIGHT;
}else{
policy = ResolutionPolicy.FIXED_WIDTH;
}
}
else if (this.fitHeight) {// fitHeight
if(newRatio < oldRatio){
policy = ResolutionPolicy.FIXED_WIDTH;
}else{
policy = ResolutionPolicy.FIXED_HEIGHT;
}
}
if (CC_EDITOR) {
cc.engine.setDesignResolutionSize(designRes.width, designRes.height);
}
else {
cc.view.setDesignResolutionSize(designRes.width, designRes.height, policy);
}
}

删除ide的缓存文件重新启动。bc97f5c0b67aaab267ea3a3e2e08e937.png

非必要的情况下我不会去改动源码,因为升级成本太高,但是引擎在第一次启动后走这里之后你再设置适配策略就不好使了,所以只能这里修改。具体原因可以参看源码。

  updateCameraViewport () {
// TODO: remove HACK
if (!CC_EDITOR && cc.director) {
let ecScene = cc.director.getScene();
if (ecScene) ecScene.setScale(1, 1, 1);
}

//如果是canvas模式才会走下边的代码。
if (cc.game.renderType === cc.game.RENDER_TYPE_CANVAS) {
let vp = cc.view.getViewportRect();
this.device.setViewport(vp.x, vp.y, vp.width, vp.height);
this._camera.a = cc.view.getScaleX();
this._camera.d = cc.view.getScaleY();
this._camera.tx = vp.x;
this._camera.ty = vp.y + vp.height;
}
},
  1. 使用widget 适配ui 将ui上的控件添加widget组件,为了使widget生效,注意全屏的控件都要添加widget,并且四个方向都设置为0.b275fdeab30addcc852247c538a74717.pnga9b1afc2db7eeb0a6f108f8c511ea114.png

  2. 使用设计分辨率和显示分辨率的宽宽比或者高高比缩放背景图。

const { ccclass, property } = cc._decorator;

@ccclass
export default class AdaptBg extends cc.Component {

start() {
let designSize = cc.Canvas.instance.designResolution;
let visibleSize = cc.view.getVisibleSize()
let rw = visibleSize.width / designSize.width
let rh = visibleSize.height / designSize.height;
let bgRatio = 1;
if (rw > rh) {
bgRatio = rw;
} else {
bgRatio = rh;
}
// this.node为背景图片
this.node.scale = bgRatio
}

}
  1. 刘海屏的适配 根据屏幕分辨率和设计分辨率的比求出需要顶部内容或者左边内容需要移动的高度或者宽度。因为我们没办法知道哪些是刘海屏,哪些不是,所以做了统一处理。这种思想其实出自一个年轻帅气又上进的小伙子。我感觉比那些直接设置canvas宽高的方式要好很多。
export enum OrientationType {
Portrait,
Landscape,
};

const AdaptTarget = cc.Enum({
None: 0,
AdaptPosForTopBang: 1, //针对顶部刘海,适配元素位置,通过调整Widget属性(竖屏往下移,左横屏往右移)
AdaptPosForBottomBar: 2, //针对底部横条,适配元素位置,通过调整Widget属性(竖屏往上移,左横屏往左移)
AdaptSizeForTopBang: 3, //针对顶部刘海,适配元素大小,(竖屏往下拉高,左横屏往右拉宽)
AdaptSizeForBottomBar: 4, //针对底部横条,适配元素大小,(竖屏往上拉高,左横屏往左拉宽)
});

export enum FitType {
HEIGHT,
WIDTH,
}

const { ccclass, property } = cc._decorator;

@ccclass
export default class AdaptUI extends cc.Component {



@property({
type: AdaptTarget
})
target = AdaptTarget.AdaptPosForTopBang;

private widget: cc.Widget;

start() {
this.widget = this.node.getComponent(cc.Widget);
if (!this.widget) {
this.widget = this.node.addComponent(cc.Widget);
}
let frameSize = cc.view.getFrameSize();
let frameAspectRatio = frameSize.width / frameSize.height;
let designSize = cc.Canvas.instance.designResolution;
let designAspectRatio = designSize.width / designSize.height

let deltaAspectRatio = 1 / (frameAspectRatio - designAspectRatio);
console.log("deltaAspectRatio ", deltaAspectRatio);

let topOffset = 0;
if (topOffset === 0 && deltaAspectRatio > 0) {

topOffset = deltaAspectRatio * 120;//这个值根据自己的设计分辨率调整
}

let bottomOffset = 0;
if (bottomOffset === 0 && deltaAspectRatio > 0) {
bottomOffset = deltaAspectRatio * 100;
}
let orientation = designSize.height > designSize.width ? OrientationType.Portrait : OrientationType.Landscape;
this.adaptLogic(topOffset, bottomOffset, orientation);
}

adaptLogic(topOffset, bottomOffset, orientation) {
switch (this.target) {
case AdaptTarget.AdaptPosForTopBang:
if (topOffset == 0) { return; }
switch (orientation) {
case OrientationType.Portrait:
this.widget.top += topOffset;
break;
case OrientationType.Landscape:
this.widget.left += topOffset;
break;
}
break;
case AdaptTarget.AdaptPosForBottomBar:
if (bottomOffset == 0) { return; }
switch (orientation) {
case OrientationType.Portrait:
this.widget.bottom += bottomOffset;
break;
case OrientationType.Landscape:
this.widget.right += bottomOffset;
break;
}
break;
case AdaptTarget.AdaptSizeForTopBang:
if (topOffset == 0) { return; }
switch (orientation) {
case OrientationType.Portrait:
this.node.anchorY = 1;
this.node.height += topOffset;
break;
case OrientationType.Landscape:
this.node.anchorX = 0;
this.node.width += topOffset;
break;
}
break;
case AdaptTarget.AdaptSizeForBottomBar:
if (bottomOffset == 0) { return; }
switch (orientation) {
case OrientationType.Portrait:
this.node.anchorY = 0;
this.node.height += bottomOffset;
break;
case OrientationType.Landscape:
this.node.anchorX = 1;
this.node.width += bottomOffset;
break;
}
break;
}
}

}

结语

以上是我个人使用的方式,仅供参考,如有疑问可以在下方留言。

欢迎关注公众号《微笑游戏》,浏览更多内容。

ed57fb5976d7cc5f2d8b871de1d0933c.png
image

更多内容

跨引擎游戏开发框架

小游戏SDK整合框架

使用四叉树优化碰撞检

游戏开发中UI管理器的使用

小游戏开发中如何优雅的使用本地存档

sdk接入整合,用一个变量切换不同渠道

CocosCreator之AssetBundle使用方案分享

CocosCreator之填色游戏的一种实现方案

一个可屏蔽长短链接的网络模块

游戏开发中的人工智能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值