精灵套件:如何根据距离改变滑行持续时间?
sprite kit: how to vary skaction duration based on distance?
好的,所以我有一个 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()
}
}
我的问题是静态持续时间,这取决于精灵以 slower/faster 速度移动的位置。无论精灵必须移动多远,我都需要保持恒定的速度。
如何根据精灵与终点的距离改变 SKAction 速度?
这需要使用距离公式。现在要保持恒定速度,您需要确定要移动的每秒点数 (pps)。
基本上公式就变成了distance/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()
}
现在你会注意到你的 sprite 运行 在每次迭代时都会上升和减速,你可能不希望这样,所以对于你的计时模式,你可能想要这样做
//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,其持续时间根据要移动的距离和要移动的节点的速度(在 points/s 中)计算得出。
好的,所以我有一个 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()
}
}
我的问题是静态持续时间,这取决于精灵以 slower/faster 速度移动的位置。无论精灵必须移动多远,我都需要保持恒定的速度。
如何根据精灵与终点的距离改变 SKAction 速度?
这需要使用距离公式。现在要保持恒定速度,您需要确定要移动的每秒点数 (pps)。
基本上公式就变成了distance/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()
}
现在你会注意到你的 sprite 运行 在每次迭代时都会上升和减速,你可能不希望这样,所以对于你的计时模式,你可能想要这样做
//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,其持续时间根据要移动的距离和要移动的节点的速度(在 points/s 中)计算得出。