2014-03-06 41 views
0

我的閃存/ as3應用程序出現問題。我創造了大部分,現在我正在努力讓我的外部資源發揮作用​​。同步圖像加載動作腳本3閃存

我的應用程序由一個Controller類組成,它控制了一個應用程序流。一開始,它初始化AppInitializer類,它加載/生成整個應用程序內容(這是一個簡單的點擊遊戲)。

在AppInitializer中,我創建了一個遊戲中可用的項目數組。 Item的構造函數將path作爲參數(String)傳遞給資源(image)。然後,在構造函數中我把我的AssetsLoader類的靜態方法,它看起來像這樣:

public static function loadImage(path:String):BitmapData 
    { 
     completed = false; 
     var loader:Loader = new Loader(); 
     loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event){completed = true; 
     trace("Loading completed"); 
     e.target.removeEventListener(Event.COMPLETE, check);}); 
     if (path == "") 
      loader.load(new URLRequest("images/default.png")); 
     else 
      loader.load(new URLRequest("images/" + path)); 
     //while (!completed); 
     var image:Bitmap = new Bitmap((loader.content as BitmapData)); 
     return image.bitmapData; 
    } 

在哪裏完成是AssetsLoader的一個靜態變量。

第一個問題是:我創建了連續多項目的對象,因此該方法的LoadImage不應該是靜態的我猜(同樣有完整的變量),因爲在加載時,可能會出現問題。

第二個問題是:此刻我無法返回bitmapData(或位圖,它並不重要),因爲return語句將始終返回null - 因爲資源異步加載並且不會在時間應用程序到達return語句。如果我取消註釋令人懷疑的循環,則完整的事件從不會被調用。

我想問一下有經驗的ActionScript開發人員指出,將不需要改變我的應用程序的其餘部分,將解決這些問題的任何解決方案。 (我認爲可以通過對加載程序使用某種排隊方法來消除第一個問題,但迄今爲止,我堅持了第二個問題,並且沒有可能的解決方案)。

我也可以考慮在我的邏輯變化,這樣我就可以下載所有圖像資源投入到「地方」,之後只是使這些圖像的副本,我的目的。如果這更容易做到。

+0

爲什麼不在你的Event函數中放入return語句和變量。或者使用具有該參數的回調代替回報。 –

回答

0

因此,正如我在評論中建議,最小的改變分辨率可能僅僅是傳遞一個函數作爲loadImage()參數的一部分。這被稱爲一個回調函數,它會是這個樣子:

首先創建回調函數:

public function addImage(bitmapData:BitmapData):void { 
    //do something with the bitmapData returned 
} 

下一頁調整loadImage()本地函數使用回調與位圖數據時,該事件已完成:

public static function loadImage(path:String, callback:Function):BitmapData { 
    completed = false; 
    var loader:Loader = new Loader(); 
    loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event){completed = true; 
    trace("Loading completed"); 
    var image:Bitmap = new Bitmap((loader.content as BitmapData)); 
    callback(image); //call the callback with the bitmap 
    e.target.removeEventListener(Event.COMPLETE, check);}); 
    if (path == "") 
     loader.load(new URLRequest("images/default.png")); 
    else 
     loader.load(new URLRequest("images/" + path)); 
} 

然後只是你做來電loadImage()像這樣:

loadImage(myPathToImage, addImage); 

這是一個簡單的決議和不正是你需要它。

+0

好吧,這看起來很容易實現,所以我的addImage函數應該是Item類的一部分呢?如果我理解正確。 – user1970395

+0

好吧,只要你將'addImage()'作爲參數傳遞給它,那麼它確實無關緊要。因此,如果它在不同的類中,並且在Item類中有該類的引用,那麼只需執行'loadImage(path,someClass.addImage);'因此基本上只需將它添加到您喜歡的位置,但聽起來像是這樣在你的Item類中會很好。 –

+0

謝謝,我設法實現了我想要的項目實例的imData變量設置! :)我也重寫了我的AssetsLoader類以實例化,並一次性加載所有圖像,從而消除了這個問題。很好的答案貝內特,謝謝你。 – user1970395

0

中超,你評論的代碼,瘋狂符合while;) 這裏爲您,簡單QueueLoader(它加載的項目一個接一個,當你添加項目到隊列中,你可以存儲在隊列項的ID ),這將有助於你與你的任務:

