Asphys
Asphys

Reputation: 185

Rotating a sprite towards a point and move it towards it with a duration

So if i have something like:

class game: SKScene {
    let sprite = SKSpriteNode(imageNamed: "sprite")
}

How do I make a point/sprite/shape that it will first rotate towards and then move towards it (not TO it) with a duration of 1 second.

Upvotes: 0

Views: 1195

Answers (1)

Luca Angeletti
Luca Angeletti

Reputation: 59496

Look at the following code

Let's define your sprite and destination point

let sprite = SKSpriteNode(imageNamed: "mario.png")
let destPoint = CGPoint(x: 10, y: 10)

Now let's define 2 vectors. The first one (v1) is a vertical vector. The second one (v2) represents the delta space from your sprite and your destination point

let v1 = CGVector(dx:0, dy:1)
let v2 = CGVector(dx:destPoint.x - sprite.position.x, dy: destPoint.y - sprite.position.y)

Now I calculate the angle between these 2 vectors

let angle = atan2(v2.dy, v2.dx) - atan2(v1.dy, v1.dx)

and assign it to the sprite

sprite.zRotation = angle

Extension

I encapsulated the code inside an extension

extension SKNode {
    func rotateVersus(destPoint: CGPoint) {
        let v1 = CGVector(dx:0, dy:1)
        let v2 = CGVector(dx:destPoint.x - position.x, dy: destPoint.y - position.y)
        let angle = atan2(v2.dy, v2.dx) - atan2(v1.dy, v1.dx)
        zRotation = angle
    }
}

So now you can do

let sprite = SKSpriteNode(imageNamed: "mario.png")
sprite.rotateVersus(CGPoint(x: 10, y: 10))

enter image description here

Rotation + Move Extension

For the rotation animation followed by the move animation you can use this extension

extension SKNode {
    func rotateVersus(destPoint: CGPoint, durationRotation: NSTimeInterval, durationMove: NSTimeInterval) {
        let v1 = CGVector(dx:0, dy:1)
        let v2 = CGVector(dx:destPoint.x - position.x, dy: destPoint.y - position.y)
        let angle = atan2(v2.dy, v2.dx) - atan2(v1.dy, v1.dx)

        let rotate = SKAction.rotateToAngle(angle, duration: durationRotation)
        let move = SKAction.moveBy(CGVector(dx: v2.dx * 0.9, dy: v2.dy * 0.9), duration: durationMove)
        let sequence = SKAction.sequence([rotate, move])
        self.runAction(sequence)
    }
}

Thanks to Wikipedia for the image.

Upvotes: 7

Related Questions