ymulki
ymulki

Reputation: 432

Swift: Calculate how much to rotate an SKSpriteNode to have it pointing at a CGPoint

I'm making a SpriteKit game in Playgrounds based on shooting space rocks. In the game, there is a gun, which is a SKSpriteNode and I want it to turn to the point that I pass into a function (CGPoint). What I would like to know is how would I calculate how much to turn the gun to face the given point? Thanks in advance!

Upvotes: 1

Views: 317

Answers (3)

Stoyan
Stoyan

Reputation: 330

Long ago, after a lot of mind tweaking math and a sleepless night, I came up with this function:

func gunAngle(gunPosition: CGPoint, targetPosition: CGPoint) -> CGFloat {
    let deltaX = Float(targetPosition.x - gunPosition.x)
    let deltaY = Float(targetPosition.y - gunPosition.y)
    let pi = CGFloat(M_PI)
    let angle = CGFloat(atan2f(deltaY, deltaX))
    var newAngle = angle

    if angle < (-pi / 2) {
        newAngle += 2 * pi
    }
return newAngle - pi/2  // Subtracting 90 degrees out of the resulting angle, as in SpriteKit 0 degrees faces left, unless you rotate your gun in the sprite accordingly
}

I realize this may not be the best method but it works for me. Some math gurus could probably come up with something really brilliant here. I'm not yet any of those.

Thanks to Ray Wenderlich, on his website there is a tutorial on that topic that helped me a lot in putting the foundation of that math.

Upvotes: 1

Steve Ives
Steve Ives

Reputation: 8134

An alternative solution (this may not be applicable to you), is to create an SKNode (called target perhaps) and then to set up an SKContraint so that your gun always faces the target. You can then move target when required to wherever you want the gun to face and the gun will turn accordingly.

let gun = SKNSpritenode...
let target = SKNode...

let orientRange = SKRange(lowerLimit: 0.0, upperLimit: 0.0)
let orientConstraint = SKConstraint.orientToNode(target, offset: orientRange)
gun.constraints = [orientConstraint]

Upvotes: 1

Bob song
Bob song

Reputation: 11

Maybe,something like

func aim(node:SKSpriteNode, point:CGPoint){

    let angle = atan2(point.y - node.position.y, point.x - node.position.x)

    node.run(SKAction.rotate(byAngle: angle, duration: 0.5))

}

Upvotes: 1

Related Questions