views:

353

answers:

2

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);
}
+3  A: 

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.

viatropos
sure. but my problem as far as i can see is that while i can iterate thru an array of sounds, sending them all one by one to get complete/error checked, i need to create individual Sound Channel variables for each sound if it has loaded successfully.
TheDarkInI1978
thanks. i see what you are instructing. although i'm still having a error which i can not solve. in order to play a sound, i also need to create a soundByName:Object along with channelByName:Object that stops a sound. i've updated my original post with my new code
TheDarkInI1978
i'm still not understanding what's wrong with my updated code.
TheDarkInI1978
I updated my code and your code up top, we just needed to instantiate the hashes: channelsByName:Object = {}.
viatropos
new problem:ReferenceError: Error #1069: Property name not found on flash.media.Sound and there is no default value. at lesson12_start_fla::MainTimeline/sound_completeHandler()
TheDarkInI1978
i've started a new thread for this new problem since it has left the scope of this thread: http://stackoverflow.com/questions/2395226/actionscript-loading-calling-sounds-from-string-array
TheDarkInI1978
it looks like there is no 'name' property on the sound object: http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/media/Sound.html. Sound does have these two properties: 'url', and 'id3'. I've never used Sound before, but I recommend getting the name via `event.currentTarget.id3.songName': http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/media/ID3Info.html. Updated our answers.
viatropos
A: 
//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();
TheDarkInI1978