How to Stop/Cancel Playsoundfilenamed in Swift

How to stop/cancel playSoundFileNamed in Swift?

New functionality has been added to Swift for SKActions:

class func stop() -> SKAction

It creates an action that tells an audio node to stop playback.
This action may only be executed on an SKAudioNode object. The audio is stopped, and if restarted, begins at the beginning. This action is not reversible.

Unfortunately, available only in iOS 9.0 and later.

How to stop a audio SKAction?

You can't stop audio from playing when run from SKAction.
You will need another engine to run your background music.

Try AVAudioPlayer - it is really easy and straightforward to use. Something like this will work:

First import header and add new property to your scene or view controller:

#import <AVFoundation/AVFoundation.h>

@interface AudioPlayerViewController : UIViewController {

@property (strong, nonatomic) AVAudioPlayer *audioPlayer;

}

After this in viewDidLoad or in didMoveToView method of scene add following code:

- (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];

}

Each time you need your music to stop, just call [self.audioPlayer stop];

When you need new music to play, put a new player into the property initialized with your new music piece.

Hope this helps.

Stopping Audio In Spritekit Swift

If you're able to target iOS 9, there's a marvellous solution for this: SKAudioNode. It lets you play music and stop it whenever you want, plus it automatically loops when it's attached to a node.

To try it out, make a property like this:

var backgroundMusic: SKAudioNode!

Then add this to didMoveToView():

backgroundMusic = SKAudioNode(fileNamed: "music.m4a")
addChild(backgroundMusic)

That's all it takes to start playing! When you want it to stop, use this:

backgroundMusic.runAction(SKAction.stop())

Stopping an SKAction

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...

Disable touches everywhere except inside of a button? - Swift

There are two solutions to your issue.

The first case I want to propose to you is based to gesture recognizer.
You can separate the button from the other touches events and switch on/off the touches event by a boolean var like this:

Gesture recognizers:

In the global var declaration section of your class:

var tapGesture :UITapGestureRecognizer!
var enableTouches:Bool = true

override func didMoveToView(view: SKView) {
super.didMoveToView(view)
self.tapGesture = UITapGestureRecognizer(target: self, action: #selector(GameClass.simpleTap(_:)))
self.tapGesture.cancelsTouchesInView = false
view.addGestureRecognizer(tapGesture)
myBtn.name = "myBtn"
}

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
return self.enableTouches
}

func simpleTap(sender: UITapGestureRecognizer) {
print("simple tap")
if sender.state == .Ended {
var touchLocation: CGPoint = sender.locationInView(sender.view)
touchLocation = self.convertPointFromView(touchLocation)
let touchedNode = self.nodeAtPoint(touchLocation)
// do your stuff
if touchedNode.name == "myBtn" {
// button pressed, do your stuff
}
}
}

override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
if died == true {
self.enableTouches = false // disable all touches but leave gestures enabled
//do whatever you want when hero is died
}
}

Only a Boolean

The second solution I want to propose is simply to stopping touches flow by using a simple boolean (it's not very elegant but it works).
This method look when button is tapped and the update method check if your hero is dead so all touches will be disabled:

In the global var declaration section of your class:

var enableTouches:Bool = true

override func didMoveToView(view: SKView) {
super.didMoveToView(view)
myBtn.name = "myBtn"
}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if (!enableTouches) {
return
}

let touch = touches.first
let positionInScene = touch!.locationInNode(self)
let touchedNode = self.nodeAtPoint(positionInScene)
// do your stuff
if touchedNode.name == "myBtn" {
// button pressed, do your stuff
if died == true {
self.enableTouches = false // disable all touches
//do whatever you want when hero is died
}
}
}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
if (!enableTouches) {
return
}

let touch = touches.first
let positionInScene = touch!.locationInNode(self)
let touchedNode = self.nodeAtPoint(positionInScene)
// do your stuff

}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
if (!enableTouches) {
return
}
}

The first case permit to you to have always the gesture enabled so you can do also other stuff with gestures when your hero will be died. The second case stop your touches when you press your button and do the "die flow". Choose which may be the most suitable for you.



Related Topics



Leave a reply



Submit