1

私はユニバーサルアセットローダークラスを作成しようとしています(stackoverflowの人々の助けを借りて)。これは、以前にダウンロードしたアセットを連想配列に格納することで記憶します。

これが最終結果です。

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
}

キャッシュされたバージョンがロードされているとき、オランダ語で次のエラーが発生します: "TypeError:Error#1034:Afgedwongen typeomzetting is mislukt:kan flash.display :: MovieClip @ 5c13421 niet omzetteninflash.display.Bitmap。atGameShip/ onShipAssetComplete ()」-「タイプ変換に失敗しました。flash.display:: MovieClip@...をflash.display.Bitmapに変換できません」などの意味です。

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

4

2 に答える 2

3

機能のカプセル化に忙しい場合、なぜあなたが使用に固執しているのかわかりませんcontentLoaderInfo-先に進んでデータもカプセル化してください。また、実際のオブジェクトへの単純な参照ではなく、オブジェクトのバイトを格納するのはなぜですか?

これが私の言いたいことの例です。1つの縮退したケースを見てください...これはキャッシュできるリクエストですが、laoderがロード中のためではありません...

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();
    }
}
}

変更されたアセットローダー:

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;
    }
}
}
于 2009-08-15T15:27:48.537 に答える
1

あなたはおそらくそれを知っているでしょうが、それを行うas3(バルクローダー)用のオープンソースライブラリはるかにあります。(私が作者なので、ここに恥知らずなプラグイン。

少なくとも、ソースコードを読むことで、取り組むべき問題や、おそらくいくつかの実装の指針についてのアイデアが得られるかもしれません。

乾杯アーサー・デバート

于 2009-08-18T11:31:19.677 に答える