Egret社区

二次或者多次加载资源bug

2014-12-16 19:07
461215
Egret版本 1.5 复现概率 100%
问题描述

第二次再去加载的时候,不会派发complete事件,虽然我知道加载重复资源有缓存机制,但是我第二次加载重复资源的时候,你至少要告诉我已经完成加载了吧,不要就死掉那里一动不动

复现步骤

把创建的新项目的 //this.createGameScene(); 改为this.onAddToStage(null);就知道后面几次完全不派发事件,我这里要不确定是否要加载相同的资源,所以,尽管你是相同的,也要给我个事件吧,别再那里装死啊

错误代码
/**
 * Copyright (c) 2014,Egret-Labs.org
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Egret-Labs.org nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY EGRET-LABS.ORG AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL EGRET-LABS.ORG AND CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

class Main extends egret.DisplayObjectContainer{

    /**
     * 加载进度界面
     */
    private loadingView:LoadingUI;

    public constructor() {
        super();
        this.addEventListener(egret.Event.ADDED_TO_STAGE,this.onAddToStage,this);
    }

    private onAddToStage(event:egret.Event){
        //设置加载进度界面
        this.loadingView  = new LoadingUI();
        this.stage.addChild(this.loadingView);

        //初始化Resource资源加载库
        RES.addEventListener(RES.ResourceEvent.CONFIG_COMPLETE,this.onConfigComplete,this);
        RES.loadConfig("resource/resource.json","resource/");
    }
    /**
     * 配置文件加载完成,开始预加载preload资源组。
     */
    private onConfigComplete(event:RES.ResourceEvent):void{
        RES.removeEventListener(RES.ResourceEvent.CONFIG_COMPLETE,this.onConfigComplete,this);
        RES.addEventListener(RES.ResourceEvent.GROUP_COMPLETE,this.onResourceLoadComplete,this);
        RES.addEventListener(RES.ResourceEvent.GROUP_PROGRESS,this.onResourceProgress,this);
        RES.loadGroup("preload");
    }
    /**
     * preload资源组加载完成
     */
    private onResourceLoadComplete(event:RES.ResourceEvent):void {
        if(event.groupName=="preload"){
            this.stage.removeChild(this.loadingView);
            RES.removeEventListener(RES.ResourceEvent.GROUP_COMPLETE,this.onResourceLoadComplete,this);
            RES.removeEventListener(RES.ResourceEvent.GROUP_PROGRESS,this.onResourceProgress,this);
            //RES.destroyRes("preload");
            this.onAddToStage(null);
            //this.createGameScene();
        }
    }
    /**
     * preload资源组加载进度
     */
    private onResourceProgress(event:RES.ResourceEvent):void {
        if(event.groupName=="preload"){
            this.loadingView.setProgress(event.itemsLoaded,event.itemsTotal);
        }
    }

    private textContainer:egret.Sprite;
    /**
     * 创建游戏场景
     */
    private createGameScene():void{

        var sky:egret.Bitmap = this.createBitmapByName("bgImage");
        this.addChild(sky);
        var stageW:number = this.stage.stageWidth;
        var stageH:number = this.stage.stageHeight;
        sky.width = stageW;
        sky.height = stageH;

        var topMask:egret.Shape = new egret.Shape();
        topMask.graphics.beginFill(0x000000, 0.5);
        topMask.graphics.drawRect(0, 0, stageW, stageH);
        topMask.graphics.endFill();
        topMask.width = stageW;
        topMask.height = stageH;
        this.addChild(topMask);

        var icon:egret.Bitmap = this.createBitmapByName("egretIcon");
        icon.anchorX = icon.anchorY = 0.5;
        this.addChild(icon);
        icon.x = stageW / 2;
        icon.y = stageH / 2 - 60;
        icon.scaleX = 0.55;
        icon.scaleY = 0.55;

        var colorLabel:egret.TextField = new egret.TextField();
        colorLabel.x = stageW / 2;
        colorLabel.y = stageH / 2 + 50;
        colorLabel.anchorX = colorLabel.anchorY = 0.5;
        colorLabel.textColor = 0xffffff;
        colorLabel.textAlign = "center";
        colorLabel.text = "Hello Egret";
        colorLabel.size = 20;
        this.addChild(colorLabel);

        var textContainer:egret.Sprite = new egret.Sprite();
        textContainer.anchorX = textContainer.anchorY = 0.5;
        this.addChild(textContainer);
        textContainer.x = stageW / 2;
        textContainer.y = stageH / 2 + 100;
        textContainer.alpha = 0;

        this.textContainer = textContainer;

        //根据name关键字,异步获取一个json配置文件,name属性请参考resources/resource.json配置文件的内容。
        RES.getResAsync("description",this.startAnimation,this)
    }
    /**
     * 根据name关键字创建一个Bitmap对象。name属性请参考resources/resource.json配置文件的内容。
     */
    private createBitmapByName(name:string):egret.Bitmap {
        var result:egret.Bitmap = new egret.Bitmap();
        var texture:egret.Texture = RES.getRes(name);
        result.texture = texture;
        return result;
    }
    /**
     * 描述文件加载成功,开始播放动画
     */
    private startAnimation(result:Array):void{
        var textContainer:egret.Sprite = this.textContainer;
        var count:number = -1;
        var self:any = this;
        var change:Function = function() {
            count++;
            if (count >= result.length) {
                count = 0;
            }
            var lineArr = result[count];

            self.changeDescription(textContainer, lineArr);

            var tw = egret.Tween.get(textContainer);
            tw.to({"alpha":1}, 200);
            tw.wait(2000);
            tw.to({"alpha":0}, 200);
            tw.call(change, this);
        }

        change();
    }
    /**
     * 切换描述内容
     */
    private changeDescription(textContainer:egret.Sprite, lineArr:Array):void {
        textContainer.removeChildren();
        var w:number = 0;
        for (var i:number = 0; i < lineArr.length; i++) {
            var info:any = lineArr[i];
            var colorLabel:egret.TextField = new egret.TextField();
            colorLabel.x = w;
            colorLabel.anchorX = colorLabel.anchorY = 0;
            colorLabel.textColor = parseInt(info["textColor"]);
            colorLabel.text = info["text"];
            colorLabel.size = 40;
            textContainer.addChild(colorLabel);

            w += colorLabel.width;
        }
    }
}
BUG截图

