(Swift Spritekit) Rotate Sprite in the Direction of Touch

Rotate a sprite to sprite position not exact in SpriteKit with Swift

According to the SpriteKit Best Practices doc

Use game logic and art assets that match SpriteKit’s coordinate and rotation conventions. This means orienting artwork to the right. If you orient the artwork in some other direction, you need to convert angles between the conventions used by the art and the conventions used by SpriteKit.

Since the default spaceship points upward (when zRotation is 0), you will need to offset your angle by 90 degrees (pi/2 radians) so that the ship faces to the right when zRotation is zero:

player?.zRotation = angle - CGFloat(M_PI_2)

Alternatively, you can rotate the spaceship to the right. To rotate the image, click on Assets.xcassets and then click on Spaceship. Right click on the Spaceship image and select the Open in External Editor menu item. This will open the image in the Preview app. In Preview, select Tools > Rotate Right and quit Preview. By rotating the artwork, your code should work without any changes.

(Xcode Swift SpriteKit) How do I move a sprite in the direction it is facing

You will need to use sin and cos. An SKAction may not be the best thing for you, so I would just do this in the update method for now till you find a better spot:

sprite.position = CGPoint(x:sprite.position.x + cos(sprite.zRotation) * 10,y:sprite.position.y + sin(sprite.zRotation) * 10)

Where 10 is the magnitude that you want the sprite to move (aka move 10 pixels)

This assumes that angle 0 means the sprite is looking right, angle 90 (PI/2) is looking up, angle 180 (PI) is looking left, and angle 270 (3PI/2) is looking down.

How do I rotate a SpriteNode with a one finger “touch and drag”

The Math was wrong. Here's what I learned you need:
Mathematical formula for getting angles

How this looks in swift:

if point.x.sign == .minus {
angle = atan(point.y/point.x) + CGFloat.pi/2
} else {
angle = atan(point.y/point.x) + CGFloat.pi/2 + CGFloat.pi
}

Also, you have to get the coordinates of another object in the scene because the entire coordinate system rotates with the object:

let body = parent?.childNode(withName: "objectInScene")
let point = touch.location(in: body!)

How to rotate a Sprite 90 degrees in SpriteKit

Based on the fact that your code works for me I would say that this is probably happening because the current value of car.zRotation is not 0.0 but rather something like -M_PI_2. So when you set it to M_PI_2 you get a rotation of 180 degrees. Try to print car.zRotation before you set a new value .

How to rotate sprite in sprite kit with swift

OK, take three. I'm not 100% sure about the specifics of when the rotation should end etc. but all the pieces should be in place with the below code. It will:

  • start rotation clockwise or counterclockwise based on the position of the first touch
  • stop the rotation if the user touches for the same direction again
  • switch the rotation if the user touches on the other half of the screen

      import SpriteKit  

    enum rotationDirection{
    case clockwise
    case counterClockwise
    case none
    }

    class GameScene: SKScene {
    var currentRotationDirection = rotationDirection.none
    let sprite = SKSpriteNode(color: UIColor.yellowColor(), size: CGSizeMake(100, 100))

    override func didMoveToView(view: SKView) {
    sprite.physicsBody = SKPhysicsBody(rectangleOfSize: sprite.size)
    sprite.physicsBody.affectedByGravity = false
    sprite.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
    self.addChild(sprite)
    }

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    let touch : UITouch = touches.anyObject() as UITouch
    let touchPosition = touch.locationInNode(self)
    let newRotationDirection : rotationDirection = touchPosition.x < CGRectGetMidX(self.frame) ? .clockwise : .counterClockwise

    if currentRotationDirection != newRotationDirection && currentRotationDirection != .none{
    reverseRotation()
    currentRotationDirection = newRotationDirection
    } else if currentRotationDirection == newRotationDirection{
    stopRotation()
    currentRotationDirection = .none
    } else if (currentRotationDirection == .none){
    setupRotationWith(direction: newRotationDirection)
    currentRotationDirection = newRotationDirection
    }
    }

    func reverseRotation(){
    let oldRotateAction = sprite.actionForKey("rotate")
    let newRotateAction = SKAction.reversedAction(oldRotateAction)
    sprite.runAction(newRotateAction(), withKey: "rotate")
    }

    func stopRotation(){
    sprite.removeActionForKey("rotate")
    }

    func setupRotationWith(#direction: rotationDirection){
    let angle : Float = (direction == .clockwise) ? Float(M_PI) : -Float(M_PI)
    let rotate = SKAction.rotateByAngle(angle, duration: 1)
    let repeatAction = SKAction.repeatActionForever(rotate)
    sprite.runAction(repeatAction, withKey: "rotate")
    }
    }

Edit: Changed example to cater the specific needs in the question. Something odd with the code formatting not quite sure what's going on there.



Related Topics



Leave a reply



Submit