Reputation: 1452
I have a game I made using sprite kit and I have added a 30 second audio file to loop infinitely as background music for my game using av audio player. When the game switches from a certain state i want to stop and start the music from the my scene file.
This is my view controller.m file where I have added a stop music method
@implementation ViewController
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
NSError *error;
NSURL *backgroundMusicUrl = [[NSBundle mainBundle] URLForResource:@"game" withExtension:@"wav"];
_backgroundMusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:backgroundMusicUrl error:&error];
_backgroundMusicPlayer.numberOfLoops = -1;
[_backgroundMusicPlayer prepareToPlay];
[_backgroundMusicPlayer play];
SKView * skView = (SKView *)self.view;
// Create and configure the scene.
SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
// Present the scene.
[skView presentScene:scene];
}
-(void)stopMusic
{
[_backgroundMusicPlayer pause];
}
and then in my my scene.m file I have tried to call the stop music method however the background music does not stop playing.
-(void)switchToTutorial{
[[ViewController alloc] stopMusic];
_gameState = GameStateTutorial;
//remove unwatnted nodes
for (int i = 0; i < _mainMenu.count; i++)
{
SKSpriteNode *chosenNode = [_mainMenu objectAtIndex:i];
[chosenNode removeFromParent];
}
for (int i = 0; i < _mainMenuButtons.count; i++)
{
SKSpriteNode *chosenNode = [_mainMenuButtons objectAtIndex:i];
[chosenNode removeFromParent];
}
[self setupTutorial];
}
Upvotes: 1
Views: 526
Reputation: 2842
The problem is this line:
[[ViewController alloc] stopMusic];
You are creating a new instance of ViewController, but should send the stopMusic message to the current used one.
A way to achieve this, would be to have a property of type ViewController in your scene and set the viewController to it.
In MyScene.h
@class ViewController; //below the #import
...
@property(weak) ViewController *viewController;
In MyScene.m
#import "ViewController.h"
...
[self.viewController stopMusic]
In ViewController.m
MyScene * scene = [MyScene sceneWithSize:skView.bounds.size];
scene.viewController = self;
The problem of this approach is you will have to pass the ViewController for each scene. Maybe it would be easier to have a static AVAudioPlayer
and two static methods to start and stop the music, then you could just call
[ViewController stopMusic];
If you have arrived in that stage, you could think about creating an extra class, i.e. MusicPlayer to handle all music for you. So you would call something like
// in ViewControllers viewDidLoad
[MusicPlayer initializePlayer];
//where needed
[MusicPlayer playMusic];
[MusicPlayer stopMusic];
Upvotes: 3