Question

I have a sprite kit game with different scenes: the main menu ("MainMenuScene") and the game scene ("MyScene"). While the user is playing the game, I have an endless playing background music. But when the player wants to stop the game and return to main menu, the background music keeps playing. What should I do to make it stop? I have tried [self removeAllActions] but it didn't work.

MyScene:

    @implementation MyScene
{
    SKAction *_backgroundMusic;
}

-(id)initWithSize:(CGSize)size {
    if (self = [super initWithSize:size]) {

        self.backgroundColor = [SKColor colorWithRed:0.15 green:0.5 blue:0.3 alpha:1.0];
    }
    //Here I make the endless background music 
_backgroundMusic = [SKAction playSoundFileNamed:@"Background 2.m4a" waitForCompletion:YES];
    SKAction * backgroundMusicRepeat = [SKAction repeatActionForever:_backgroundMusic];
    [self runAction:backgroundMusicRepeat];
    return self;
}

- (void)selectNodeForTouch:(CGPoint)touchLocation
{
    SKSpriteNode *touchedNode = (SKSpriteNode *)[self nodeAtPoint:touchLocation];
    if ([_MainMenuButton isEqual:touchedNode]) {
        SKScene *mainMenuScene = [[MainMenuScene alloc]initWithSize:self.size];
        [self.view presentScene:mainMenuScene];
//Here is where the music should stop, when the player presses the 'return to main menu' button
    } 
}
Was it helpful?

Solution

I would not recommend using SKAction to play background music. Instead use AVAudioPlayer.

To use the AVAudioPlayer:

  1. Add the AVFoundation to your project.

  2. #import <AVFoundation/AVFoundation.h> into your .m file.

  3. Add AVAudioPlayer *_backgroundMusicPlayer; in @implementation

Use this code snippet to run your audio:

- (void)playBackgroundMusic:(NSString *)filename
{
    NSError *error;
    NSURL *backgroundMusicURL = [[NSBundle mainBundle] URLForResource:filename withExtension:nil];
    _backgroundMusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:backgroundMusicURL error:&error];
    _backgroundMusicPlayer.numberOfLoops = -1;
    _backgroundMusicPlayer.volume = 0.8;
    _backgroundMusicPlayer.delegate = self;
    [_backgroundMusicPlayer prepareToPlay];
    [_backgroundMusicPlayer play];
}

Also read up on the AVAudioPlayer Class Reference so you know what all the properties do such as setting volume, number of loops, etc...

OTHER TIPS

try this to play the music:

  [self runAction:backgroundMusicRepeat withKey:@"bgmusic"];

and this to stop:

  [self removeActionForKey:@"bgmusic"];

update

SKAction * backgroundMusicRepeat = [SKAction playSoundFileNamed:@"Background 2.m4a" waitForCompletion:YES];
backgroundMusicRepeat = [SKAction repeatActionForever:backgroundMusicRepeat];

 [self runAction:backgroundMusicRepeat];

I have run those code in my own project and seems work. but not your way, it only stop when I quit the view, I don't even need removeActionForKey . [self removeActionForKey:@"bgmusic"]; won't work in the scene.

So if you want stop sound while switch between diferent scenes of same view, I suggest you using AVAudioPlayer.

I also found some other questions in stackoverflow has the same problem as you, like this: how to pause the sound when use SpriteKit and this: Spritekit stopping sound they both go for the AVAudioPlayer.

as one of the comment in those links said: you should use the playSoundFileNamed method for playing sound effects... something short 1 or 2 seconds, like explosion sound --don't use it for background sound.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top