SpriteKit Swift动画一次只能在一个精灵上 - iOS

Posted

技术标签:

【中文标题】SpriteKit Swift动画一次只能在一个精灵上 - iOS【英文标题】:SpriteKit Swift animation only on one sprite at once - iOS 【发布时间】:2016-05-30 16:21:50 【问题描述】:

我尝试为每个精灵管理多个动画。我遇到的问题是,当我选择一个精灵时,它会正确设置动画,但是当我选择另一个精灵时,第一个精灵的动画停止,第二个精灵开始动画。但我希望动画在每个用手指触摸的精灵用户上继续。这里有 3 个带有 swift 代码的函数:

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


如何管理动画在每个触摸的精灵上继续,而不是在每次我触摸另一个精灵时停止?我可以通过再次选择任何精灵来再次制作动画,但一次只能选择一个,再也不会...

感谢您的帮助,

【问题讨论】:

【参考方案1】:

您的代码是正确的。如果您使用此委托方法或在UIPanGestureRecognizer 上,问题可能出在您的touchesBegan 上,可能您正在触发一些删除节点的方法(node.removeFromParent() 或类似node.removeAllActions() 的东西)。 就像您在屏幕上点击一样,由于父节点删除了节点或所有操作都立即停止了,因此 repeatForEver 立即停止。

如果你想停止一些动作,最好给 runAction 一个特定的键:

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

然后,停止它:

NPuzzle30.removeActionForKey("NPuzzle30repeatForEver")

编辑:(在您上次代码更新之后)

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

【讨论】:

感谢您的帮助。只有当我在屏幕上选择另一个精灵时,动画才会停止。但是,如果我再次选择精灵,我可以再次启动它,但我不能移动超过一个精灵......这是我的代码的更大部分: 我认为您必须在代码中搜索有关“removeAllActions()”的所有行并从中开始调试。 ;) 亚历山德罗,非常感谢!有用 !!我是 ios 上 Swift 的初学者,很高兴能得到更多实验用户的帮助。

以上是关于SpriteKit Swift动画一次只能在一个精灵上 - iOS的主要内容,如果未能解决你的问题,请参考以下文章

SpriteKit问题与Swift中的SKShader动画

SpriteKit 动画意外停止

在 swift Playground 中创建纹理动画 [关闭]

SpriteKit fps 在第一次动画调用时下降

Spritekit 动画加载时间

在更新函数中使用 spriteKit 增加 spriteNode 的大小(Swift)