I have several levels all using the same sound effects. Instead of having the same code in every level, I consolidated all of the sounds into a singleton class. However, having it in a singleton no sound is played when I run the method from other classes. I have no errors or warnings.
When I have the same code in each class I have no problems playing the sound.
Question: Does SKAction playSoundFileNamed
not work when called from a singleton or is my code missing something?
My singleton header file...
-(void)soundSwordWhoosh;
My singleton methods file...
@implementation Animations{
SKAction *swordWhooshSound;
}
-(id)init {
self = [super init];
if (self)
{
swordWhooshSound = [SKAction playSoundFileNamed:@"SwordWhoosh.mp3" waitForCompletion:YES];
}
return self;
}
-(void)soundSwordWhoosh {
[self runAction:swordWhooshSound];
}
I then call the method like this:
[_animations soundSwordWhoosh];
Your singleton is probably not in the node hierarchy (ie not a child or grandchild etc of the scene). Hence you can't run any actions on self
as the singleton instance will not receive regular updates from Sprite Kit.
It is also not necessary to use a singleton here because you can do the same thing easier using class methods. You just need to pass in the node that the sound should be played for.
Here's an example helper class:
@interface SoundHelper
+(void) playSwordSoundWithNode:(SKNode*)node;
@end
@implementation SoundHelper
+(void) playSwordSoundWithNode:(SKNode*)node
{
[node runAction:[SKAction playSoundFileNamed:@"SwordWhoosh.mp3" waitForCompletion:YES]];
}
@end
If you are worried about "caching" the action it's not worth doing it. You'll do plenty of other things that affect performance far more. Besides Sprite Kit internally creates a copy of every action, whether you create a new one or Sprite Kit copies it shouldn't change much. Still you could cache it in static
variables if you wanted to.
You can call the helper methods like so from any node and any method (don't forget to #import "SoundHelper.h"
):
-(void) someNodeMethod
{
[SoundHelper playSwordSoundWithNode:self];
}
PS: you should not use .mp3 files for sound effects, as it is highly inefficient. The iOS hardware can only decode one mp3 at a time in hardware, the rest is done by the CPU. Better suited formats for short sound effects are .caf and .wav.