What am I missing in this Embed & Texture create code? - actionscript-3

I am trying to follow the Starling video tutorials by Hemanth Sharma. I have typed the code as he has done on his 2nd video (linked here), but I am having difficulty getting the same results.
At first, when my code matched Mr. Sharma's and appeared as:
var bitmap:Bitmap = new Assets[name]();
gameTextures[name] = Texture.fromBitmap( bitmap );
I received the error using this code. The error stated that I was trying to instantiate a class from a non-object.
I traced the code process by breaking this into steps. Now my code appears as:
trace( "Building for", name );
var classObj : Class = Assets[name];
trace( "Class", classObj );
var bitmap : Bitmap = new classObj() as Bitmap;
trace( "Bitmap", bitmap );
trace( "Assign value" );
Assets["gameTextures"][name] = Texture.fromBitmap( bitmap );
trace("Value assigned" );
Using this code, I am able to see that the reason I get the error with Mr. Sharma's code is that the classObj, which Mr. Sharma accesses using Assets[name], initializes to null.
Mr. Sharma has no constructor to set the value of the static variables, so I assume that the Embed meta tag has something to do with the assignment of value to this field.
I will copy my code from that file and paste it below.
Does anyone see where I am making my error?
Can anyone explain how Embed metatags work so that I can find the error with more skill than I have now?
Assets.as:
package
{
import flash.display.Bitmap;
import flash.utils.Dictionary;
import starling.textures.Texture;
public class Assets
{
[Embed(source="../media/graphics/bgWelcome.jpg")]
public static const BgWelcome:Class;
[Embed(source="../media/graphics/welcome_hero.png")]
public static const WelcomeHero:Class;
[Embed(source="../media/graphics/welcome_title.png")]
public static const WelcomeTitle:Class;
[Embed(source="../media/graphics/welcome_playButton.png")]
public static const WelcomePlayButton:Class;
[Embed(source="../media/graphics/welcome_aboutButton.png")]
public static const WelcomeAboutButton:Class;
private static var gameTextures:Dictionary = new Dictionary();
public static function getTexture( name: String ): Texture
{
if( Assets.gameTextures[name] == undefined ){
trace( "Building for", name );
var classObj : Class = Assets[name];
trace( "Class", classObj );
var bitmap : Bitmap = new classObj() as Bitmap;
trace( "Bitmap", bitmap );
trace( "Assign value" );
Assets["gameTextures"][name] = Texture.fromBitmap( bitmap );
trace("Value assigned" );
}
return Assets.gameTextures[name];
}
}
}

You as well might try..catch it to diagnose error immediately.
public static function getTexture(name:String):Texture
{
if (!Assets.gameTextures[name])
{
try
{
var aClass:Class = Assets[name];
var aRaster:Bitmap = new aClass();
Assets.gameTextures[name] = Texture.fromBitmap(aRaster);
}
catch (fail:Error)
{
throw "There's no texture <" + name + "> in Assets.";
}
}
return Assets.gameTextures[name];
}

I'm currently working on a game and have a similar setup like yours, this is the code I have been using with success:
EmbeddedAssets.as (inside a folder named utils):
package utils
{
import starling.textures.Texture;
public class EmbeddedAssets
{
[Embed(source = "./../assets/icons/stats.png")]
private static const stats:Class;
public static const statsButtonTexture:Texture = Texture.fromEmbeddedAsset(stats);
Embed(source = "./../assets/icons/stats_down.png")]
private static const stats_down:Class;
public static const statsButtonDownTexture:Texture = Texture.fromEmbeddedAsset(stats_down);
}
}
Then, somewhere else in my code I use those reference as follows:
private function setStatsButtonStyles(button:Button):void
{
var defaultICon:ImageLoader = new ImageLoader();
defaultIcon.source = EmbeddedAssets.statsButtonTexture;
defaultIcon.width = 60;
defaultIcon.height = 60;
var downIcon:ImageLoader = new ImageLoader();
downIcon.source = EmbeddedAssets.statsButtonDownTexture;
downIcon.width = 60;
downIcon.height = 60;
button.defaultIcon = defaultIcon;
button.downIcon = downIcon;
button.width = button.height = 60;
}
Note that I use a Feathers UI Button, not a Starling one (Feathers Buttons have more functionality but the idea is the same).

Related

synchronous image loading action script 3 flash

