Chunky Chunk
Chunky Chunk

Reputation: 17217

Dynamically Creating Variables In Actionscript 3.0?

i'm loading several sound files, and want to error check each load. however, instead programming each one with their own complete/error functions, i would like them to all use the same complete/error handler functions.

a successfully loaded sound should create a new sound channel variable, while an unsuccessfully loaded sound will produce a simple trace with the name of the sound that failed to load. however, in order to do this, i need to dynamically create variables, which i haven't yet figured out how to do.

here's my code for my complete and error functions:

function soundLoadedOK(e:Event):void
 {
 //EX: Sound named "explosion" will create Sound Channel named "explosionChannel"
 var String(e.currentTarget.name + "Channel"):SoundChannel = new SoundChannel();
 }

function soundLoadFailed(e:IOErrorEvent):void
 {
 trace("Failed To Load Sound:" + e.currentTarget.name);
 }

-=-=-=-=-=-=-=-=- UPDATED (RE: viatropos) -=-=-=-=-=-=-=-=-

can not find the error.

TypeError: Error #1009: Cannot access a property or method of a null object reference. at lesson12_start_fla::MainTimeline/loadSounds() at lesson12_start_fla::MainTimeline/frame1():

//Sounds
var soundByName:Object = {};
var channelByName:Object = {};
var soundName:String;
var channelName:String;
loadSounds();

function loadSounds():void
{
    var files:Array = ["robotArm.mp3", "click.mp3"];
    var i:int = 0;
    var n:int = files.length;
    for (i; i < n; i++)
    {
        soundName = files[i];
        soundByName[soundName] = new Sound();
        soundByName[soundName].addEventListener(Event.COMPLETE, sound_completeHandler);
        soundByName[soundName].addEventListener(IOErrorEvent.IO_ERROR, sound_ioErrorHandler);
        soundByName[soundName].load(new URLRequest(soundName));
    }
}

function sound_completeHandler(event:Event):void
{
    channelName = event.currentTarget.id3.songName;
    channelByName[channelName] = new SoundChannel();
}

function sound_ioErrorHandler(event:IOErrorEvent):void
{
    trace("Failed To Load Sound:" + event.currentTarget.name);
}

Upvotes: 1

Views: 2109

Answers (2)

Chunky Chunk
Chunky Chunk

Reputation: 17217

//Load Sounds
var soundDictionary:Dictionary = new Dictionary();
var soundByName:Object = new Object();
var channelByName:Object = new Object();

loadSounds();

function loadSounds():void
    {
    var files:Array = ["robotArm.mp3", "click.mp3"]; //etc.
    for (var i:int = 0; i < files.length; i++)
        {
        var soundName:String = files[i];
        var sound:Sound=new Sound(); 
        soundDictionary[sound] = soundName;
        soundByName[soundName] = sound;
        sound.addEventListener(Event.COMPLETE, sound_completeHandler);
        sound.addEventListener(IOErrorEvent.IO_ERROR, sound_ioErrorHandler); 
        sound.load(new URLRequest(soundName));
        }
    }                                                                        

function sound_completeHandler(e:Event):void
    {
    var soundName:String=soundDictionary[e.currentTarget];                      
    channelByName[soundName] = new SoundChannel();                          
    }

function sound_ioErrorHandler(e:IOErrorEvent):void
    {
    trace("Failed To Load Sound:" + soundDictionary[e.currentTarget]);
    }

//Play Sound
channelByName["robotArm.mp3"] = soundByName["robotArm.mp3"].play();

//Stop Sound
channelByName["robotArm.mp3"].stop();

Upvotes: 0

Lance Pollard
Lance Pollard

Reputation: 79178

You can do this a few ways:

  1. Storing your SoundChannels in an Array. Good if you care about order or you don't care about getting them by name.
  2. Storing SoundChannels by any name in an Object. Good if you want to easily be able to get the by name. Note, the Object class can only store keys ({key:value} or object[key] = value) that are Strings. If you need Objects as keys, use flash.utils.Dictionary, it's a glorified hash.

Here's an example demonstrating using an Array vs. an Object.

var channels:Array = [];
// instead of creating a ton of properties like
// propA propB propC
// just create one property and have it keep those values
var channelsByName:Object = {};

function loadSounds():void
{
    var files:Array = ["soundA.mp3", "soundB.mp3", "soundC.mp3"];
    var sound:Sound;
    var soundChannel:SoundChannel;
    var i:int = 0;
    var n:int = files.length;
    for (i; i < n; i++)
    {
        sound = new Sound();
        sound.addEventListener(Event.COMPLETE, sound_completeHandler);
        sound.addEventListener(IOErrorEvent.IO_ERROR, sound_ioErrorHandler);
        sound.load(files[i]);
    }
}

function sound_completeHandler(event:Event):void
{
    // option A
    var channelName:String = event.currentTarget.id3.songName;
    // if you want to be able to get them by name
    channelsByName[channelName] = new SoundChannel();

    // optionB
    // if you just need to keep track of all of them,
    // and don't care about the name specifically
    channels.push(new SoundChannel())
}

function sound_ioErrorHandler(event:IOErrorEvent):void
{
    trace("Failed To Load Sound:" + event.currentTarget.name);
}

Let me know if that works out.

Upvotes: 3

Related Questions