如何停止音频 SKAction?
Posted
技术标签:
【中文标题】如何停止音频 SKAction?【英文标题】:How to stop a audio SKAction? 【发布时间】:2014-04-29 00:58:42 【问题描述】:目标:我要呈现一个新场景:
[self.scene.view presentScene:level2 transition:reveal];
并结束当前的背景音乐以开始新的背景音乐(2级的新背景音乐)。
问题:在呈现新场景时,1. 场景(level1)的背景音乐会一直播放,即使离开迷你游戏也不会停止,因为整个游戏由几个迷你游戏组成。
播放的音乐是一个 SKAction:
@implementation WBMAnimalMiniGameLvL1
-(id)initWithSize:(CGSize)size
if (self = [super initWithSize:size])
/* Setup your scene here */
self.temporaryScore = 0;
self.animalSKSprites = [[WBMAnimalsMiniGameModel alloc] init];
self.backgroundImage = [SKSpriteNode spriteNodeWithImageNamed:@"farmBackground1024x768.png"];
self.backgroundImage.position = CGPointMake(CGRectGetMidX(self.frame),
CGRectGetMidY(self.frame));
self.temporaryStartingPointIndex = -1;
[self addChild:self.backgroundImage];
self.playBackgroundSound = [SKAction playSoundFileNamed:@"farm.mp3" waitForCompletion:NO];
//SKAction *repeat = [SKAction repeatActionForever:playSound];
[self runAction:self.playBackgroundSound withKey:@"play"];
[self drawAllAnimalsOntoScreen];
return self;
到下一个级别的转换发生在这里:
-(void)transitionToNextLevel
NSLog(@"transitionToNextLevel");
SKTransition *reveal = [SKTransition moveInWithDirection:SKTransitionDirectionDown duration:0.5];
//SKView *skView = (SKView *)self.view;
SKScene *level2 = [[WBMAnimalMiniGameLvL2 alloc] initWithSize:self.size];
level2.scaleMode = SKSceneScaleModeAspectFill;
[self removeAllActions];
[self removeActionForKey:@"play"];
//self.scene.view.paused = YES;
//self.playBackgroundSound = nil;
[self.scene.view presentScene:level2 transition:reveal];
在 cmets 代码行中,您可以查看我已经尝试过的内容以及无效的内容。 :
[self removeAllActions];
[self removeActionForKey:@"play"];
什么都没做。 该:
self.scene.view.paused = YES;
线条仅停止过渡,但音乐仍在继续。
我尝试了以下方法: - 在 a 上使用了弱或强属性:
@property (nonatomic,weak) SKAction *playBackgroundSound;
保护指向 SKAction 的指针,以便我可以使用“withKey”属性访问它,因为我在“initWithSize”中初始化了 SKAction。有人写道,SKAction 是一个即发即弃的对象,我理解为没有存储指向它的指针,以后访问它是不可能的(直接)。但是,它没有工作/帮助我。
我查看了许多其他 *** 帖子,但没有一个对我有帮助,或者至少给了我一个线索,为什么会发生这种情况:
SKAction playSoundFileNamed stops background music
Stop SKAction that RepeatsForever - Sprite Kit
Is it possible to end an SKAction mid-action?
Pausing a sprite kit scene
... 想法:似乎动作是随着SKScene对象的创建而创建的。它与它“挂钩”并在音频持续时间后完成。当我使用 repeatForever 时,它永远不会停止。但是,没有办法暂停或停止它。 我还尝试将 SKAction 连接到 SKSpriteNode。当 SKScene 被加载时,动物也会被加载。所以我尝试在 SKSpriteNode 上挂接 SKAction 并使用 SKSpriteNode 中的 removeAllActions 等,但它也不起作用。
我查看了有关 SKAction、SKView、SKScene、SKSpriteNode 的文档,但最终对我没有多大帮助。
看起来该对象存在于某处运行其操作。
错误不是关于什么:
这不是模拟器或设备相关的错误 - 我已经在模拟器和设备上进行了测试,结果相同(错误)。
这不是与项目相关的错误 - 我已经在一个单独的项目中对其进行了测试,它要小得多并且结果相同(错误)。
临时解决方案: 我一直在使用 AVFoundation 框架中的 AVAudioPlayer 类。我创建了一个:
//@property (nonatomic) AVAudioPlayer *theBackgroundSong;
这并没有太大帮助,因为我想在加载 level2 时更改背景歌曲,并且我在从嵌套的 SKScene 结构访问属性时遇到了巨大的问题。
任何建议、线索、提示或想法都会有很大帮助。
【问题讨论】:
AVAudioPlayer 或像 ObjectAL 这样的“适当的”音频引擎是可行的方法。我相信 playSoundFileNamed: 动作只是为了做一些快速的音频(也许是测试)而存在,但我不会将它用于任何现实世界的应用程序。主要是因为您完全无法控制正在播放的音频,您无法音高或平移、暂停或恢复、预加载或释放它。 我同意你的看法。看来我将不得不改变我的方法。我不确定 ios sprite kit 的音频播放能力是低还是我缺乏使用它的知识。 我认为他们把这个动作放在那里是为了方便初学者/学习者。如果没有准系统“播放音频”功能,SK 似乎会丢失。 我用它来播放连接到 SKSpriteNodes 上的短暂的短声音,比如动物的声音。我的工作做得很好。但是,如果最后几秒钟就会成为问题,因为如果您更快地单击动物,那么声音会同时播放。我不能让他们排队或阻止他们。我相信苹果会慢慢解决这个问题并添加更多功能。对于初学者来说还可以。 【参考方案1】:从 SKAction 运行时,您无法停止播放音频。 您将需要另一个引擎来运行您的背景音乐。 试试 AVAudioPlayer - 它使用起来非常简单直接。这样的事情会起作用:
首先导入标头并将新属性添加到您的场景或视图控制器:
#import <AVFoundation/AVFoundation.h>
@interface AudioPlayerViewController : UIViewController
@property (strong, nonatomic) AVAudioPlayer *audioPlayer;
在 viewDidLoad 或场景的 didMoveToView 方法中添加以下代码:
- (void)viewDidLoad
[super viewDidLoad];
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/audiofile.mp3", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
self.audioPlayer.numberOfLoops = -1;
if (!self.audioPlayer)
NSLog([error localizedDescription]);
else
[self.audioPlayer play];
每次您需要停止音乐时,只需致电[self.audioPlayer stop];
当您需要播放新音乐时,将新播放器放入使用您的新音乐片段初始化的属性中。
希望这会有所帮助。
【讨论】:
"从 SKAction 运行时,您无法停止播放音频" - 你是对的。我不确定,但现在我确定了。它有帮助:)。 它对我不起作用,但看起来这是要走的路。但是,我没有发出任何声音。你知道可能是什么问题吗?错误是:操作无法完成。 (OSStatus 错误 2003334207。)【参考方案2】:现在您可以通过为其分配键字符串然后稍后使用removeActionForKey
来停止播放声音动作
对不起,这是斯威夫特。但是可以移植到 Obj-C 上。
let action: SKAction = SKAction.playSoundFileNamed("sounds/boom.wav", waitForCompletion: true)
self.runAction(action, withKey:"die-sound")
// later you do:
self.removeActionForKey("die-sound")
我测试成功了
【讨论】:
在 Swift 中,太棒了;)。请仅编辑哪个版本(1.2 或 2.0) 我在这里看到了几个类似问题的解决方案,但它对我不起作用。我可以看到该动作已成功从节点中删除,但声音会继续播放直到完成。 即使在今天,它也不能在 Objective-C 中工作。对我来说它不起作用。以上是关于如何停止音频 SKAction?的主要内容,如果未能解决你的问题,请参考以下文章
spritekit 如何在两个不同的节点上转换两个 SKAction