I am having a problem with my flash/as3 application. I've created most of it and at the moment I'm struggling to get my external resources work.
My application consists of a Controller class, that takes control of an application flow. At the beginning it initializes AppInitializer class, that loads / generates the whole app content (it is a simple point'n'click game).
In AppInitializer I create an array of items available in a game. Item's constructor takes path as a parameter (String) to the resource (image). Then, inside the constructor I call a static method of my AssetsLoader class which looks like that:
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;
}
Where completed is a static variable of AssetsLoader.
First problem is: I create many Item objects in a row, so the method loadImage should not be static I guess (same with completed variable), since that may cause problems when loading.
Second problem is: At the moment I'm unable to return the bitmapData (or bitmap, it does not really matter), because the return statement will always return null - because the resource is loaded asynchronously and is not loaded at the time application reaches return statement. If I uncomment the wile loop, the complete event is never called.
I would like to ask more experienced ActionScript developers to point out any solutions that would require minimal changes to the rest of my app and would solve those problems. (I think first problem can be eliminated by using some sort of queueing method for the loader, but I'm stuck with the second problem for few days so far and came up with no possible solution).
I could also consider changes in my logic, so I could preload all image resources into "somewhere" and after that just make copies of these images for my purposes. If that's easier to do.
So as I suggested in the comments, a minimal change resolution could simply be to pass a function to call as part of the parameters for loadImage(). This is known as a callback function, and it would look something like this:
First create the callback function:
public function addImage( bitmapData:BitmapData ):void {
//do something with the bitmapData returned
}
Next adjust your loadImage() local function to use the callback with the bitmap data when the event has completed:
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));
}
Then just you make the call to loadImage() like so:
loadImage( myPathToImage, addImage );
That is a simply resolution and does exactly what you need it to.
Super, you commented that insane line of code with while ;)
Here for you, simple QueueLoader (It loads items one by one, when you add item to the queue, you can store id of item in queue), that will help you with your task:
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;
}
}
Your loadImage mehtod will look at the end:
public static function loadImage(path:String):int
{
return queueLoader.addItem(path);
}

flash as3 serial port