分享到 :
0 人收藏

15 个回复

倒序浏览
dom  圆转纯熟 | 2014-12-16 19:32:36
这个是设计如此,因为你启动组加载前是可以调用RES.isGroupLoaded()这个方法立即判断出来组是否已经加载完成的。都已经知道组是加载过的再启动加载就没意义了,你要是有循环加载的组,可以通过那个方法判断一下再启动。
innocentjulie  圆转纯熟 | 2014-12-17 09:42:14
dom 发表于 2014-12-16 19:32
这个是设计如此,因为你启动组加载前是可以调用RES.isGroupLoaded()这个方法立即判断出来组是否已经加载完 ...

就算是你们设计如此,第二次加载难道就不会给用户任何提示?还有我如果是相同的组,但是组里面的资源不一样,isGroupLoaded判断是否已经加载完成呢还是会加载新资源?不给任何提示,再用户看来就是功能缺陷
innocentjulie  圆转纯熟 | 2014-12-17 11:14:02
如果动态创建的资源完全跟上次加载相同的话,isGroupLoaded 返回true?
如果资源组的内容不同,isGroupLoaded 返回false?
dom  圆转纯熟 | 2014-12-17 13:02:58
innocentjulie 发表于 2014-12-17 11:14
如果动态创建的资源完全跟上次加载相同的话,isGroupLoaded 返回true?
如果资源组的内容不同,isGroupLoade ...

createGroup创建资源组的时候,有个override是否覆的参数,传入true才能覆盖已经存在的资源组,一个组名只能对应一个组。如果第二次创建的覆盖了第一次原先的组,那isGroupLoaded返回的是false。这个接口是可靠的,没有问题。
dom  圆转纯熟 | 2014-12-17 13:04:59
innocentjulie 发表于 2014-12-17 09:42
就算是你们设计如此,第二次加载难道就不会给用户任何提示?还有我如果是相同的组,但是组里面的资源不一 ...

关于没有提示的问题。这个可以优化。改成控制台输出一个warning:要启动加载的资源组已经是加载完成的。
innocentjulie  圆转纯熟 | 2014-12-17 13:16:09
dom 发表于 2014-12-17 13:02
createGroup创建资源组的时候,有个override是否覆的参数,传入true才能覆盖已经存在的资源组,一个组名 ...

但是我测试的时候override是true,第二次加载的资源跟第一次加载的资源一样的话,isGroupLoaded返回的是true,系统设定是这样的么。。。
dom  圆转纯熟 | 2014-12-17 13:20:19
innocentjulie 发表于 2014-12-17 13:16
但是我测试的时候override是true,第二次加载的资源跟第一次加载的资源一样的话,isGroupLoaded返回的是tr ...

[AppleScript] 纯文本查看 复制代码
 public createGroup(name:string,keys:Array<string>,override:boolean=false):boolean{
            if(override){
                var index:number = this.loadedGroups.indexOf(name);
                if(index!=-1){
                    this.loadedGroups.splice(index,1);
                }
            }
            return this.resConfig.createGroup(name,keys,override);
        }

这里是createGroup的代码。你传入的override如果真的是true的,会从loadedGroup里移除那个组名。请再测试一下确认问题是否存在。
innocentjulie  圆转纯熟 | 2014-12-17 14:00:41
本帖最后由 innocentjulie 于 2014-12-17 14:01 编辑
dom 发表于 2014-12-17 13:20
[mw_shl_code=applescript,true] public createGroup(name:string,keys:Array,override:boolean=false):b ...

我第二次加载相同的资源的时候,测试如下
console.log(RES.isGroupLoaded("role_load"));
        RES.createGroup("role_load",["bgImage2"],true);
        console.log(RES.isGroupLoaded("role_load"));
        RES.loadGroup( "role_load");
        console.log(RES.isGroupLoaded("role_load"));
输出为true,false,true,也就是只要重复加载时调用loadGroup后马上变成true,而不是派发出complete事件,任何监听都没用,只能用RES.isGroupLoaded来判断重复资源是否加载完成,而不仅仅在complete事件里面加判断
dom  圆转纯熟 | 2014-12-17 14:17:46
innocentjulie 发表于 2014-12-17 14:00
我第二次加载相同的资源的时候,测试如下
console.log(RES.isGroupLoaded("role_load"));
        RES.cr ...

我这边测试了是没问题的。请上传一个能重现第二次加载会导致监听无效的简单demo。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|京网文[2014]0791-191号|京ICP证150115号|Egret社区 ( 京ICP备14025619号

Powered by Discuz! X3.2 © 2001-2019 Comsenz Inc.

返回顶部