2013-09-30 4 views
8

Играя с SKSprites в IOS SpriteKit, и я в основном хочу, чтобы спрайт случайным образом перемещал определенное направление на определенное расстояние, а затем выбирал новое случайное направление и расстояние. Простой достаточно, создайте метод, который генерирует случайные числа, затем создает анимацию, а в блоке завершения анимации он обращается к той же самой процедуре.Как вы перемещаете IOS SKSprite с постоянной скоростью

Это действительно работает, но также позволяет анимации двигаться с одинаковой скоростью, поскольку анимации основаны на длительности. Если объект должен перемещать 100, он перемещается на 1/2 скорости, которую он перемещает, если следующий случайный говорит ему, чтобы он переместил 200 ... Так как, черт возьми, я двигаюсь с постоянной скоростью?

+1

Вы должны размещать код, который вы используете, чтобы определить (и анимировать в) новое положение. Основной ответ на ваш вопрос заключается в том, что продолжительность анимации должна быть фиксированной кратной расстоянию между текущим и следующим местоположением, но было бы легче объяснить это с изменением вашего текущего кода. –

+0

Я сделал это, и пока он работает, он просто кажется kludgy, я бы подумал, что может быть что-то похожее на переход к xy со скоростью вместо того, чтобы все было основано на длительности. – user282172

+0

Этот тип модели, где вы вычисляете длительность на пиксель, перемещаете, а затем умножая его на сколько вам нужно переместить, нужно делать такие вещи, как принимать во внимание, если вы перемещаете x и y одновременно, поскольку 1 пиксельная диагональ на самом деле на большее расстояние, чем 1 пиксель влево и вправо, (квадратный корень из 2 против 1), предполагая, что пиксели сами по себе являются квадратными. – user282172

ответ

13

@Noah Уизерспун правильно выше - использовать Пифагор, чтобы получить плавную скорость:

//the node you want to move 
SKNode *node = [self childNodeWithName:@"spaceShipNode"]; 

//get the distance between the destination position and the node's position 
double distance = sqrt(pow((destination.x - node.position.x), 2.0) + pow((destination.y - node.position.y), 2.0)); 

//calculate your new duration based on the distance 
float moveDuration = 0.001*distance; 

//move the node 
SKAction *move = [SKAction moveTo:CGPointMake(destination.x,destination.y) duration: moveDuration]; 
[node runAction: move]; 
3

В качестве расширения для @AndyOS «ы ответа, если вы собираетесь двигаться только вдоль one axis (X например), вы можете упростить математику, делая это вместо того, чтобы:

CGFloat distance = fabs(destination.x - node.position.x); 
4

Использование Swift 2.x Я решил с этим маленьким способом:

func getDuration(pointA:CGPoint,pointB:CGPoint,speed:CGFloat)->NSTimeInterval { 
    let xDist = (pointB.x - pointA.x) 
    let yDist = (pointB.y - pointA.y) 
    let distance = sqrt((xDist * xDist) + (yDist * yDist)); 
    let duration : NSTimeInterval = NSTimeInterval(distance/speed) 
    return duration 
} 

С помощью этого метода я могу использовать в Ивар myShipSpeed ​​и непосредственно вызывать свои действия, например:

let move = SKAction.moveTo(dest, duration: getDuration(self.myShip.position,pointB: dest,speed: myShipSpeed)) 
self.myShip.runAction(move,completion: { 
    // move action is ended 
})