如何使用forEach和进度条将图片添加到容器Sprite?

时间:2013-03-24 23:13:59

标签: actionscript-3 foreach loader

我成功加载单个图像并使用addChild()创建它。现在我尝试使用forEach循环将多个图像加载到sprite“Container”中,从而增加每个图像的X值,使它们显示在一行中。图像加载器引用XML文档中的链接。如果我测试此代码,则在加载图像时会弹出此错误,并尝试removeChild()loadBar动画。

ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()

这是AS3:

private function loadBG():void {
    var artGrab:Number = 0;
    var artX:Number = 0;
    for each (var albumData:XML in mainXML.artist[artistID].album) {
        imgURL = new URLRequest(mainXML.artist[artistID].album[artGrab].art);
        imgLdr = new Loader();

        //if you're loading a bigger image or need a preloader
        imgLdr.contentLoaderInfo.addEventListener(Event.COMPLETE,onBGLoaded);
        imgLdr.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onLoading); 
        //add loader animation "All Loader"
        ldrAnim = new AllLoader();
        albumContainer.addChild(ldrAnim);
        ldrAnim.x = artX;
        ldrAnim.y = 200; 
        imgLdr.load(imgURL);
        artGrab++;
        artX + 481;
        ldrAnim.x + 481;
    }
}

private function onLoading(evt:ProgressEvent):void {
    var bytesToLoad:Number = imgLdr.contentLoaderInfo.bytesTotal;
    var numberLoaded:Number = imgLdr.contentLoaderInfo.bytesLoaded;
    ldrAnim.progBar.scaleX = numberLoaded / bytesToLoad;
    var loadedPercent = Math.round(numberLoaded / bytesToLoad * 100);
    ldrAnim.progPercent.text = loadedPercent + " %";
    trace("Loading..." + loadedPercent + "%");
}

private function onBGLoaded(evt:Event):void {
    trace("image loaded!");
    //image setup
    addChildAt(imgLdr,0);
    //now that its 100% loaded, you can resize it , etc.
    removeChild(ldrAnim);

    //use cross multiplying of fractions to maintain aspect ratio
    var origW = imgLdr.contentLoaderInfo.width;
    var origH = imgLdr.contentLoaderInfo.height;
    trace("orig width: "+ origW + "orig height: " + origH);
    //set new width
    imgLdr.width = 481;
    var newH:Number = 481 * origH / origW;
    imgLdr.height = newH;

    //may wish to do positioning AFTER resizing
    imgLdr.x = stage.stageWidth / 2 - imgLdr.width / 2;
    imgLdr.x = 0;
    imgLdr.y = 0;
    imgLdr.width = 480;
    imgLdr.height = 480;
    imgLdr.alpha = 1;   
    imgLdr.z = 0;
}

祝福你阅读这一切,我不明白是什么导致了这个错误所以感谢评论!

2 个答案:

答案 0 :(得分:1)

发生的事情是您已经填充变量ldrAnim多次,每次都创建一个新的AllLoader。当你打电话给removeChild()时,第一次工作正常(排序 - 它将删除你创建的最后一个,是否与加载的图像匹配)。当你再次拨打removeChild()时,你正在为你刚删除的同一个呼叫它(它不再是你正在呼叫它的对象的孩子)。

解决此问题的一种方法是使用Dictionary并将每个AllLoader与该图片的Loader相关联。当COMPLETE事件触发时,您可以根据事件的属性查找Alloader并将其删除。

另一个解决方案是编写一个包装AllLoaderLoader的类,然后在Loader加载完成后处理两者之间的转换。

这可能看起来像这样:

public class LoadSwitcher extends Sprite{
   protected var loader:Loader;
   protected var allLoader:AllLoader;
   public function loadSwitcher(url) {
       super();
       loader = new Loader();
       var request:URLRequest = new URLRequest(url);
       loader.contentLoaderInfo.addEventListener(Event.COMPLETE, switchLoaders);
       allLoader = new AllLoader(loader);//assume AllLoader now has logic to watch the loader for % complete
       loader.load(request);
       addChild(allLoader);
   }
   protected function switchLoaders(e:Event):void {
      removeChild(allLoader);
      addChild(loader);
   }
}

然后,只为每张相册创建并定位其中一个。

答案 1 :(得分:1)

你需要有一个动画数组供你的加载器自己保存,然后当另一个ProgressEvent.PROGRESS事件到达时,查询数组event.target索引,抓取相应的动画并调整,一旦将一个侦听器放在多个不同的对象上,就停止依赖单值全局变量!

var animations:Vector.<AllLoader>;
var loaders:Vector.<LoaderInfo>;
private function loadBG():void {
    var artGrab:int=0;
    var artX:int=0;
    animations=new Vector.<AllLoader>();
    loaders=new Vector.<LoaderInfo>;
    for each (var albumData:XML in mainXML.artist[artistID].album) {
        imgURL = new URLRequest(mainXML.artist[artistID].album[artGrab].art);
        imgLdr = new Loader();
        //if you're loading a bigger image or need a preloader
        imgLdr.contentLoaderInfo.addEventListener(Event.COMPLETE,onBGLoaded);
        imgLdr.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onLoading); 
        //add loader animation "All Loader"
        ldrAnim = new AllLoader();
        albumContainer.addChild(ldrAnim);
        anomations.push(ldrAnim)
        loaders.push(imgLdr.contentLoaderInfo); // fill the arrays
        ldrAnim.x = artX;
        ldrAnim.y=200; 
        imgLdr.load(imgURL);
        artGrab++;
        artX+=481;
    }
}

private function onLoading(evt:ProgressEvent):void{
    var bytesToLoad:Number=evt.target.bytesTotal;
    var numberLoaded:Number=evt.target.bytesLoaded; // note it now refers to target of event
    var index:int=loaders.indexOf(evt.target); // should be valid
    var ldrAnim:AllLoader=animations[index]; // grab corresponding animation
    ldrAnim.progBar.scaleX = numberLoaded/bytesToLoad;
    var loadedPercent=Math.round(numberLoaded/bytesToLoad*100);
    ldrAnim.progPercent.text = loadedPercent +" %";
    trace("Loading..."+loadedPercent +"%");
}

作为一个教训,您自己使用onBGLoaded功能执行相同的操作。请注意,您必须从事件中正确检索imgLdr值。