Stopping an running SKAction - Sprite Kit
You just have to use either:
something.paused = false // or true
to pause actions on the nodesomething.removeAllActions()
to definitely remove actions associated to the node- name your action when launching
something.runAction(action,withKey:"action1")
and thensomething.removeActionForKey("action1")
to remove a given action
You may also change the speed if needed.
Swift 3 (SpriteKit): Stopping a forever looping SKAction has a delay
I don't have an exact explanation why drawFrame() is called multiple times at the moment (but I will try to discover that :D)... Anyways, try this code:
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
var stop = false
override func didMove(to view: SKView) {
run(SKAction.repeatForever (
SKAction.sequence ([
SKAction.run({[unowned self] in
if self.stop {
self.action(forKey: "frameDrawing")?.speed = 0.0
}else{
self.drawFrame()
}
}),
SKAction.wait(forDuration:0.03),
])), withKey: "frameDrawing"
)
}
func drawFrame() {
//(code)
print("drawFrame")
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
stop = !stop
print(stop ? "stopped": "running")
if !stop {
self.action(forKey: "frameDrawing")?.speed = 1.0
}
}
}
Use touchesBegan to toggle paused mode.
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"];
SpriteKit: How to stop actions with removeAllActions immediately
I can't reproduce what you are saying. For me, everything works fine. Take a look at this example (I didn't changed the size of a scene so it is 1024x768 which is default):
import SpriteKit
class GameScene: SKScene {
let sprite = SKSpriteNode(color: .whiteColor(), size: CGSize(width: 123, height: 123))
override func didMoveToView(view: SKView) {
sprite.alpha = 0.5
let sprite1 = SKSpriteNode(color: .redColor(), size: CGSize(width: 123, height: 123))
let scaleUp = SKAction.scaleBy(2.0, duration: 7)
sprite.runAction(scaleUp)
sprite.position = CGPoint(x: 448, y: 223)
addChild(sprite)
sprite1.position = sprite.position
addChild(sprite1)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
sprite.removeAllActions()
sprite.setScale(1.0)
}
}
Notice how white sprite is scaled to its original size when screen is tapped (at least in my case).
A fact worth of mentioning about how SKActions work is that actions are queued and always processed in the next frame. Also, you can't run an action on a node which is not added to the scene. The point is that what you have posted should work, and if it doesn't work, then something else is wrong, but not this part of the code.
Stop an action that runs forever, run another acton and resume the stopped action in SpriteKit
SKActions in Spritekit have a built in completion handler when they are run. so no need to dispatch queue.
I've broken the actions into variables for easier reading, and in my opinion jump down should be faster than jump up
to access a completion of an SKAction the put your follow up code in squiggly brackets after the run command
self.run(someAction) {
//run some code after someAction has run
}
all you need to do is
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
coco.removeAction(forKey: "cocoWalk")
let setJumpTexture = SKAction.setTexture(SKTexture(imageNamed: "coco_jump.png"))
let setWalkTexture = SKAction.setTexture(SKTexture(imageNamed: "coco_walk2.png"))
let jumpUp = SKAction.moveBy(x: 0, y: 150, duration: 0.5)
let jumpDown = SKAction.moveBy(x: 0, y: -150, duration: 0.25)
coco.run(SKAction.sequence([setJumpTexture, jumpUp, jumpDown, setWalkTexture])) {
self.coco.run(self.walkForever, withKey: "cocoWalk")
}
}
Is it possible to end an SKAction mid-action?
Look at the SKNode.h
header file - it has two functions listed:
- (void)removeActionForKey:(NSString *)key;
- (void)removeAllActions;
The latter will work: [monsterNode removeAllActions];
stopping and continuing a SKAction
You can use the speed
property to pause/resume an action:
SKAction *action = [_hero actionWithKey:@"move"];
action.speed = 0; // to pause
or
action.speed = 1; // to resume
Pause an SKAction in Spritekit with Swift
You should run an action with key:
square.runAction(SKAction.repeatActionForever(moveSequence), withKey:"moving")
Then, use action's speed property to pause it:
if let action = square.actionForKey("moving") {
action.speed = 0
}
or to unpause it:
action.speed = 1
swift: detect which skaction stopped in group
You could create another action to handle what happens after moving, then run these actions as a sequence.
let afterMoveHandler = SKAction.runBlock({
// Your code here
})
let moveSequence = SKAction.sequence([moveUp, afterMoveHandler])
let bearRun = SKAction.group([moveSequence, bearRep])
If you want an extension of SKAction to do what you are looking for, consider the following:
(Code is Swift 3)
extension SKAction
{
static func run(action:SKAction,completion:()->()) -> SKAction
{
return SKAction.sequence([action, SKAction.run(completion)]
}
}
Usage:
let moveUpEvent = SKAction.run(action:moveUp){/*do something here*/}
let bearRun = SKAction.group([moveUpEvent , bearRep])
Related Topics
How to Create a Packed Data Structure in Swift
Conflicting Definition of Swift Struct and Array
Swift .Uppercasestring or .Lowercasestring Property Replacement
Swift: Function with Default Parameter Before Non-Default Parameter
Why Does a Public Class/Struct in Swift Require an Explicit Public Initializer
Coredata Crash Error Xcode 11 Beta, iOS 13 Beta
How to Write an 'If Case' Statement as an Expression
How to Check If a String Contains Letters in Swift
Swift: Uicollectionview Selecting Cell Indexpath Issues
How to Add "%" to Data in iOS-Chart
Swift: How to Fully Strip Internal/Inline Symbols
Swiftui MACos Xcode Style Toolbar
Convert String to Cgfloat in Swift