CocosCreator 跨平台全屏适配方案整理

**

介绍

**

cocos官方提供四种适配方案 Fit Height ,Fit Width ,NO_BORDER ,ExactFit 。这些在官方文档里有详细赘述,这里我们就不做过多介绍。
这里我们就ExactFit(同时勾选Fit Height ,Fit Width)模式进行扩展。
这种模式没有黑边,也不会裁剪设计分辨率范围内的图像。但是代价是场景图像的 x 和 y 方向的缩放倍率不同,图像会产生形变拉伸。有没有办法既没有黑边又没有拉伸呢。有就是麻烦一点。

同时解决各个浏览器全屏的适配问题(高版本safari地址栏,安卓浏览器全屏)

**

适用范围

**

  • 游戏区域相对固定
  • 游戏区域和UI区域可以很好的分离
  • 对背景没有严格的要求

**

准备

**

  • 我们首先要设计两套简单的UI方式,因为我们有时候横板的设计直接到竖版,或者竖版直接发横板都是有问题的
  • 游戏区域看游戏而定有的一套就行
  • 设计分辨率为最小的ui分辨率,可以往大了拉伸不可以再小了。

    **

代码部分

**

  • 首先建立对Canvas操作的脚本

    const {ccclass,property} =cc._decorator;
    @ccclass
    @ccclass
    export default class ScreenAdaptation extends cc.Component {
    //横板设计分辨率
    @property(cc.Size)
    private designSiveH: cc.Size = cc.size(1440, 1080);
    private clientSize: cc.Size = cc.size(0, 0);
    /竖版设计分辨率
    @property(cc.Size)
    private designSiveV: cc.Size = cc.size(1080, 1920);
    /**
    * H 横板 V 竖版 记录当前
    */
    private _screenOrientation: string = “”;
    public start() {
    this.changeDesignResolution();
    }
    public update(){
    //检测分辨率 某些环境下对尺寸改变添加回调函数会有严重延时所以放在update检测
    this.changeDesignResolution();
    }
    //对分辨率进行检测
    public changeDesignResolution(){
    let size: cc.Size = cc.view.getFrameSize();
    //未检测到尺寸变化则跳出函数
    if (size.width == this.clientSize.width && size.height == this.clientSize.height) {
    return;
    }
    this.clientSize = cc.size(size.width, size.height);
    //计算当前屏幕比
    let proportion: number = (size.width / size.height);
    //屏占比切换条件 当宽>高 设定为横屏,当然你可以根据实际调整
    if (proportion >= 1) {
    //屏幕和横板设计相比比较宽
    if (proportion >= this.designSiveH.width / this.designSiveH.height) {
    //重新设定canvas设计分辨率
    this.node.getComponent(cc.Canvas).designResolution = cc.size(size.width * (this.designSiveH.height / size.height), this.designSiveH.height);
    } else {
    //重新设定canvas设计分辨率
    this.node.getComponent(cc.Canvas).designResolution = cc.size(this.designSiveH.width, size.height * (this.designSiveH.width / size.width));
    }
    if (this._screenOrientation != “H” ) {
    this._screenOrientation = “H”;
    //通知所有需要改变场景变成横屏
    }
    }else{//竖屏处理
    if (proportion >= this.designSiveV.width / this.designSiveV.height) { //屏幕比较宽
    this.node.getComponent(cc.Canvas).designResolution = cc.size(size.width * (this.designSiveV.height / size.height), this.designSiveV.height);
    } else {
    this.node.getComponent(cc.Canvas).designResolution = cc.size(this.designSiveV.width, size.height * (this.designSiveV.width / size.width));
    }
    if (this._screenOrientation != “V” ) {
    this._screenOrientation = “V”;
    }
    }
    }
    }

**

全屏处理

**
safar浏览器中只有一个Creator网页,横屏后会自动全屏, 但是如果有多个网页,Creator网页横屏后safar浏览器无法全屏.所以添加遮罩层进行引导玩家上滑全屏
对于某些安卓手机则需要玩家触摸遮罩层,才会给你全屏。所以综合处理方案如下
一、将项目打包,找到打包出的index.html文件,在html文件里,添加一个div标签和一个文本提示,代码如下:

    <div id="mask">
        <h1 id="tip">请向上滑动全屏显示</h1>
    </div>