package { 

    import flash.display.Sprite; 
    import flash.display.StageAlign; 
    import flash.display.StageScaleMode; 
    import flash.events.Event; 

    public class StackOverflow extends Sprite { 

     public function StackOverflow() { 
      addEventListener(Event.ADDED_TO_STAGE, onAdded); 
     } 

     private function onAdded(e:Event):void { 
      removeEventListener(Event.ADDED_TO_STAGE, onAdded); 

      stage.align = StageAlign.TOP_LEFT; 
      stage.scaleMode = StageScaleMode.NO_SCALE; 

      setup(); 
     } 

     private function setup():void { 
      //Store somewhere reference on QueueLoader to reuse it, and use queue 
      var loader:QueueLoader = new QueueLoader(); 
      loader.addEventListener(QueueLoaderEvent.COMPLETE, onCompleteItem); 
      //Add as many images to load as you want, and store Id's of items that 
      //will be loaded in future, if you want... 
      loader.addItem("someUrl1"); 
      loader.addItem("someUrl2"); 
      var importantId:int = loader.addItem("someUrl3"); 
      loader.addItem("someUrl4"); 
      loader.addItem("someUrl6"); 
     } 

     private function onCompleteItem(e:QueueLoaderEvent):void { 
      trace("Item loaded"); 
     } 
    } 
} 

import flash.display.Loader; 
import flash.events.Event; 
import flash.events.EventDispatcher; 
import flash.events.IEventDispatcher; 
import flash.net.URLRequest; 

internal class QueueLoader extends EventDispatcher { 
    private var _list:Array; 
    private var _cursor:int; 
    private var _loading:Boolean; 

    public function QueueLoader(target:IEventDispatcher = null) { 
     super(target); 
     _list = []; 
    } 

    public function addItem(url:String):int { 
     var item:Object = {url: url, id: ++_cursor}; 
     _list.push(item); 
     loadNext(); 
     return item.id; 
    } 

    override public function dispatchEvent(evt:Event):Boolean { 
     if (hasEventListener(evt.type) || evt.bubbles) { 
      return super.dispatchEvent(evt); 
     } 
     return true; 
    } 

    protected function loadNext():void { 
     if (_list.length > 0 && !_loading) { 
      var loader:Loader = new Loader(); 
      var data:Object = _list[0]; 
      var request:URLRequest = new URLRequest(data.url); 
      loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete, false, 0, true); 
      loader.load(request); 
      _loading = true; 
     } 
    } 

    private function onComplete(e:Event):void { 
     var data:Object = _list.shift(); 
     data.content = e.currentTarget.content; 
     dispatchEvent(new QueueLoaderEvent(QueueLoaderEvent.COMPLETE, data.id, data)); 
     _loading = false; 
     loadNext(); 
    } 
} 

internal class QueueLoaderEvent extends Event { 

    public static const COMPLETE:String = "queueLoaderEventComplete"; 

    private var _id:int; 
    private var _data:Object; 

    public function QueueLoaderEvent(type:String, $id:int, $data:Object, bubbles:Boolean = false, cancelable:Boolean = false) { 
     _id = $id; 
     _data = $data; 
     super(type, bubbles, cancelable); 
    } 

    override public function clone():Event { 
     return new QueueLoaderEvent(type, id, data, bubbles, cancelable); 
    } 

    public function get id():int { 
     return _id; 
    } 

    public function get data():Object { 
     return _data; 
    } 
} 

的LoadImage mehtod將着眼於年底:

public static function loadImage(path:String):int 
{ 
    return queueLoader.addItem(path); 
} 
+0

矯枉過正,用戶要求最低限度的更改解決方案。他唯一需要的改變是在本地匿名函數中移動變量和返回語句。實際上,他可能只需要在函數中進行回調。 –

+0

爲什麼矯枉過正?準備好使用,非常小,易於理解的實用程序。如果他將在當前'loadImage'實現中更改多行代碼,那麼這樣做也會帶來更多好處。 –

+1

那麼有很多原因,首先解決這個問題的最低限度只需要在他當前的實現中添加幾行代碼。用戶的實現也比使用你建議的類更快。然後在使用該類作爲加載器時存在很多問題。只要命名一個非常明顯的名稱,「dispatchEvent」每次調用時都會在內存中創建一個新對象,但速度很慢。流水線化的加載器會支持回調,並且除非絕對需要,否則不依賴於'dispatchEvent'。即使那樣我會建議信號。 –