gpt4 book ai didi

actionscript-3 - 运行时加载外部 Assets 并在 actionscript 3 中重新使用预加载的 Assets ?

转载 作者:行者123 更新时间:2023-12-04 07:04:51 26 4
gpt4 key购买 nike

我正在创建一个 2d flash 游戏(在 flex/actionscript 3 中编码),在需要时下载 Assets 。目前我有这样的设置:

资源加载器.as

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

public class AssetLoader extends Loader
{
//set vars
private var url:String = "http://test.com/client/assets/";

public function AssetLoader(url:String)
{
Logger.log("AssetLoader request: " + this.url + url);
var request:URLRequest = new URLRequest(this.url + url);
this.load(request);
}
}
}

然后,在我要加载 Assets 的地方,我执行以下操作:
var asset:AssetLoader = new AssetLoader("ships/" + graphicId + ".gif");
asset.contentLoaderInfo.addEventListener(Event.COMPLETE, onShipAssetComplete, false, 0, true);

private function onShipAssetComplete(event:Event):void
{
var loader:Loader = Loader(event.target.loader);
shipImage = Bitmap(loader.content);
shipImage.smoothing = true;
addChild(shipImage);
}

问题是,这种方法不会检查已经下载的 Assets ,所以它会在第二次请求相同的 Assets 时重新下载它们(我认为)。

所以,我需要的是一个存储所有下载 Assets 的数组,并根据请求检查该 Assets 的名称是否存在于数组中。因此,如果它已经被下载,则必须从内存中返回该 Assets ,而不是重新下载。

我可以使assetloader成为一个静态类,但是我必须等待事件在下载完图像后触发——所以我不能简单地让静态函数返回相应的图像。知道我应该怎么做吗?

编辑评论后尝试:
package
{
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;

public final class AssetManager
{
private static var assets:Object = {};
private static var preUrl:String = Settings.ASSETS_PRE_URL;

public static function load(postUrl:String):*
{
if (assets[postUrl])
{ //when the asset already exists
//continue
}
else
{ //the asset still has to be downloaded
var request:URLRequest = new URLRequest(preUrl + postUrl);
var loader:Loader = new Loader();
loader.load(request);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,
function(event:Event):void
{
var loader:Loader = Loader(event.target.loader);
assets[postUrl] = loader.content;
}, false, 0, true);
}
}
}
}

EDIT2:再次尝试
package
{
import flash.display.Loader;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.net.URLRequest;

public final class AssetManager
{
private static var assets:Object = {};
private static var preUrl:String = Settings.ASSETS_PRE_URL;

public static function load(postUrl:String):*
{
if (assets[postUrl])
{ //the asset already exists
var dispatcher:EventDispatcher = new EventDispatcher();
dispatcher.dispatchEvent(new CustomEvent(CustomEvent.LOAD_COMPLETE, assets[postUrl]));
}
else
{ //the asset still has to be downloaded
var request:URLRequest = new URLRequest(preUrl + postUrl);
var loader:Loader = new Loader();
loader.load(request);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,
function(event:Event):void
{
var loader:Loader = Loader(event.target.loader);
assets[postUrl] = loader.content;
var dispatcher:EventDispatcher = new EventDispatcher();
dispatcher.dispatchEvent(new CustomEvent(CustomEvent.LOAD_COMPLETE, assets[postUrl]));
}, false, 0, true);
}
}
}
}

然后,我尝试以下操作:
var asset:AssetManager = AssetManager.load("ships/" + graphicId + ".gif");
asset.addEventListener(CustomEvent.LOAD_COMPLETE, onShipAssetComplete, false, 0, true);

但是得到一个错误,“未定义的方法 addEventListener 由静态 AssetManager 类型的引用”(粗略翻译)。

最佳答案

您可以在 AssetLoader 类中添加一个静态对象(用作字典,其中 Assets 的 url 作为键, Assets 的内容作为值),同时继续以您现在使用的方式使用该类。

private static var assets:Object = {};

不同之处在于,如果之前已经请求过内容的 URL,则您的类将需要检查该静态对象。如果有,立即分派(dispatch)完成事件。如果没有,请按照正常程序进行,不要忘记用新加载的 Assets 填充静态对象。

更新:

这是我的意思的一个简单例子。我没有时间对此进行测试,但它应该可以工作。

注:
您必须调用您创建的 AssetLoader 实例的 loadAsset() 方法才能实际加载 Assets 。这与我们扩展的 Loader 类的工作方式是一致的。
在调用 loadAsset() 方法之前,您应该始终添加所有事件监听器。在您的问题中,您从构造函数中调用 load() 方法,然后才为 Event.COMPLETE 添加事件监听器。这可能会产生奇怪的结果。

这是代码:
package
{
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;


public class AssetLoader extends Loader
{
private static const BASE_URL:String = 'http://test.com/client/assets/';

public static var storedAssets:Object = {};

private var assetURL:String;
private var urlRequest:URLRequest;
private var cached:Boolean = false;


public function AssetLoader(url:String):void
{
trace('Loading: ' + url);
assetURL = url;

if (storedAssets[assetURL] != null)
{
cached = true;
trace('Cached');
}
else
{
trace('Loading uncached asset');
urlRequest = new URLRequest(BASE_URL + assetURL);
contentLoaderInfo.addEventListener(Event.COMPLETE, OnAssetLoadComplete);
}
}

public function loadAsset():void
{
if (cached)
loadBytes(storedAssets[assetURL]);
else
load(urlRequest);
}

private function OnAssetLoadComplete(event:Event):void
{
storedAssets[assetURL] = contentLoaderInfo.bytes;
trace('Loaded ' + contentLoaderInfo.bytesLoaded + ' bytes');
}

}

}

更新 2:

以下是如何使用上面的类:
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
}

关于actionscript-3 - 运行时加载外部 Assets 并在 actionscript 3 中重新使用预加载的 Assets ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1263177/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com