二、 在style-mobile.css中为这个div和字体添加css样式:

#mask {
	position:absolute;
	z-index:9999;
	background-color:#C0C0C0;
	left: 0;
    top: 0;
	height:1080px;
    width:100%;
	display :none;
	opacity:0.5;
}
 
#tip{
	color:red;
	text-align:center;
	float:center;
	line-height:250px;
}

三、重点构建代码

public start() {
    //尝试用cc自带方法进行全屏实验
    if (!CC_DEBUG && cc.sys.isMobile) {
        if (cc.screen["fullScreen"]) {
            cc.screen["fullScreen"]()
        }
        if (cc.screen["autoFullScreen"]) {
            cc.screen["autoFullScreen"]();
        }
    }
    //注册SAFARI全屏事件
    if (cc.sys.isMobile && cc.sys.browserType == cc.sys.BROWSER_TYPE_SAFARI) {
        window.addEventListener("scroll", () => {
            if (window.orientation == 90 || window.orientation == -90) {
                if (window.innerHeight == document.documentElement.clientHeight) {
                    let docClientHeight = document.documentElement.clientHeight;
                    let mask = document.getElementById('mask');
                    mask.style.height = document.getElementById('Cocos2dGameContainer').style.height = docClientHeight + 'px';
                    mask.style.display="none";
                    //document.addEventListener('touchmove',function(e){e.preventDefault();},false)
                }
            } else {
                document.body.scrollTop = -1;
                window.scrollTo(0,1)
            }
        })
    }
    
}
public mobileFullscreen(){
    //唯一性检测 保证此函数仅运行一次 因为有些就是不给你全屏你也没办法 就不要为难用户了
    if(window['mobileFullscreen']){
        this.mobileFullscreen=()=>{};
        return
    }
    //检测如果存在全屏函数则执行
    if(document.documentElement.requestFullscreen||document.documentElement['mozRequestFullscreen']||document.documentElement['webkitRequestFullscreen']||document.documentElement['msRequestFullscreen']){   
        document.getElementById('mask').addEventListener('touchmove',function(e){e.preventDefault();},false)
        //显示点击遮罩
        document.getElementById('mask').style.display = 'block';
        //对遮罩添加点击事件
        document.getElementById('mask').ontouchend=()=>{
            if(document.documentElement.requestFullscreen){
                document.documentElement.requestFullscreen()
            }else if(document.documentElement['mozRequestFullscreen']){
                document.documentElement['mozRequestFullscreen']()
            }else if(document.documentElement['webkitRequestFullscreen']){
                document.documentElement['webkitRequestFullscreen']()
            }else if(document.documentElement['msRequestFullscreen']){
                document.documentElement['msRequestFullscreen']()
            }
            document.getElementById('mask').ontouchend=()=>{}
            //关闭遮罩
            document.getElementById('mask').style.display = 'none';
        }
    }
    window['mobileFullscreen']=true;
}
public update(){
    //检测SAFARI是否全屏
    if (cc.sys.isMobile && cc.sys.browserType == cc.sys.BROWSER_TYPE_SAFARI) {
        //console.log(window.innerHeight,document.documentElement.clientHeight,window.innerWidth,document.documentElement.clientWidth);
        let display=document.getElementById('mask').style.display;
        if (window.innerHeight == document.documentElement.clientHeight && display!='none' ) {
            document.getElementById('mask').style.display = 'none';
        }
        else if(window.innerHeight != document.documentElement.clientHeight && display!='block'){
            //如果检测到没有全屏显示出mask并且设置遮罩层大于屏幕显示区域进而玩家可以滑动屏幕 ,进而引导用户滑动
            document.getElementById('mask').style.height=(document.documentElement.clientHeight+100)+"px";
            document.getElementById('mask').style.display = 'block';
        }
    }else if(cc.sys.isMobile && !window['mobileFullscreen']){//检测安卓设备
        this.mobileFullscreen();
    }
}

个人原创整理且看且珍惜

14赞

感谢分享,非常实用!

这么好的文章居然没人顶

我用这个方法全屏后,底部有灰边了啊

底部灰边怎么处理了?