sprite kit:如何根据距离改变 skaction 持续时间?
Posted
技术标签:
【中文标题】sprite kit:如何根据距离改变 skaction 持续时间?【英文标题】:sprite kit: how to vary skaction duration based on distance? 【发布时间】:2017-03-21 12:52:56 【问题描述】:好的,所以我有一个 Cgpoints 数组,我在遍历数组时将一个精灵节点移动到该数组。精灵与下一个点的距离因每个点而异
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()
我的问题是静态持续时间,这取决于精灵的位置,他以较慢/较快的速度移动。无论精灵必须走多远,我都需要保持恒定的速度。
如何根据精灵与终点的距离来改变 SKAction 的速度?
【问题讨论】:
【参考方案1】:这需要使用距离公式。现在要保持恒定速度,您需要确定要移动的每秒点数 (pps)。
基本上公式变成了距离/pps
假设我们想要从 (0,0) 到 (0,300)(这是 300 点,所以我们需要 2 秒)
伪代码:
让时长 = sqrt((0 - 0) * (0 - 0) + (0 - 300) * (0 - 300)) / (150) 持续时间 = sqrt(90000) / (150) 持续时间 = 300 / 150 持续时间 = 2
然后您将其弹出到您的移动操作中:
let action = SKAction.move(to: points[i], duration: duration)
您的 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
【讨论】:
每一帧都会有很多SKActions
创建和销毁。我想知道你为什么没有警告skyguy?他正在做的事情不是去 IMO 的有效方式,也没有任何意义(即使行动的持续时间很短)。
我认为他还是个新手,我不想在他身上扔太多
SKAction
followPath
将是他有兴趣了解路径的真正方法
是的,那行得通。或者直接更新位置属性而不使用操作...我同意这对于新手来说可能太多了,但我不知道,当有人将持续时间为 2 秒的SKAction
放入update:
时,它只是戳我的眼睛方法并在下一帧中覆盖该操作。没有意义。
哦,我忘了在我的回答中提到,谢谢提醒,我删除了更新功能【参考方案2】:
您必须创建一个新的 SKAction,其持续时间根据要移动的距离和要移动的节点的速度(以点/秒为单位)计算得出。
【讨论】:
以上是关于sprite kit:如何根据距离改变 skaction 持续时间?的主要内容,如果未能解决你的问题,请参考以下文章
如何根据平移手势速度向 Sprite Kit 节点应用角脉冲
如何通过 Sprite Kit 中的 CGPoints 数组制作动画 - Swift