我一直在尝试创建一个通用资产加载器类(在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:错误#1034:Afgedwongen typeomzetting is mislukt:kan flash.display :: MovieClip @ 5c13421 niet omzetten in flash.display.Bitmap。at GameShip / onShipAssetComplete()“ - 表示”类型转换失败,无法将flash.display :: MovieClip @ ...转换为flash.display.Bitmap“。
所以,我想知道,我应该如何扩展这个加载器类并让它以正确的方式返回缓存资产?我在数组中存储资产的方式可能无效吗?或者我应该在AssetLoader方法中使用除了loadBytes之外的其他内容吗?
答案 0 :(得分: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();
}
}
}
已更改的资产加载程序:
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;
}
}
}
答案 1 :(得分:1)
您可能已经意识到这一点,但是有一个as3(bulkloader)的开源库可以做到这一点以及更多。 (这里是无耻的插件,因为我是作者。
至少,阅读源代码可能会为您提供解决问题的想法,也许还有一些实现指针。
干杯 亚瑟·德伯特