2009-08-15 3 views
1

私は連想配列に格納することでpreviouselyダウンロードした資産を覚えている、(ここではstackoverflowの時の人々の助けを借りて)ユニバーサル資産ローダークラスを作成しようとしてきました。ハウツーは、Loaderクラスを拡張およびActionScript/Flex 3の中にキャッシュされた資産を返しますか?

これは、最終的な結果である:

AssetLoader.as

package 
{ 
    import flash.display.Loader; 
    import flash.events.Event; 
    import flash.net.URLRequest; 
    import flash.utils.ByteArray; 

    public final class AssetLoader extends Loader 
    { 
     public static var storedAssets:Object = {}; 
     private var postUrl:String; 
     private var urlRequest:URLRequest; 
     private var cached:Boolean = false; 

     public final function AssetLoader(postUrl:String):void 
     { 
      this.postUrl = postUrl; 
      if (storedAssets[postUrl]) 
      { 
       cached = true; 
      } 
      else 
      { 
       urlRequest = new URLRequest(Settings.ASSETS_PRE_URL + postUrl); 
       contentLoaderInfo.addEventListener(Event.COMPLETE, OnAssetLoadComplete); 
      } 
     } 

     //starts loading the asset 
     public final function loadAsset():void 
     { 
      if (cached) 
      { 
       loadBytes(storedAssets[postUrl]); 
      } 
      else 
      { 
       load(urlRequest); 
      } 
     } 

     //runs when the asset download has been completed 
     private final function OnAssetLoadComplete(event:Event):void 
     { 
      storedAssets[postUrl] = contentLoaderInfo.bytes; 
     } 
    } 
} 

がSettings.ASSETS_PRE_URL今すぐ "http://site.com/assets/"

に等しく、私の問題は、たびにクライアントがクラッシュする原因になっているということです

var assetLdr:AssetLoader = new AssetLoader("ships/" + graphicId + ".gif"); 
assetLdr.contentLoaderInfo.addEventListener(Event.COMPLETE, onShipAssetComplete); 
assetLdr.loadAsset(); 

private function onShipAssetComplete(event:Event):void 
{ 
    var shipImage:Bitmap = Bitmap(event.target.loader.content); 
    // Do stuff with shipImage 
} 
:クラスからのキャッシュバージョンを(新たにダウンロード1が作業を行う)取得しようとしますキャッシュされたバージョンがロードされている場合は

、私はオランダ語で次のエラーを取得する:「例外TypeError:エラー#1034:Afgedwongenのtypeomzettingはmisluktです:flash.display.Bitmap中館は、flash.display ::ムービークリップ@ 5c13421 nietのomzetten。 GameShip/onShipAssetComplete() " - タイプ変換が失敗した、flash.display :: MovieClip @ ...をflash.display.Bitmapに変換できないなどの意味です。

このローダークラスを拡張し、キャッシュされたアセットを正しい方法で返すようにしますか?アセットに配列を格納する私の方法はおそらく無効ですか?AssetLoaderメソッドでloadBytes以外のものを使用する必要がありますか?

+0

あなたはイーライグリーンフィールドのSuperImageを見てきたキャッシュ・ビットは、実際にはかなりいいです:?http://www.quietlyscheming.com/blog/2007/01/23/some-thoughts-on-doubt-on-flex-as-the-最高のオプション - orhow-i-made-my-flex-images-stop-dancing/ –

+0

私はちょうどそれをチェックアウトしましたが、それはイメージのためのもので、私のクラスはすべてのアセットタイプのものです。私が投稿コードについて間違っているか知っている。 – Tom

答えて

3

なぜ機能がカプセル化されているのであれば、contentLoaderInfoを使用することを強くお勧めしますか?データをカプセル化して実際のオブジェクトを参照するのではなく、オブジェクトのバイトを格納する理由は?

ここに私が意味するものの例があります。

:アップ変更資産ローダー

package 
{ 

import flash.display.BitmapData; 
import flash.display.Sprite; 

public class TestAssetLoader extends Sprite 
{ 
    public var loader:AssetLoader; 
    public var degenerateLoader:AssetLoader; 
    public var cachedLoader:AssetLoader; 

    public function TestAssetLoader() 
    { 
     loader = new AssetLoader("picasso_blue_guitar.jpg"); 
     loader.addEventListener(AssetLoaderEvent.ASSET_LOAD_COMPLETE, handleAssetLoaded); 
     loader.loadAsset(); 

     // NOTE: you'll have to think about this case .... 
     // where an asset is in the process of loading when you get another request 
     // e.g. it isn't yet cached but is already being loaded ... 
     degenerateLoader = new AssetLoader("picasso_blue_guitar.jpg"); 
     degenerateLoader.loadAsset(); 
    } 

    private function handleAssetLoaded(event:AssetLoaderEvent):void 
    { 
     // here is your content 
     // var myImage:Bitmap = Bitmap(event.content); 

     // This is guaranteed to hit the cache 
     cachedLoader = new AssetLoader("picasso_blue_guitar.jpg"); 
     cachedLoader.loadAsset(); 
    } 
} 
} 

