麒麟子Cocos Creator实用技巧九:棋牌UI全分辨率适配方案


麒麟子在五一劳动节这一天,为大家准备了一个DEMO。 DEMO演示了,大厅,背景,以及像 3D麻将,斗地主等桌面的适配方案。使大家可以用一套资源,适配从iPhoneX(目前最长的移动设备) 到 iPad(目前最短的移动设备 )的分辨率。

PS:黑莓那种1:1也可以的,只是我人为的把它忽略了。

本DEMO在线演示: https://qilinzi.ukylin.net/?lesson=09

本DEMO源代码:https://gitee.com/qilinzi/qlz_ccc_tips


不谋万世者,不足谋一时。不谋全局者,不足谋一域。

麒麟子对这句话的理解就是,早睡早起,好好学习,天天向上。哈哈哈哈。正文开始之前,先瞎**几句,是麒麟子的风格,大家久了就习惯了。如果不想看的,直接到正文即可。 这段的主要目的,是想缓解一下大家的压力。毕竟大部分看这个文章的朋友,都在996,或者在去996的路上。

麒麟子不只一次说过,不要总是学人有跟热点,不要总幻想自己是站在风口的猪。即便你飞起来了,那万一风突然停了呢。选择一个自己看好的领域进行深耕,不断积累。

而选择什么领域,技术只是基础。用户需求是否可持续,才是你能否持续深耕的关键。

麒麟子有云:棋牌之路漫漫其修远兮,吾将上下而求索(翻译:棋牌领域是棵常青树,是一个可以深耕的领域)

后面的文章,大部分是基于棋牌来讲解知识点,但对于其他游戏也同样适用


一、不同适配策略的表现效果

Cocos Creator的Canvas提供了fitWidth和fitHeight两个开关,可以实现4种效果

1、fitWidth = false, fitHeight = false

    对应的是自动选择定宽还是定高,当用户手机比设计分辨率更宽时,使用定宽。 当用户手机比设计分辨率更短时,使用定高。 带来的就是裁剪效果

2、fitWidth = true, fitHeight = false

    对应的是定宽效果

3、fitHeight = false,fitHeight = true

对应的是定高效果

4、fitWidth = true,fitHeight = true

对应的是show_all效果

在设计分辨率不变的情况下,不同的适配策略,在不同的设备上的表现效果,如下图

二、幼麟棋牌的适配模式

1、适配效果介绍

棋牌游戏,卡牌游戏等项目的适配,比RPG要难一点。特别是牌桌和全屏界面。对于RPG来说,只需要做靠主界面的停靠即可。而棋牌游戏,桌子本来空间就不足,简单的停靠是满足不了需求的。幼麟棋牌团队在经历了十几个项目之后总结出一条铁律:不允许任意分辨率对内容裁剪。这条铁律沿用至今,暂时没有发现满足不了的情况。

看到上面黑字的时候,我们肯定第一时间想到全显的适配策略。 

心细的朋友应该能够发现,全显和幼麟棋牌,都是保证内容能够全部显示。但为什么麒麟子在画图的时候,要把全显的背景弄成黑色呢。 你没看错,这不是麒麟子脑袋抽风,这是因为,二者有区别。

有兴趣的朋友可以拿ShowAll和幼麟棋牌的适配方案做一个测试,你会发现,核心差异就在Widget是否能够正确停靠的问题。 使用ShowAll方案,Widget会按绿色边缘作为停靠。 而使用幼麟棋牌方案,Widget会使用屏幕宽高作为停靠。

2、全分辨率适配代码实现

