Swift 精灵套件:如何根据距离改变动作持续时间?

Swift 精灵套件:如何根据距离改变动作持续时间?,swift,swift3,sprite-kit,skaction,Swift,Swift3,Sprite Kit,Skaction,好的,我有一个Cgpoints数组,当我遍历数组时,我将一个sprite节点移动到这个数组中。精灵到下一个点的距离随每个点而变化 func moveGuy() { let action = SKAction.move(to: points[i], duration: 2) action.timingMode = .easeInEaseOut guy.run(action) } //UPDATE override func update(_ currentTime:

好的,我有一个Cgpoints数组,当我遍历数组时,我将一个sprite节点移动到这个数组中。精灵到下一个点的距离随每个点而变化

func moveGuy() {
    let action = SKAction.move(to: points[i], duration: 2)
    action.timingMode = .easeInEaseOut
    guy.run(action)   
}

//UPDATE
override func update(_ currentTime: CFTimeInterval) {
    if(mouseIsDown)
    {
       moveGuy()
    }
}
我的问题是静态持续时间,这取决于精灵的位置,他以较慢/较快的速度移动。无论精灵必须走多远,我都需要有恒定的速度


如何根据精灵到终点的距离改变动作速度

这需要使用距离公式。现在,为了保持恒定的速度,您需要确定要移动的每秒点数(pps)

基本上,公式变成了距离/pps

假设我们要从(0,0)到(0300)(这是300点,所以需要2秒)

伪代码:

让持续时间=sqrt((0-0)*(0-0)+(0-300)*(0-300))/(150)
持续时间=平方米(90000)/(150)
持续时间=300/150
持续时间=2

然后将其弹出到移动操作中:

let action=SKAction.move(到:点[i],持续时间:持续时间)

您的Swift代码应如下所示:

let pps = 150 //define points per second
func moveGuy() {
    var actions = [SKAction]()
    var previousPoint = guy.position // let's make sprite the starting point
    for point in points
    {
      //calculate the duration using distance / pps
      //pow seems to be slow and some people have created ** operator in response, but will not show that here
      let duration = sqrt((point.x - previousPoint.x) * (point.x - previousPoint.x) + 
                     (point.y - previousPoint.y) * (point.y - previousPoint.y)) / pps

      //assign the action to the duration
      let action = SKAction.move(to: point, duration: duration)
      action.timingMode = .easeInEaseOut
      actions.append(action)
      previousPoint = point
    }   
    guy.run(actions)
}

//Since the entire path is done in moveGuy now, we no longer want to be doing it on update, so instead we do it during the mouse click event
//I do not know OSX, so I do not know how mouse down really works, this may need to be fixed
//Also I am not sure what is suppose to happen if you click mouse twice,
//You will have to handle this because it will run 2 actions at once if not done
override func mouseDown(event:NSEvent)
{
    moveGuy()
}
现在你会注意到你的精灵在每次迭代中都会加速和减速,你可能不想这样,所以对于你的计时模式,你可能想这样做

//Use easeInEaseOut on our first move if we are only moving to 1 point
if points.count == 1
{
    action.timingMode = .easeInEaseOut
}
//Use easeIn on our first move unless we are only moving to 1 point
else if previousPoint == sprite.position
{
    action.timingMode = .easeIn
}
//Use easeOut on our last move unless we are only moving to 1 point
else if point == point.last
{
    action.timingMode = .easeOut
}
//Do nothing
else
{
    action.timingMode = .linear
}

您必须创建一个新的SKAction,其持续时间根据要移动的距离和要移动的节点的速度(以点/秒为单位)计算

这将是大量的
SKActions
创建和销毁每个帧。我想知道你为什么不提醒skyguy这件事?他所做的不是一种有效的方法,也没有意义(即使行动的持续时间很短也没有意义)。我认为他还是一个新手,我不想对他施加太多的压力。
SKAction
followPath
将是真正的方法,如果他有兴趣了解pathsYeah,那就行了。或直接更新位置属性而不使用操作。。。我同意这对新手来说可能太多了,但我不知道,当有人在
更新:
方法中放置持续时间为2秒的
SKAction
并在下一帧中覆盖该操作时,这只会刺痛我的眼睛。没有道理。哦,我忘了在我的回答中提到,谢谢你提醒我,我删除了更新功能