...それがキャッシュされる可能性が要求されるが、laoderがロードの過程にあるためではありません... 1つの縮退ケースを見てみましょう

package 
{ 
    import flash.display.Loader; 
    import flash.events.Event; 
    import flash.net.URLRequest; 

    public final class AssetLoader extends Loader 
    { 
     public static var ASSETS_PRE_URL:String = ""; 

     public static var storedAssets:Object = {}; 
     private var postUrl:String; 

     public final function AssetLoader(_postUrl:String):void 
     { 
       postUrl = _postUrl; 
     } 

     //starts loading the asset 
     public final function loadAsset():void 
     { 
      if(storedAssets[postUrl]) 
      { 
       trace("cached load"); 

       var resource:DisplayObject = storedAssets[postUrl]; 

       if(resource is Bitmap) 
       { 
        resource = new Bitmap(Bitmap(resource).bitmapData); 
       } 

       dispatchEvent(new AssetLoaderEvent(AssetLoaderEvent.ASSET_LOAD_COMPLETE, resource)); 
      } 
      else 
      { 
       var urlRequest:URLRequest = new URLRequest(ASSETS_PRE_URL + postUrl); 
      contentLoaderInfo.addEventListener(Event.COMPLETE, OnAssetLoadComplete); 
       load(urlRequest); 
      } 
     } 

     //runs when the asset download has been completed 
     private final function OnAssetLoadComplete(event:Event):void 
     { 
      trace("non-cached load"); 
      var loader:Loader = Loader(event.target.loader); 
      storedAssets[postUrl] = loader.content; 
      dispatchEvent(new AssetLoaderEvent(AssetLoaderEvent.ASSET_LOAD_COMPLETE, loader.content)); 
     } 
    } 
} 

とイベント:

package 
{ 
import flash.display.DisplayObject; 
import flash.events.Event; 

public class AssetLoaderEvent extends Event 
{ 
    public static const ASSET_LOAD_COMPLETE:String = "AssetLoaderEvent_LoadComplete"; 

    public var content:DisplayObject; 

    public function AssetLoaderEvent(type:String, _content:DisplayObject, bubbles:Boolean=false, cancelable:Boolean=false) 
    { 
     content = _content; 
     super(type, bubbles, cancelable); 
    } 

    override public function clone():Event 
    { 
     return new AssetLoaderEvent(type, content, bubbles, cancelable); 
    } 

    override public function toString():String 
    { 
     return "[AssettLoaderEvent] " + type; 
    } 
} 
} 
+0

ありがとうございましたが、試しましたか?私はちょうど私のコードでそれを実装し、最初の画像はうまくロードされ(ダウンロードされた)、数秒後に私は第2の画像(キャッシュされた)を呼び出し、それは上手くいく。ただし、2番目の(キャッシュされた)イメージがロードされると、最初のイメージが突然消えます。これを引き起こす原因は何ですか? – Tom

+1

うん - 悪いです。私はキャッシュされたコピーを取得するときにBitmapリソースを複製するコードを更新しました。 2つの異なる親を持つステージに同じDisplayObjectを追加することはできません。 Bitmap ...の代わりにマップにbitmapDataを格納することもできます。これはあなた次第です。 –

+0

ありがとうございます。だから私は音などのために同じ種類のことをしなければならないと思いますか? – Tom

1

おそらく、その認識しているが、それとだけではありませんAS3(bulkloader)のためのオープンソースライブラリがあります。ここで(恥知らずなプラグ、私は著者だからです。

最低でも、ソースコードを読むこと、あなたに取り組むための課題についてのアイデアと、おそらくいくつかの実装ポインタを与えるかもしれない。

乾杯 アーサーDebert

+0

素敵な仕事!私はそれがイメージのためのものだと思ったので私はそれを使用しなかった、ここで間違っているかもしれない。それは、私が欲しいものにはあまりにも多くの機能を持っているように思われ、不要な量のコードにつながるでしょう。 – Tom

+0

何かをロードします。それは16kbでコンパイルされています。大規模な方法では、必要のないローディングタイプや便利なメソッド(getNetStream、getSoundなど)を削除してください。 –

関連する問題