类型错误 1009 和 AS3 中的静音



真的很陌生,所以,如果我以某种方式错过了一些明显的解决方案,我真的很抱歉,但是哦,好吧......我正在制作一个
游戏,我正在尝试制作一个角色选择菜单。每个角色都会有同一首歌曲的唯一版本(具有相同的 bps),因此当您"悬停在"其中一个选项上时,角色的歌曲将播放,其他歌曲将被静音(不暂停或停止,以免失去歌曲所有版本之间的同步)......
现在,我试图只为其中一首歌曲编程,然后在我想通后对其他歌曲重复该方法。
所以。。。
我做错了什么?

代码如下:

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;
}
}
}

(如果我尝试预览 swf,一切正常,直到我到达第二帧,其中输出开始重复 类型错误:错误 #1009:无法访问空对象引用的属性或方法。 在 MainThing/FrameHandler())
TypeError #1009 似乎是一个非常常见的错误,但我所读到的内容并没有真正帮助我解决这个问题......抱歉,如果这里已经有解决方案,而我只是搜索不够......
提前感谢!

请在调试模式下运行您的 swf,并向我们提供导致错误的行号。不知道是什么原因导致问题,也不确定你想做什么,但为什么要重复自己?甚至很难阅读。你可以这样做完全相同的事情:

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;
}
}

而且效率会更高。

感谢Pawel Audionysos和VC.One帮助我解决问题。 我解决了!我没有使用SoundTransform.volume函数,而是使用SoundChannel.position和一个变量来"保存"上一首歌曲停止的位置,以便下一首歌曲从该点开始: 如果有人感兴趣,这是代码:

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;
}
}
}
}