Mitsuki MK Kazen
Mitsuki MK Kazen

Reputation: 21

TypeError 1009 and muting sound in AS3

I'm really new to this, so, I'm really sorry if there is some obvious solution that I've somehow missed, but oh well...
I am in the process of making a game, and I was trying to make a character selection menu. Each character would have a unique version of the same song (with the same bps) so that when you were "hovering over" one of the choices, the character's song would play and the other ones would be muted (Not paused or stopped, so as not to lose the synchronisation between all the versions of the song)...
Right now, I was trying to program this for only one of the songs, and then, repeat the method for the other ones once I figured it out.
So...
What am I doing wrong?

Here's the code:

package {

import flash.display.MovieClip;
import flash.events.Event; 
import flash.media.SoundTransform;
import flash.media.Sound;
import flash.media.SoundChannel; 
import flash.media.SoundMixer; 

public class MainThing extends MovieClip {
    private var soulcounting: Number = 1;
    private var Muting: Boolean = false;
    private var snd:Sound = new Sound();

    public function MainThing() {
        snd.load(new URLRequest("SOUL1.mp3"));
        stage.addEventListener(Event.ENTER_FRAME, FrameHandler);
        }

    private function FrameHandler(event: Event): void {
        if (Object(root).currentFrame == 2) {
            var channel:SoundChannel = snd.play(0,1);
            channel.soundTransform = new SoundTransform(1,0);
            /*the soulcounting number is determined by a keyboard function...  
            I didn't deem it necessary to be included in here,  
            as I don't think it is part of the problem.*/
            if (soulcounting == 1) {
                Object(root).SOULS.gotoAndStop(1);
                Muting = false;
                }

            if (soulcounting == 2) {
                Object(root).SOULS.gotoAndStop(2);
                Muting = true;
                }

            if (soulcounting == 3) {
                Object(root).SOULS.gotoAndStop(3);
                Muting = true;
                }

            if (soulcounting == 4) {
                Object(root).SOULS.gotoAndStop(4);
                Muting = true;
                }

            if (soulcounting == 5) {
                Object(root).SOULS.gotoAndStop(5);
                Muting = true;
                }

            if (soulcounting == 6) {
                Object(root).SOULS.gotoAndStop(6);
                Muting = true;
                }

            if(Muting){
                setVolume(channel);
                }

            if(!Muting){
                setVolume(channel, 1);
                }
            } 

    private function setVolume (Soundchannel:SoundChannel, volume:Number=0) {
        var trans:SoundTransform = Soundchannel.soundTransform;
        trans.volume = volume;
        Soundchannel.soundTransform = trans;
        }
    }
}

(If I try to preview the swf, everything works fine until I get to the second frame, in which the Output starts repeating TypeError: Error #1009: Cannot access a property or method of a null object reference. at MainThing/FrameHandler())
TypeError #1009 seems to be a very common mistake around here, but what I have read hasn't really helped me with this problem... Sorry if there was already a solution in here, and I just didn't search enough...
Thanks in advance!

Upvotes: 1

Views: 68

Answers (2)

Mitsuki MK Kazen
Mitsuki MK Kazen

Reputation: 21

Thanks to Pawel Audionysos and VC.One for helping me with my problem. I solved it! Instead of using the SoundTransform.volume function, I used the SoundChannel.position and a variable to "save" the position at which the previous song stopped, so that the next one would start from that point: Here's the code if anyone's interested:

package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.media.SoundTransform;
import flash.media.Sound;
import flash.media.SoundChannel; 
import flash.media.SoundMixer; 
import flash.net.URLLoader;
import flash.net.URLRequest;

public class MainThing extends MovieClip {
    private var bool:Boolean = false;
    private var snd1:Sound = new Sound();
    private var snd2:Sound = new Sound();
    private var snd3:Sound = new Sound();
    private var snd4:Sound = new Sound();
    private var snd5:Sound = new Sound();
    private var snd6:Sound = new Sound();
    private var channel1:SoundChannel = new SoundChannel();
    private var channel2:SoundChannel = new SoundChannel();
    private var channel3:SoundChannel = new SoundChannel();
    private var channel4:SoundChannel = new SoundChannel();
    private var channel5:SoundChannel = new SoundChannel();
    private var channel6:SoundChannel = new SoundChannel();
    private var songtime:Number = 0;
    private var NoSongHasBeenPlayedYet:Boolean = true;
    private var comesfromnothing:Boolean = true;
    private var comesfrom1:Boolean = false;
    private var comesfrom2:Boolean = false;
    private var comesfrom3:Boolean = false;
    private var comesfrom4:Boolean = false;
    private var comesfrom5:Boolean = false;
    private var comesfrom6:Boolean = false;

    public function MainThing() {
        snd1.load(new URLRequest("SOUL1.mp3"));
        snd2.load(new URLRequest("SOUL2.mp3"));
        snd3.load(new URLRequest("SOUL3.mp3"));
        snd4.load(new URLRequest("SOUL4.mp3"));
        snd5.load(new URLRequest("SOUL5.mp3"));
        snd6.load(new URLRequest("SOUL6.mp3"));
        stage.addEventListener(KeyboardEvent.KEY_DOWN, MenuButtons);

        stage.addEventListener(Event.ENTER_FRAME, FrameHandler);
    }
    private function FrameHandler(event: Event): void {
        if (Object(root).currentFrame == 2) {
            //I ommitted the part of the changes to the MovieClip's frames
            //the music function is called here... It didn't work anywhere else.
            Music();
            }
        } 
    private function Music():void{
        if(NoSongHasBeenPlayedYet){
            //this part happens either when the frame has just changed, or when the "songtime" variable has surpassed the audio length.
            comesfromnothing = true;
            channel1 = snd1.play(0,100);
            channel2 = snd2.play(0,100);
            channel3 = snd3.play(0,100);
            channel4 = snd4.play(0,100);
            channel5 = snd5.play(0,100);
            channel6 = snd6.play(0,100);
            NoSongHasBeenPlayedYet = false;
            bool = false;

            }
        if(!bool && songtime < 15150){
            switch(soulcounting){
                //In the original, there are 6 cases, for each song. I didn't put all of them in here because they are mostly the same, just with different numbers.
                case 1:
                    if(comesfromnothing){
                        trace(songtime);
                        songtime = channel2.position;
                        channel1.stop();
                        channel2.stop();
                        channel3.stop();
                        channel4.stop();
                        channel5.stop();
                        channel6.stop();
                        channel1 = snd1.play(songtime,100);
                        songtime = channel1.position;   
                        //the bool variable is there so that it doesn't create a new SoundChannel at every frame    
                        bool = true;
                        comesfromnothing = false;
                        comesfrom1 = true;

                    }
                    if(comesfrom2){
                        trace(songtime);
                        songtime = channel2.position;
                        channel1.stop();
                        channel2.stop();
                        channel1 = snd1.play(songtime,100);
                        songtime = channel1.position;       
                        bool = true;
                        comesfrom1 = true;
                        comesfrom2 = false;

                    }
                    if(comesfrom3){
                        trace(songtime);
                        songtime = channel3.position;
                        channel1.stop();
                        channel3.stop();
                        channel1 = snd1.play(songtime,100);
                        songtime = channel1.position;       
                        bool = true;
                        comesfrom1 = true;
                        comesfrom3 = false;
                    }
                    if(comesfrom4){
                        trace(songtime);
                        songtime = channel4.position;
                        channel1.stop();
                        channel4.stop();
                        channel1 = snd1.play(songtime,100);
                        songtime = channel1.position;       
                        bool = true;
                        comesfrom1 = true;
                        comesfrom3 = false;
                    }
                break;
            if(channel1.position  > 15100){
                trace(songtime);
                songtime = 0;
                channel1.stop();
                channel2.stop();
                channel3.stop();
                channel4.stop();
                channel5.stop();
                channel6.stop();
                NoSongHasBeenPlayedYet = true;

            }
        }
        public function MenuButtons(event: KeyboardEvent): void {
            if (Object(root).currentFrame == 2) {

            //this is the part of the controls, the bool is set to false so each time you press a botton, the audio can change.
            if (Keyboard.LEFT == event.keyCode && soulcounting != 1 && soulcounting != 4 && !Keyboardpressed) {
                soulcounting -= 1;
                bool = false;
                Keyboardpressed = true;} 
            else if (Keyboard.LEFT == event.keyCode && (soulcounting == 1 || soulcounting == 4) && !Keyboardpressed) {
                soulcounting += 2;
                bool = false;
                Keyboardpressed = true;} 
            else if (Keyboard.RIGHT == event.keyCode && soulcounting != 3 && soulcounting != 6 && !Keyboardpressed) {
                soulcounting += 1;
                bool = false;
                Keyboardpressed = true;} 
            else if (Keyboard.RIGHT == event.keyCode && (soulcounting == 3 || soulcounting == 6) && !Keyboardpressed) {
                soulcounting -= 2;
                bool = false;
                Keyboardpressed = true;} 
            else if ((Keyboard.UP == event.keyCode || Keyboard.DOWN == event.keyCode) && soulcounting > 3 && !Keyboardpressed) {
                soulcounting -= 3;
                bool = false;
                Keyboardpressed = true;} 
            else if ((Keyboard.DOWN == event.keyCode || Keyboard.UP == event.keyCode) && soulcounting < 4 && !Keyboardpressed) {
                soulcounting += 3;
                bool = false;
                Keyboardpressed = true;
                }
            }
        }
    }

Upvotes: 1

Paweł Audionysos
Paweł Audionysos

Reputation: 606

Please run your swf in debug mode and give us the line number that is causing the error. Don't know what cause the problem and not sure what you want to do but why you repeat yourself like that? It's even hard to read. Exactly the same thing you can do like that:

public class MainThing extends MovieClip {
    private var soulcounting: Number = 1;
    private var Muting: Boolean = false;
    private var snd:Sound = new Sound();

    public function MainThing() {
        snd.load(new URLRequest("SOUL1.mp3"));
        stage.addEventListener(Event.ENTER_FRAME, FrameHandler);
    }

    private function FrameHandler(event: Event): void {
        if (Object(root).currentFrame != 2) return;
        var channel:SoundChannel = snd.play(0,1);
        channel.soundTransform = new SoundTransform(1,0);
        /*the soulcounting number is determined by a keyboard function...  
        I didn't deem it necessary to be included in here,  
        as I don't think it is part of the problem.*/
        SOULS.gotoAndStop(soulcounting);
        Muting = soulcounting != 1;
        setVolume(channel, Number(!Muting));
    } 

    private function setVolume (sch:SoundChannel, volume:Number=0) {
        var trans:SoundTransform = sch.soundTransform;
        trans.volume = volume;
        sch.soundTransform = trans;
    }

}

And it would be even more efficient.

Upvotes: 2

Related Questions