Hey trying to bring data in through the serial port but i get this error.
1037: Packages cannot be nested.
I then need to take these values and use 1 to control video playback and the other to control the audio volume
package
{
import flash.display.Sprite;
import flash.net.XMLSocket;
import flash.events.DataEvent;
public class receiveData extends Sprite
{
public static const PORT:Number = 5331;
public static const COMMA:String = ",";
public static const LOCALHOST:String = "127.0.0.1";
private var socket:XMLSocket = null;
public function receiveData()
{
super();
init();
}
private function init():void
{
socket = new XMLSocket();
socket.addEventListener( DataEvent.DATA, doSocketData );
socket.connect( LOCALHOST, PORT );
}
protected function doSocketData( event:DataEvent ):void
{
var parts:Array = null;
var sensorone:Number = 0;
var sensortwo:Number = 0;
var values:String = event.data.toString();
parts = values.split( COMMA );
trace( parts[0]);
trace( parts[1]);
sensorone = new Number( parts[0] );
sensortwo = new Number( parts[1] );
}
}
}
So basically you need to put that code in a separate AS3 file and set that as the document class or as the class file for a MovieClip you make in Flash. Alternatively you could use a different IDE like FlashBuilder or FlashDevelop or FDT and avoid the Flash IDE (which as a programmer primarily I feel muddles things up quite a bit).
http://www.actionscript.org/forums/showthread.php3?t=136364 (haha SO won't let me LMGTFY)
Looks like you're on the right track though if you're using tinkerproxy or something of the sort to forward the data (have fun I gotta get myself back into that, check out links in th description of my vid http://www.youtube.com/watch?v=71eFWknHKEM&list=UUSz-eugjE1d6yki6ZT51CKg&index=17&feature=plcp :)

Read/write as3 zip using fzip

I'm creating a custom file type in AIR, which is a zip file under a different extension. I've been trying a few libs out, and settled on Fzip. This is to house my apps project files.
The tests seem to run OK, apart from occasionally getting 'Unknown record signature' Error.
I'm wondering if I'm missing something, and perhaps someone can shed some light. First time I've attempted something like this.
It seems to occur randomly, I have a basic app which allows you to add new files at runtime. Contents display in a list and upon select you view the text content.
From time to time when adding a new file, saving, then reopening I get this unknown record error. The main functions which could be the cause
private function openComplete( event:Event ):void {
_zipFile.loadBytes( _file.data );
dispatch( new ZipServiceEvent( ZipServiceEvent.CONTENTS_CHANGE ) );
}
public function saveFile( event:Event=null ):void {
if( _file.isDirectory ) {
browseForSave();
return void;
}
if ( _file.extension != _ext )
_file = new File( _file.nativePath + _ext );
var stream:FileStream = new FileStream();
stream.open( _file, FileMode.WRITE );
_zipFile.serialize( stream );
stream.close();
}
public function getFile( name:String ):FZipFile {
return _zipFile.getFileByName( name );
}
public function addFile( name:String, contents:ByteArray ):void {
_zipFile.addFile( name, contents );
}
private function saveFileHandler( event:Event ):void {
var contents:ByteArray = new ByteArray();
contents.writeMultiByte( view.filecontents.text, 'utf-8' );
model.addFile( view.filename.text, contents );
}
I would need to test you class to look for errors… I wont have time to check it but in the meanwhile I´ll post an Util class I created for this purpose. It´s not very extensive, it was just for a small project but it may help you…
package com.models
{
import com.events.AppEvent;
import deng.fzip.FZip;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.utils.ByteArray;
public class ZIPEncoder extends EventDispatcher
{
private var _zip:FZip;
private var _compressedBytes:ByteArray = new ByteArray();
public function ZIPEncoder(target:IEventDispatcher=null)
{
super(target);
}
public function newZip(name:String = ""):void
{
if(_zip) _zip = null;
_zip = new FZip();
_zip.addEventListener(Event.COMPLETE, onZipComplete);
}
public function newEntry(name:String, bytes:ByteArray):void
{
if(_zip == null)
{
throw(new Error("No zipOutput initialized. Call newZip() to initialize a new ZipOutput object before creating entry instances"));
return;
}
_zip.addFile(name, bytes);
}
public function compress():void
{
_zip.serialize(_compressedBytes, false);
dispatchEvent(new AppEvent(AppEvent.ZIP_ENCODED, _compressedBytes));
}
private function onZipComplete(event:Event):void
{
dispatchEvent(new AppEvent(AppEvent.ZIP_ENCODED, _compressedBytes));
}
//public function get zip():ZipOutput { return _zip; }
}
}
hope it helps…

sound stream stops loading

I have a little sound stream script here, but sometimes if you press play to the next track before the current has done loading the next track doesn't comeplete loading
package player {
import flash.events.Event;
import flash.display.Sprite;
import flash.external.ExternalInterface;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.net.URLRequest;
import player.Loader_bar;
public class Stream extends Sprite {
private var _Sound = null;
private var _Channel = null;
private var isLoading = false;
private var _Loader_bar = null;
public var loader_color = null;
public var loader_width = 0;
public var loader_height = 0;
private var i = 0;
public function Stream(){
this._Loader_bar = new Loader_bar();
addChild(this._Loader_bar);
}
public function cnstr(){
this._Loader_bar.color = this.loader_color;
this._Loader_bar.w = this.loader_width;
this._Loader_bar.h = this.loader_height;
this._Loader_bar.cnstr();
}
public function play(url){
this.stop();
this.close();
this._Sound = new Sound();
this.isLoading = true;
this.addEventListener(Event.ENTER_FRAME, listener_bytesLoaded);
this._Sound.addEventListener(Event.COMPLETE, listener_loadedComplete);
this._Sound.load(new URLRequest(url));
this._Channel = this._Sound.play();
}
public function stop(){
if(this._Channel){
this._Channel.stop();
}
}
private function close(){
if(this.isLoading){
this._Sound.close();
}
}
private function listener_loadedComplete(event){
this.close();
this.isLoading = false;
this.removeEventListener(Event.ENTER_FRAME, listener_bytesLoaded);
}
private function listener_bytesLoaded(event){
var float = this._Sound.bytesLoaded / this._Sound.bytesTotal;
this._Loader_bar.progress(float);
var data = {
i : this.i,
float : float,
loaded : this._Sound.bytesLoaded,
total : this._Sound.bytesTotal
};
ExternalInterface.call('swf2js', 'tst_progress', data);
this.i++;
}
}
}
close():void
Closes the stream, causing any download of data to cease.
try this:
create a boolean like hasLoaded, set it to false. When the sound successfully loads set it to true.
Then when you play a sound you can test for hasLoaded in your play() function. If you have called play() before your previous sound has loaded, hasLoaded will be false, in which case you call this._Sound.close() before creating and loading the new sound. The reason for testing instead of just calling close() is so if you have paused the stream you don't have to reload it to play it again.
ADDITION:
Concerning the load not reporting properly, you have your progress logic set up incorrectly. Try this:
1) import flash.events.ProgressEvent
2) For the listener, replace this.addEventListener(Event.ENTER_FRAME, listener_bytesLoaded); in your play() method with this._Sound.addEventListener(ProgressEvent.PROGRESS, listener_bytesLoaded);
3) Change your listener_bytesLoaded() method to the following:
private function listener_bytesLoaded(event:ProgressEvent)
{
var percent = event.bytesLoaded / event.bytesTotal;
this._Loader_bar.progress(percent);
var data = {
i : this.i,
float : percent,
loaded : event.bytesLoaded,
total : event.bytesTotal
};
ExternalInterface.call('swf2js', 'tst_progress', data);
this.i++;
}
4) Change this.removeEventListener(Event.ENTER_FRAME, listener_bytesLoaded);
in your listener_loadedComplete() method to this._Sound.removeEventListener(ProgressEvent.PROGRESS, listener_bytesLoaded); and then move it out of that method and place it inside the conditional in the close() method.
NOTE - I didn't actually compile this but I think its good to go. Hope that helps. :)

