我正在使用SpriteKit构建我的第一个项目,但我无法弄清楚这一部分。
我的项目包括飞入屏幕的敌方直升机。每个敌人在14秒左右播放声音文件。这不是一个循环。它包括敌人在进入屏幕前接近的声音,以及在屏幕上移动时更多的声音fx。问题在于,当我杀死其中一架直升机时,即使在敌方直升机节点从场景中移除后,声音也会继续播放。
我尝试使用playSoundFileNamed动作,但我知道那些动作无法停止。
我尝试使用SoundManager,但由于所有敌人都拥有相同的文件ID,如果我停止一个,它会停止所有这些,甚至是屏幕上的那些。
我读过我应该使用OpenAL但我找不到一个解释如何为每个声音添加某种ID来知道要停止哪一个的来源。
与AVAudioPlayer相同。我尝试为每个敌人创建一个玩家但由于某种原因,runBlock SKAction只是忽略了这个代码并且从不播放声音。奇怪的。我也读过AVAudioPlayer比播放声音FX更适合播放背景音乐。
是否有某种声音引擎有助于解决这个问题?
答案 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添加到您的直升机,播放您孩子的声音,然后暂停孩子