Rotate a Sprite to Sprite Position Not Exact in Spritekit with Swift

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.

SpriteKit - Rotate sprite towards point

Your problem lies here:

SKNode *center = [[SKNode alloc] init];
center.position = CGPointMake(self.size.width/2, self.size.height/2);
[self rotateNode:self toFaceNode:center];

The center node's position is based on the size of the enemy sprite.

You need to move this part to the scene class. Call the method at the point you initialise the enemy node in the scene. I am assuming the name of the enemy class as EnemySprite and that of the space station node as spaceStation.

EnemySprite *enemy = [[EnemySprite alloc] initWithLevel:1 andSize:CGSizeMake(100, 100)]; //Assuming values as well
[self addChild:enemy];
[self rotateNode:enemy toFaceNode:spaceStation];

This should make it work.

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.

How to rotate a sprite node in sprite kit?

You make SKAction for the rotation and run that action on the node.
for example:

//M_PI/4.0 is 45 degrees, you can make duration different from 0 if you want to show the rotation, if it is 0 it will rotate instantly
SKAction *rotation = [SKAction rotateByAngle: M_PI/4.0 duration:0];
//and just run the action
[yourNode runAction: rotation];

Swift SpriteKit - Prevent sprite node from angular rotation

Your player doesn't actually have a physics body until you get to this line inthe 'physics' section:

player.physicsBody = SKPhysicsBody(texture: texture, size: size)

so all of these lines to set properties on the physics body aren't doing anything:

    player.physicsBody?.isDynamic = true
player.physicsBody?.allowsRotation = false
player.physicsBody?.angularVelocity = 1

// Physics
player.physicsBody?.categoryBitMask = BodyType.player.rawValue
player.physicsBody?.contactTestBitMask = BodyType.dot.rawValue
player.physicsBody?.collisionBitMask = 0

Move the creation of the physics body to the top of the 'physics' section, and all the physics body's property assignment after that.



Related Topics



Leave a reply



Submit