Stop Skaction That Repeatsforever - Sprite Kit

Stop SKAction that RepeatsForever - Sprite Kit

The method is supposed to be called on the node which the SKAction is running on.

Change

[self removeActionForKey:@"animation1"]; 

to

[sprite removeActionForKey:@"animation1"]; 

swift spritekit : How to stop a runBlock?

So you are naming an object "noObject" and an action "stop"? :)

Anyway, you should use a group and a few sequence actions.

The idea

This code

self.runAction(SKAction.waitForDuration(5), completion: {
print("slide02")
})

can also be written this way

let action1 = SKAction.sequence([SKAction.waitForDuration(5), SKAction.runBlock { print("slide02") }])

Solution

Given a sprite

let sprite = SKSpriteNode()

and 4 actions

let action0 = SKAction.runBlock { print("slide01") }
let action1 = SKAction.sequence([SKAction.waitForDuration(5), SKAction.runBlock { print("slide02") }])
let action2 = SKAction.sequence([SKAction.waitForDuration(8), SKAction.runBlock { print("slide03") }])
let action3 = SKAction.sequence([SKAction.waitForDuration(6), SKAction.runBlock { print("slide06") }])

we can group the actions like this

let group = SKAction.group([action0, action1, action2, action3])

Now we can run the action with a key

sprite.runAction(group, withKey: "group")

and stop it

sprite.removeActionForKey("group")

How to stop SKAction called on DidMove when a variable changes

You can use a property observer for this kind of tasks:

var i = 50{
didSet{
if i < 18{
spriteNode.removeAction(forKey: "key")
}
}
}

This means that everytime i is set to another value, the didSet block is called.

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.

Remove SKAction and restore node state

Thanks to the helpful comment and answer I came to my own solution. I think the state machine would be bit too heavy here. Instead I created a wrapper node, which main purpose is run the animation. It also has a state: isAimating property. But, first of all, it allows to keep startAnimating() and stopAnimating() methods close to each other, incapsulated, so it's more difficult to mess up.

class ShowMoveAnimNode: SKNode {
let animKey = "showMove"

var isAnimating: Bool = false {
didSet {
guard oldValue != isAnimating else { return }
if isAnimating {
startAnimating()
} else {
stopAnimating()
}
}
}

private func startAnimating() {
let shortPeriod = 0.2
let scaleDown = SKAction.scale(by: 0.75, duration: shortPeriod)
let seq = SKAction.sequence([scaleDown,
scaleDown.reversed(),
scaleDown,
scaleDown.reversed(),
SKAction.wait(forDuration: shortPeriod * 6)])
let repeated = SKAction.repeatForever(seq)
run(repeated, withKey: animKey)
}

private func stopAnimating() {
removeAction(forKey: animKey)
xScale = 1
yScale = 1
}
}

Usage: just add everything that should be animated to this node. Works well with simple animations, like: fade, scale and move.

How can I slow down a SKSpriteNode that is running SKAction followPath for a slow motion effect using Sprite Kit?

Each node has a speed property:

A speed modifier applied to all actions executed by a node and its
descendants.

Discussion

The default value is 1.0, which means that all actions run
at their normal speed. If you set a different speed, time appears to
run faster or slower for all actions executed on the node and its
descendants. For example, if you set a speed value of 2.0, actions run
twice as fast.

You could set this to a value smaller than 1 to make the action run slower. You can even animate the speed to gradually slow down:

[mySprite runAction:[SKAction speedTo:0.5 duration:1.0]];

SKAction go to and stop at a specific frame

There is no action to play from frame x to y. But it's easy to replicate because the animate actions..

+ (SKAction *)animateWithTextures:(NSArray *)textures 
timePerFrame:(NSTimeInterval)sec

.. take an array of textures as input. You either create the array just with the specific frame textures you want to play, or if you already have an array allFrames with all textures you can get a new array with the desired frames like so if you wanted to play from frame 15 to end:

NSRange range = NSMakeRange(15, allFrames.count - 15);
NSArray* animFrames = [allFrames subarrayWithRange:range];
SKAction anim = [SKAction animateWithTextures:animFrames timePerFrame:0.1];

Stop SKAction after a certain amount of time

You are removing the wrong action. The action with key "enemy1" is:

SKAction.sequence([delay, actionMove, actionRemove])

which simply animates the enemy. Removing this only stops this sequence of actions temporarily. When addEnemy1 is called again, the sequence of action is added again.

The action that spawns the enemy is the action that you run on self here:

    run(SKAction.repeatForever(
SKAction.sequence([SKAction.run() { [weak self] in
self?.addEnemy1()
},
SKAction.wait(forDuration: 5.0)])))

Yo should give a key to that action instead:

...
},
SKAction.wait(forDuration: 5.0)])), withKey: "spawnEnemy")

and then remove that from self:

removeAction(forKey: "spawnEnemy")


Related Topics



Leave a reply



Submit