Cocos creator screen adaptation fitHeight / fitWidth, mobile phone vertical screen, PC browser adaptation, PC resolution full screen adaptation, blood bar adaptation

 

1. Use creator3.3.2 to realize the adaptation effects of mobile phone and browser respectively as follows Package web-mobile (there is such a need/sweating!)

pc browser display

Mobile terminal display

 

 

1. First set the resolution and default adaptation in the project, here is 750*1334, the default is to adapt to the width

Set the widget adaptation of Canvas, the code is hung under Canvas, pcBg is the blue area shown in the figure in the pc browser, the code is as follows

  @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. Because I want to prevent the near big and far small, the camera that irradiates the character has been changed to an orthographic camera

3. Still according to the targetTexture of the camera, project the 3D to the 2D display, and assign the RenderTexture to the camera and ui to display the projected sprite. The code is as follows

 

  start() {

        // Project the projection of the 3d illumination onto the 2d ui

        const renderTex = this.render;

        this.cam.targetTexture = renderTex;

        this.show3d.spriteFrame.texture = renderTex;

    }

4. Realize that the blood bar follows the protagonist. Since it follows, the blood bar ui cannot be added as a widget. player3dHps is the position of the blood bar hanging point of all players in 3D, and uiHps is the sprite of all blood bars. Through worldToScreen, the world coordinates are transferred to The position on the ui, and then assign it to the blood bar ui

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

            // blood bar

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

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

            this.uiHps[i].worldPosition = ve1

        })

But the final result is no problem displayed on the mobile phone, but it is the same effect on the PC

That’s because our canvas on the PC side is the middle position of the mobile phone. After the world coordinates are rotated to the screen, it is relative to the blue area, not the dark blue area of ​​the mobile phone canvas, so +(the left offset of the canvas widget-the middle canvas half the width of the region) the region

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

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

will get the correct position 

There are still some small problems actually displayed on the mobile phone, because the mobile phone is adapted according to the width, and the actual screen height is different from the design height, because if the actual mobile phone screen is higher than the design height, the position of the blood bar will be higher than There are a lot of overhead, first look at the code

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

            let offsetHeight = !sys.isMobile?0: ((view.getVisibleSize().width*design.height/design.width)-view.getVisibleSize().height);// Calculate the difference between the height and the actual resolution,

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

It can be understood that the blood bar y is 100 at the height of 1334, and it may be 120 at the height of 1600, resulting in exceeding the normal value of the position of the top of the head. Students who have time can debug this offsetHeight, and it will be clear on the mobile browser.

GitHub in the project address  - SuiFengErQu/cocos-creator3d-mini_demo: cocos creator3.3.2 hand practice small function      adaptationScreen scene

2. Full-screen adaptation of the PC browser, you can understand it by looking at the code, the design resolution is 1920*1280, using cocos creator2.4.4

Test the image alignment based on 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);
    }

Here is actually calculating the ratio of the actual width to the design width, the ratio of the actual height to the design height

When the proportion is the same, or the absolute value of the proportion subtraction is greater than 0.2, then it is not suitable, otherwise the interface will be disordered. Here, if it is the mobile terminal, it is > 0.5, because the proportion difference of the mobile terminal is relatively large, so the value should be adjusted as much as possible. Adapt to more mobile phones.

If the width ratio is small, then adapt to width, otherwise adapt to height

The rest is to add widgets on the interface to adjust, you can see the display effect in different situations

 

If it exceeds a certain ratio, it will no longer fit, and the direct part will be hidden

Mobile terminal display 

 

Guess you like

Origin blog.csdn.net/github_38633141/article/details/121402183