这里要注意,CocosCreator场景中,一定要去掉 fitWidth和fitHeight。 一个都不能留,否则是有问题的。下面的代码是从Demo代码中的Utils.ts文件中截取的。

    public static resize() {
        
        var cvs = cc.find('Canvas').getComponent(cc.Canvas);
        //保存原始设计分辨率,供屏幕大小变化时使用
        if(!this.curDR){
            this.curDR = cvs.designResolution;
        }
        var dr = this.curDR;
        var s = cc.view.getFrameSize();
        var rw = s.width;
        var rh = s.height;
        var finalW = rw;
        var finalH = rh;

        if((rw/rh) > (dr.width / dr.height)){
            //!#zh: 是否优先将设计分辨率高度撑满视图高度。 */
            //cvs.fitHeight = true;
            
            //如果更长,则用定高
            finalH = dr.height;
            finalW = finalH * rw/rh;
        }
        else{
            /*!#zh: 是否优先将设计分辨率宽度撑满视图宽度。 */
            //cvs.fitWidth = true;
            //如果更短,则用定宽
            finalW = dr.width;
            finalH = rh/rw * finalW;
        }
        cvs.designResolution = cc.size(finalW, finalH);
        cvs.node.width = finalW;
        cvs.node.height = finalH;
        cvs.node.emit('resize');
    }

麒麟子保证,用上面的代码,配上fitWidth = false, fitHeight = false. 你将再也不用因为分辨率适配而掉头发 (因为刘海屏适配掉的头发不算在这个里面)

不要太浪哦!!!!

三、背景适配

按理说,我们弄一张足够大的背景,总是能撑满所有分辨率的。但这样一来,美术的设计成本就高了。 特别是不能复用一些现成(别人)的资源。

麒麟子弄了一个bg_scaler.ts来满足大家,大家可以通过点击大厅的 居中,自由缩放,裁剪 来观察不同的效果。

关键代码如下:

resize () {

        this.node.width = this.originWidth;
        this.node.height = this.originHeight;

        //0、居中(居中其实不需要挂这个脚本,浪费效率)
        //1、宽高都根据高度拉伸
        //2、长边充满
        var cvs = cc.find('Canvas').getComponent(cc.Canvas);
        var size = cc.view.getFrameSize();
        
        var dr = Utils.curDR;
        var scaleMethod = this.mode;

        //
        var fitWidth = true;
        //如果更宽,则使用定高
        if((size.width/size.height) > (dr.width / dr.height)){
            fitWidth = false;
        }

        //自由缩放撑满
        if(scaleMethod == 1){
            if(fitWidth){
                this.node.height = this.node.width/size.width * size.height;
            }
            else{
                this.node.width = this.node.height/size.height * size.width;
            }
        }
        //保持等比缩放撑满
        else if(scaleMethod == 2){
            if(fitWidth){
                //定宽表示设备更高了,则以高的缩放为准
                var oldHeight = this.node.height;
                this.node.height = this.node.width/size.width * size.height;
                var scale = this.node.height/oldHeight;
                this.node.width = scale * this.node.width;
            }
            else{
                //定高表示设备更宽的,以宽的缩放为准
                var oldWidth = this.node.width;
                this.node.width = this.node.height/size.height * size.width;
                var scale = this.node.width / oldWidth;
                this.node.height = scale * this.node.height;
            }
        }
        else{
            //默认处理,有黑边
        }
    }

四、麻将桌子适配

麒麟子的DEMO里面,处理了一个假3D的麻将桌子。因为这个比较特殊,所以放在这里作为了案例。此代码在DEMO代码的 09_3dmjtable.ts文件中。它实现的效果是,如果屏幕比设计分辨率高,比如 iPad这样的设备,那么将会多显示出一些墙壁上的内容。如果比设计分辨率更长,比如iPhoneX,那么将会做一定的拉伸,确保背景充满。

    start () {
        cc.find('Canvas').on('resize',this.resize.bind(this));
        this.resize();
    }

    resize(){
        var canvas = cc.find('Canvas');
        if(canvas.width > Utils.curDR.width){
            this.node.width = canvas.width;
        }
    }

五、斗地主桌子适配

半弧的桌子适配是最容易的,只需要一个Widget无脑充满即可

六、总结

本文章和DEMO只是演示了一些基本的适配技巧。 每一个项目,面对的需求都大相径庭,没有哪一个方案是可以一劳永逸的,需要大家根据自身项目的情况,酌情调整。

本DEMO在线演示: https://qilinzi.ukylin.net/?lesson=09

本DEMO源代码:https://gitee.com/qilinzi/qlz_ccc_tips

发布了230 篇原创文章 · 获赞 542 · 访问量 118万+

猜你喜欢

转载自blog.csdn.net/qq_36720848/article/details/89742451