笔记十二 :Egret分帧(frame)加载图形对象(基于通用MVC框架)

笔记十二 :Egret分帧(frame)加载图形对象(基于通用MVC框架)

前言:卡顿是游戏们,手机app们,网页们的大敌。卡顿的原因有很多种,在游戏中,假如在短时间内加载大量的图形对象,就会像一大堆车子堵在了一个狭小的路口,造成卡顿。分帧加载是短时间内加载大量的对象时,把这些对象加载的时间错开,平摊到更长的时间内,这样每秒加载的对象数量会减少,但流畅度会提升。

源代码:

演示加载20000张Image:(左普通加载,右分帧加载)

能看出来,左边普通加载的时候,人物动作都被卡住不动了,而右边的分帧加载,人物的动作没有受到加载的影响。

思路:利用Egret白鹭中的ENTER_FRAME监听,让加载的函数分批次的进行。

步骤一:基于通用MVC框架,快速建立一个基本界面。(参考笔记一,笔记十)

涉及到的文件:

\src\example\module\demo\frameload\FrameLoadController.ts

\src\example\module\demo\frameload\FrameLoadView.ts

\resource\skins\demo\frameload\FrameLoadViewSkin.exml

步骤二:学习官网的帧事件

步骤三:分别设置普通加载和分帧加载

文件:\src\example\module\demo\frameload\FrameLoadView.ts

    private img: egret.Bitmap;
    private tempx: number = 0;
    private tempy: number = 0;

普通加载:

简单的for循环生成20000张图片

    //初始化普通加载
    public initNormalLoad(): void {
        for (let i: number = 0; i < 20000; i++) {
            //生成图片
            let img: egret.Bitmap = new egret.Bitmap();
            img.texture = RES.getRes("table_activity");
            //调整位置
            img.x = this.tempx;
            img.y = this.tempy;
            //add to Stage
            this.group.addChild(img);
            //自动适应下一个图片的位置
            this.tempx += 10;
            if (this.tempx >= 400) {
                this.tempx = 0;
                this.tempy += 5;
            }
        }
    }

分帧加载:

监听ENTER_FRAME,使得游戏中的每一帧都会触发addItem()函数,而每一帧都会执行一个for循环加载50张图片,当一共400帧的时候,20000张图片才会全部加载完成。

    //初始化分帧加载
    public initFrameLoad(): void {
        this.addEventListener(egret.Event.ENTER_FRAME, this.addItem, this);
        this.timeOnEnterFrame = egret.getTimer();
    }

    //分帧添加item
    private _addIndex: number = 0;//分帧第几个
    private timeOnEnterFrame: number = 0;//记录下的系统时间
    private addItem() {
        let self = this;
        if (this._addIndex < 400) {
            for (let i: number = 0; i < 50;i++){
                //生成图片
                let img: egret.Bitmap = new egret.Bitmap();
                img.texture = RES.getRes("table_activity");
                //调整位置
                img.x = this.tempx;
                img.y = this.tempy;
                //add to Stage
                this.group.addChild(img);
                //自动适应下一个图片的位置
                this.tempx += 10;
                if (this.tempx >= 400) {
                    this.tempx = 0;
                    this.tempy += 5;
                }
            }
           this._addIndex++;
        }
        else {
            this.removeEventListener(egret.Event.ENTER_FRAME, this.addItem, this);
        }

        //记录每一帧时间
        var now = egret.getTimer();
        var time = this.timeOnEnterFrame;
        var pass = now - time;
        console.log("onEnterFrame: ", (1000 / pass).toFixed(5));
        this.timeOnEnterFrame = egret.getTimer();
    }

步骤四 运行测试两种加载方式

添加执行测试:\src\example\module\demo\frameload\FrameLoadView.ts

    public initUI(): void {
        //两种加载方式
        //this.initFrameLoad();
        this.initNormalLoad();
    }

添加测试按钮:

\src\example\module\demo\DemoView.ts

    private button4ClickHandler(e: egret.TouchEvent): void {
        //这是打开帧加载的测试
        App.ViewManager.open(1, ViewConst.FrameLoad);
    }