SKAction的持续时间不同 - 在行动完成后跳过?

时间:2016-12-25 03:07:38

标签: swift

我在GameViewController中的乒乓球游戏中有以下代码:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        let location = touch.location(in: self)

        main.run(SKAction.moveTo(x: location.x,duration: 4), completion: {
           print( "COMPLETED TOUCH BEGAN")
        })
    }
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        let location = touch.location(in: self)

        main.run(SKAction.moveTo(x: location.x,duration: 1), completion: {
            print( "COMPLETED TOUCH MOVED")
        })
    }
}

出于某种原因,当touchesBegan的持续时间大于touchesMoved的持续时间时,我的播放器将首先完成touchesMoved操作(即使touchesBegan必须先来),然后跳到另一个x位置然后移动持续时间4以完成touchesBegan。这几乎就像玩家到达touchesMoved中指定的位置(它应该与touchesBegan中的位置几乎完全相同),回到有点任意的数量,然后移动到touchesBegan位置。有没有理由为什么它会跳回来然后这样移动呢?

我的假设是,出于某种原因,touchesMoved动作同时进行,当它们完成时,位置会跳回到touchesBegan中缓慢移动的位置并完成该动作 - 几乎就像有两个物体以不同的速度移动,较慢的物体在较快的物体完成后出现。这一切都正确吗?如果是这样,为什么会这样?

修改

我看到当我将拨片移动到屏幕的一侧时,然后点击屏幕的另一端并滑过,它将移动到我释放的最终位置,然后跳转并移动到我第一次按下的地方。这几乎就像第一个动作是在后台播放。奇怪的是,如果我按住手指(保持调用的touchesMoved方法)直到touchesBegan中的移动完成(所以这里是4秒),它不会跳到另一侧屏幕!

总之,我有多个SKActions以不同的持续时间运行,根据我的观察,优先级超过了添加到action数组的最新操作。但是,对象不是在彼此之间进行多个动作,而是跳转到屏幕上的不同位置以完成最终动作。

1 个答案:

答案 0 :(得分:0)

如果设置第二个SKAction移动相同的节点,则第二个节点不会取消第一个节点。相反,基于所有SKAction运行的每帧,计算节点的位置。如果SKAction具有相同的持续时间并且同时运行,则最后运行的SKAction将总是胜出。例如:

// Same duration, node finishes at 100
main.run(SKAction.moveTo(x: -100, duration: 2)) //first to run
main.run(SKAction.moveTo(x: 100, duration: 2))  //second to run

如果第一个SKAction的持续时间较长,则在第二个SKAction完成后,该位置将仅根据第一个SKAction进行计算,例如:

//First SKAction's duration is longer, node finishes at -100
main.run(SKAction.moveTo(x: -100, duration: 3))
main.run(SKAction.moveTo(x: 100, duration: 2))

这就是你看到'跳'的原因。

SKAction documentation

  

节点可以同时运行多个操作,即使这些操作也是如此   在不同的时间执行。场景记录了多远   每个动作都来自完成并计算动作的效果   在节点上。例如,如果您运行两个移动的动作   同一节点,两个操作都会对每个帧应用更改。如果搬家   行动是在相同和相反的方向,节点将保持不变   静止的。

在您的代码touchesMoved中可以多次调用,并且每次向节点添加另一个SKAction时。我建议您在运行另一个SKAction之前删除主节点上的所有操作:

main.removeAllActions()

所以最终会是:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        let location = touch.location(in: self)
        main.removeAllActions()
        main.run(SKAction.moveTo(x: location.x,duration: 4), completion: {
            print( "COMPLETED TOUCH BEGAN")
        })
    }
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        let location = touch.location(in: self)
        main.removeAllActions()
        main.run(SKAction.moveTo(x: location.x,duration: 1), completion: {
            print( "COMPLETED TOUCH MOVED")
        })
    }
}