SpriteKit - 如何在敌人被杀时停止声音

时间:2014-04-18 01:29:27

标签: audio sprite-kit

我正在使用SpriteKit构建我的第一个项目,但我无法弄清楚这一部分。

我的项目包括飞入屏幕的敌方直升机。每个敌人在14秒左右播放声音文件。这不是一个循环。它包括敌人在进入屏幕前接近的声音,以及在屏幕上移动时更多的声音fx。问题在于,当我杀死其中一架直升机时,即使在敌方直升机节点从场景中移除后,声音也会继续播放。

我尝试使用playSoundFileNamed动作,但我知道那些动作无法停止。

我尝试使用SoundManager,但由于所有敌人都拥有相同的文件ID,如果我停止一个,它会停止所有这些,甚至是屏幕上的那些。

我读过我应该使用OpenAL但我找不到一个解释如何为每个声音添加某种ID来知道要停止哪一个的来源。

与AVAudioPlayer相同。我尝试为每个敌人创建一个玩家但由于某种原因,runBlock SKAction只是忽略了这个代码并且从不播放声音。奇怪的。我也读过AVAudioPlayer比播放声音FX更适合播放背景音乐。

是否有某种声音引擎有助于解决这个问题?

2 个答案:

答案 0 :(得分:0)

我能够解决它将所有音频播放器保持在一个阵列中。这是代码:

首先创建一个NSMutableArray来跟踪所有玩家(称为'playerArray')。然后每个SKSpriteNode在它们被添加到场景时获得它自己的播放器:

NSError *error;
NSURL * backgroundSound = [[NSBundle mainBundle] URLForResource:@"coptersound" withExtension:@"mp3"];
AVAudioPlayer *copterPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:backgroundSound error:&error];
copterPlayer.numberOfLoops = 1;
copterPlayer.delegate = self;
[copterPlayer prepareToPlay];

SKAction *moveCopter = [SKAction moveToX:(-10 - enemy.size.width) duration:14];
SKAction *copterSound = [SKAction runBlock:^{

    [playerArray addObject:copterPlayer];
    [copterPlayer play];

    [enemy.userData setValue:copterPlayer forKeyPath:@"player"];

}];

SKAction *moveGroup = [SKAction group:@[copterSound, moveCopter]];

然后,当检测到碰撞时,这就是我停止玩家的方式:

   [[enemy.userData objectForKey:@"player"] stop];
   [playerArray removeObject:[enemy.userData objectForKey:@"player"]];

需要暂停所有玩家吗?这样做:

    for(AVAudioPlayer *a in playerArray) {
        [a pause];
    }

不要忘记使用以下方法删除所有已完成播放的玩家:

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
    [playerArray removeObject:player];
}

不确定这是否是最好的方式,但它完美无缺。仍然可以提供更好的建议,因为这是我第一次使用SpriteKit。

答案 1 :(得分:0)

playSoundWithFile可以停止,将儿童SKNode添加到您的直升机,播放您孩子的声音,然后暂停孩子