Pierro787 Pierro787 - 6 months ago 38
Swift Question

SpriteKit Swift animation only on one sprite at once - iOS

I try to manage several animations for each of my sprites. The problem I have is when I select one sprite, its get animated correctly but when I choose another sprite, the animation of the first one stops and the animation begins on the second one. But I would like the animation to continue on evry sprite user touched with the finger. Here is 3 functions with the swift code:

override func didMoveToView(view: SKView) {

let urlStr = NSBundle.mainBundle().pathForResource("Video_Socle", ofType: "mov")
let url = NSURL(fileURLWithPath: urlStr!)

player = AVPlayer(URL: url)
NSNotificationCenter.defaultCenter().addObserverForName(AVPlayerItemDidPlayToEndTimeNotification, object: player!.currentItem, queue: nil)
{ notification in
let t1 = CMTimeMake(5, 100);
self.player!.seekToTime(t1)
self.player!.play()
}


videoNode = SKVideoNode(AVPlayer: player!)
videoNode!.position = CGPointMake(frame.size.width/2, frame.size.height/2)
videoNode!.size = CGSize(width: 2048, height: 1536)
videoNode!.zPosition = 0


background.addChild(videoNode!)
videoNode!.play()



let gestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(GameScene.handlePanFrom(_:)))
self.view!.addGestureRecognizer(gestureRecognizer)
}


func handlePanFrom(recognizer : UIPanGestureRecognizer) {
if recognizer.state == .Began {
var touchLocation = recognizer.locationInView(recognizer.view)
touchLocation = self.convertPointFromView(touchLocation)

self.selectNodeForTouch(touchLocation)
} else if recognizer.state == .Changed {
var translation = recognizer.translationInView(recognizer.view!)
translation = CGPoint(x: translation.x, y: -translation.y)

self.panForTranslation(translation)

recognizer.setTranslation(CGPointZero, inView: recognizer.view)
} else if recognizer.state == .Ended {

}
}

func degToRad(degree: Double) -> CGFloat {
return CGFloat(degree / 180.0 * M_PI)
}

func selectNodeForTouch(touchLocation : CGPoint) {
// 1
let touchedNode = self.nodeAtPoint(touchLocation)

if touchedNode is SKPuzzle {
// 2
if !selectedNode.isEqual(touchedNode) {
selectedNode.removeAllActions()
selectedNode.runAction(SKAction.rotateToAngle(0.0, duration: 0.1))

selectedNode = touchedNode as! SKPuzzle

// 3
if touchedNode.name! == kpuzzleNodeName {
let sequence = SKAction.sequence([SKAction.rotateByAngle(degToRad(-4.0), duration: 0.1),
SKAction.rotateByAngle(0.0, duration: 0.1),
SKAction.rotateByAngle(degToRad(4.0), duration: 0.1)])
selectedNode.runAction(SKAction.repeatActionForever(sequence))
}
}
}
}



func panForTranslation(translation : CGPoint) {
let position = selectedNode.position

if selectedNode.name! == kpuzzleNodeName {
selectedNode.position = CGPoint(x: position.x + translation.x * 2, y: position.y + translation.y * 2)

print (selectedNode.name)
print (selectedNode.name2)
if selectedNode.name2 == "0" {

Anim_Puzzle13(selectedNode)
}

print (selectedNode.name2)
if selectedNode.name2 == "1" {
Anim_Puzzle19(selectedNode)
}

print (selectedNode.name2)
if selectedNode.name2 == "2" {
Anim_Puzzle30(selectedNode)
}

print (selectedNode.name2)
if selectedNode.name2 == "3" {
Anim_Puzzle11(selectedNode)
}

print (selectedNode.name2)
if selectedNode.name2 == "4" {
Anim_Puzzle29(selectedNode)
}

print (selectedNode.name2)
if selectedNode.name2 == "5" {
Anim_Puzzle35(selectedNode)
}

}

}




func Anim_Puzzle13 (Node13 : SKPuzzle) {

let puzzle13 = SKAction.animateWithTextures(sheet_puzzle13.Puzzle13_(), timePerFrame: 0.033)
NPuzzle13 = Node13
NPuzzle13.runAction(SKAction.repeatActionForever(puzzle13))
NPuzzle13.position = CGPoint(x: 500, y: 400)
NPuzzle13.zPosition = 1

}

func Anim_Puzzle19 (Node19 : SKPuzzle) {


let puzzle19 = SKAction.animateWithTextures(sheet_puzzle19.Puzzle19_(), timePerFrame: 0.033)
NPuzzle19 = Node19
NPuzzle19.runAction(SKAction.repeatActionForever(puzzle19))
NPuzzle19.position = CGPoint(x: 600, y: 500)
NPuzzle19.zPosition = 1

}

func Anim_Puzzle30 (Node30 : SKPuzzle) {


let puzzle30 = SKAction.animateWithTextures(sheet_puzzle30.Puzzle30_(), timePerFrame: 0.033)
NPuzzle30 = Node30
NPuzzle30.runAction(SKAction.repeatActionForever(puzzle30))
NPuzzle30.position = CGPoint(x: 700, y: 600)
NPuzzle30.zPosition = 1

}

func Anim_Puzzle11 (Node11 : SKPuzzle) {


let puzzle11 = SKAction.animateWithTextures(sheet_puzzle11.Puzzle11_(), timePerFrame: 0.033)
NPuzzle11 = Node11
NPuzzle11.runAction(SKAction.repeatActionForever(puzzle11))
NPuzzle11.position = CGPoint(x: 800, y: 700)
NPuzzle11.zPosition = 1

}

func Anim_Puzzle29 (Node29 : SKPuzzle) {


let puzzle29 = SKAction.animateWithTextures(sheet_puzzle29.Puzzle29_(), timePerFrame: 0.033)
NPuzzle29 = Node29
NPuzzle29.runAction(SKAction.repeatActionForever(puzzle29))
NPuzzle29.position = CGPoint(x: 900, y: 800)
NPuzzle29.zPosition = 1

}

func Anim_Puzzle35 (Node35 : SKPuzzle) {


let puzzle35 = SKAction.animateWithTextures(sheet_puzzle35.Puzzle35_(), timePerFrame: 0.033)
NPuzzle35 = Node35
NPuzzle35.runAction(SKAction.repeatActionForever(puzzle35))
NPuzzle35.position = CGPoint(x: 1000, y: 900)
NPuzzle35.zPosition = 1

}


}

How to manage for the animation to continue on evry sprites touched and not to stop each time I touch another sprite ? I can make animation again by selecting again any sprite, but only one at a time, never more...

Thanks for your help,

Answer

Your code is correct. The issue could be on your touchesBegan if you use this delegate method or on UIPanGestureRecognizer, probably you're trigger some method to remove your nodes (node.removeFromParent() or something like node.removeAllActions()). It's like you tap on your screen and the repeatForEver is stopped immediatly due to the node removed by the parent or all actions was stopped immediately.

If you want to stop some action it's better to give to the runAction a specific key:

NPuzzle30.runAction(SKAction.repeatActionForever(puzzle30),withKey: "NPuzzle30repeatForEver")

and then, stop it with:

NPuzzle30.removeActionForKey("NPuzzle30repeatForEver")

EDIT: (after your last code update)

if touchedNode is SKPuzzle { 
        // 2
        if !selectedNode.isEqual(touchedNode) {
            selectedNode.removeAllActions()
            ...
            // here you remove all actions about your selectedNode, also repeatActionForever..
    }
}
Comments