Run-time loading of external assets and re-using preloaded assets in actionscript 3?

I'm creating a 2d flash game (coded in flex/actionscript 3) where assets are downloaded when they are needed. Currently I have it setup like this:
AssetLoader.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);
}
}
}
Then, where I want to load the asset I do the following:
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);
}
The thing is, that this method doesn't check for already downloaded assets, so it will redownload them the second time the same asset is being requested (I think).
So, what I need is an array where all downloaded assets are stored, and on request the name of this asset is checked for existance in the array. So if it has already been downloaded, that asset from memory must be returned rather than redownloaded.
I could make the assetloader a static class, but I have to wait for the event to fire when it's done downloading the image - so I can't simply let a static function return the corresponding image. Any idea how I should do this?
EDIT for an attempt after comments:
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: another attempt
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);
}
}
}
}
Then, I try the following:
var asset:AssetManager = AssetManager.load("ships/" + graphicId + ".gif");
asset.addEventListener(CustomEvent.LOAD_COMPLETE, onShipAssetComplete, false, 0, true);
But get an error, "undefined method addEventListener by a reference of the type static AssetManager" (roughly translated).
You could add a static object (used as a dictionary with urls for assets as keys and the content for assets as values) in the AssetLoader class and in the same time keep using the class in the way you're using it right now.
private static var assets:Object = {};
The difference would be that your class would need to check against that static object if the URL for the content has already been requested previously. If it has, dispatch the complete event immediately. If it hasn't, follow the normal routine and don't forget to populate your static object with the newly loaded asset.
Update:
This is a quick example of what I meant. I haven't had time to test this, but it should work.
Note:
You must invoke the loadAsset() method of the AssetLoader instances you create in order to actually load the asset. This is consistent with the way the Loader class we're extending works.
You should always add all event listeners BEFORE invoking the loadAsset() method. In your question you're calling the load() method from within the constructor and only afterwards add the event listener for Event.COMPLETE. This could produce strange results.
Here's the code:
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');
}
}
}
Update 2:
Here's how one would use the class above:
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
}
Perhaps you should take a look at Bulk Loader. It does the kinds of things your looking to do. If you really want to use a custom solution, it would be a great point of reference, but why reinvent the wheel?
Tyler.
Here is an alteration of your load command to capture the resourceId
public function load(postUrl:String):*
{
var index:int;
if ((index = assetExists(postUrl)) != -1)
{
dispatchEvent(new CustomEvent(CustomEvent.LOAD_COMPLETE, asset[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)
{
// NOTE: not sure on scoping here ...
// pretty sure you're this will be the Loader
// if not just read it off the event like you were before
assets[postUrl] = content;
dispatchEvent(new CustomEvent(CustomEvent.LOAD_COMPLETE, asset[postUrl]));
}, false, 0, true);
}
}
/* In a new file */
public class CustomEvent extends Event
{
public static const LOAD_COMPLETE:String = "CustomEvent_LoadComplete";
// If you know the type you should use it (e.g. Sprite/DisplayObject)
public var content:*;
public function CustomEvent(type:String, _content:*)
{
content = _content;
super(type);
}
}
Note: when you write an Event descendant you should also override the toString and clone methods. I've also cheated on the constructor since you may want to pass through weakReferences and things like that.