cocos creator屏幕适配fitHeight / fitWidth,手机端竖屏,pc端浏览器适配,pc分辨率全屏适配,血条跟随的适配

一,使用creator3.3.2 分别实现手机端和浏览器的适配效果如下 打包web-mobile(居然会有这种需求 /流汗!)

pc浏览器显示

手机端显示

 

1、首先在项目中设置分辨率 和默认适配 这里是750*1334,默认以宽度来适配

设置Canvas的widget适配,代码挂在Canvas下,pcBg是pc浏览器显示的如图蓝色区域,代码如下

  @property(Node)
    pcBg: Node = null;

    onLoad() {

        let design = view.getDesignResolutionSize(); // 设计分辨率,。就是设置的 750 1334 根据不同端做适配
        if(!sys.isMobile)
        {// pc端
            view.setDesignResolutionSize(design.width, design.height, ResolutionPolicy.FIXED_HEIGHT);
        }
        else
        {// 手机端
            view.setDesignResolutionSize(design.width, design.height, ResolutionPolicy.FIXED_WIDTH);
        }

        this.updateSizeFit();
        let _this = this;
        // 监听浏览器窗口大小变化
        view.setResizeCallback(function () {
            _this.updateSizeFit();
            // rect.left, rect.top, rect.width, rect.height (像素值)
        });
    }
     // 根据浏览器窗口变化适配
     updateSizeFit() {
        var rect = view.getVisibleSize();// 获取实际显示的尺寸
        var design = view.getDesignResolutionSize();// 获取设计分辨率
        let wi = this.node.getComponent(Widget);
        // 设置手机端和pc端canvas的显示位置,在pc是横屏的,但是canvas应该是中间的手机位置。所以要左右减 
        //  实际屏幕宽度的一半减去手机屏宽的一半,就是pcBg距离Canvas左侧的距离
        if (!sys.isMobile) { // pc端加背景图,实现中间显示手机界面
            wi.right = rect.width/2-(rect.height*design.width/design.height)/2;
            wi.left = rect.width/2-(rect.height*design.width/design.height)/2;
            wi.top = 0;
            wi.bottom = 0;
            wi.updateAlignment();
        }
        else
        { // 手机端 屏幕宽度高,就是canvas的宽高。,距离是0就可以
            wi.right = 0;
            wi.left = 0;
            wi.top = 0;
            wi.bottom = 0;
            wi.updateAlignment();
        }
        // pc大背景全屏显示,大背景图平铺到pc上,相对于canvas 左右都是负的宽的的一半
        var widget = this.pcBg.getComponent(Widget)
        widget.right = -rect.width/2;
        widget.left = -rect.width/2;
        widget.top = 0;
        widget.bottom = 0;
        widget.target = this.node;
        widget.updateAlignment();
    }

 2、因为我为了防止近大远小,所以照射角色的相机改成了正交相机

3、还是根据camera的targetTexture,把3d投射到2d显示,把RenderTexture赋值给camera和ui要显示投射的sprite,代码如下

  start() {

        // 投影 吧3d照射的投影到2d ui上

        const renderTex = this.render;

        this.cam.targetTexture = renderTex;

        this.show3d.spriteFrame.texture = renderTex;

    }

4、实现血条跟随主角 ,既然跟随,那血条ui就不能加widget, player3dHps是所有玩家的3d下的血条挂点位置,uiHps是所有血条的sprite,通过worldToScreen,把世界坐标转到ui上的位置,再赋值给血条ui

 this.player3dHps.forEach((item, i) => {

            // 血条

            let ve1 = new Vec3(0, 0, 0)

            this.cam.worldToScreen(item.worldPosition, ve1);

            this.uiHps[i].worldPosition = ve1

        })

但是最终的结果在手机端显示没问题,pc端却是这样的效果

那是因为pc端我们的canvas是中间手机位置,世界坐标转屏幕后,是相对于可是蓝色区域的,不是手机canvas深蓝区域的,所以要+(canvas的widget的左侧偏移-中间canvas区域的宽的一半)这区域

 let canvasWidget = find("Canvas").getComponent(Widget)

    this.uiHps[i].worldPosition = ve1.add(new Vec3(canvasWidget.left,0,0));

就能得到正确位置了 

实际显示在手机还有一些小问题,因为手机端是按照宽度适配的,在实际的屏幕高度和设计高度是不一样,因为如果实际手机屏幕比设计高度要高,会导致血条位置高于头顶很多,先看代码

 let canvasWidget = find("Canvas").getComponent(Widget)

            let offsetHeight = !sys.isMobile?0: ((view.getVisibleSize().width*design.height/design.width)-view.getVisibleSize().height);// 计算出高度比实际分辨率的差距,

            this.uiHps[i].worldPosition = ve1.add(new Vec3(canvasWidget.left,-offsetHeight/2,0));

可以理解为在1334高度下血条y是100,在1600下可能是120,导致超过头顶位置正常值,有时间的同学可以调试一下这个offsetHeight,在手机浏览器上看看就明白了

项目地址 中的 GitHub - SuiFengErQu/cocos-creator3d-mini_demo: cocos creator3.3.2练手小功能      adaptationScreen场景

二、pc端浏览器全屏适配,看代码就明白了,设计分辨率是1920*1280,使用cocos creator2.4.4

测试一下图片 基于Canvas 对齐 

  onLoad() {
        this.updateSizeFit();
        let _this = this;
        // 监听浏览器窗口大小变化
        cc.view.setResizeCallback(function () {
            _this.updateSizeFit();
            // rect.left, rect.top, rect.width, rect.height (像素值)
        });
    }  
  // 根据浏览器窗口变化适配
    updateSizeFit() {
        var rect = cc.game.canvas.getBoundingClientRect();
        let rateWidth = Math.round(rect.width / 1920 * 100) / 100;
        let rateHeight = Math.round(rect.height / 1080 * 100) / 100;
        // console.log("屏幕发生变化", rateWidth, rateHeight) 手机端和pc参数不同
        if (Math.abs(rateWidth - rateHeight) > (GameConfig.getPlatform(true)===GameConfig.PLATFORM.PC?0.2:0.5) || rateWidth == rateHeight) {// 宽高差距太大或者宽高比=,不做适配
            cc.Canvas.instance.fitHeight = false;
            cc.Canvas.instance.fitWidth = false;
            UIModalMgr.inst.updateMaskView();// 更新popUI mask大小
            EventCenter.emit(EventCenterNameEnum.ScreenChange);
            return;
        }
        if (rateWidth < rateHeight) {
            cc.Canvas.instance.fitHeight = false;
            cc.Canvas.instance.fitWidth = true;
        }
        else if (rateHeight < rateWidth) {
            cc.Canvas.instance.fitHeight = true;
            cc.Canvas.instance.fitWidth = false;
        }
        UIModalMgr.inst.updateMaskView();// 更新popUI mask大小
        EventCenter.emit(EventCenterNameEnum.ScreenChange);
    }

这里实际上就是 计算实际宽度和设计宽度的比例,实际高度和设计高度的比例

当比例一样,或者比例相减的绝对值大于0.2,那就不适配,否则会界面错乱,这里如果是手机端是》0.5,因为手机端的比例差距比较大,所以值调大一些,尽可能适配更多的手机。

如果宽度比例小,那就以宽来适配,否则以高来适配

剩下的就是界面上加widget来调了,可以看一下不同情况下显示效果

超过一定比例不再适配,直接部分被隐藏

手机端显示 

猜你喜欢

转载自blog.csdn.net/github_38633141/article/details/121402183