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.
Admin
Updated on June 04, 2022Comments
-
Admin almost 2 years
Hi my problem is regarding the rotation of two sprites. When I touch the right half of the screen the rotation starts and moving sprite2 and sprite3. If I touch the left half of the screen the rotation stops because velocity-velocity = 0. If I touch the left half again the rotation begins.
However, if I touch the half of the screen corresponding with the current rotational-direction the velocity is duplicated. I want to be able to change the direction of the rotation, but for the speed to remain constant.
Video demonstrating the problem: http://youtu.be/HxLwl1QZiNM
import SpriteKit class GameScene: SKScene { let sprite = SKSpriteNode(imageNamed:"bWhite") let sprite2 = SKSpriteNode(imageNamed:"bBlue") let sprite3 = SKSpriteNode(imageNamed:"bRed") let circle = SKSpriteNode(imageNamed:"bCircle") override func didMoveToView(view: SKView) { /* Setup your scene here */ backColor = SKColor(red: 0, green: 0, blue: 0, alpha: 1) self.backgroundColor = backColor sprite.setScale(1.25) sprite2.setScale(1) sprite3.setScale(1) sprite.position = CGPointMake(self.frame.size.width/2, (self.frame.size.height/2)-200); circle.position = CGPointMake(self.frame.size.width/2, (self.frame.size.height/2)-200); sprite3.zRotation = 172.77 sprite2.anchorPoint = CGPointMake(-1.10, 0.5); sprite3.anchorPoint = CGPointMake(-1.10, 0.5); self.addChild(sprite) self.addChild(circle) sprite.addChild(sprite2) sprite.addChild(sprite3) } override func touchesBegan(touches: NSSet, withEvent event: UIEvent) { /* Called when a touch begins */ for touch: AnyObject in touches { let location = touch.locationInNode(self) let action = SKAction.rotateByAngle(CGFloat(M_PI), duration:1) let action2 = SKAction.rotateByAngle(CGFloat(-M_PI), duration:1) if (location.x > self.frame.size.width / 2) { sprite2.runAction(SKAction.repeatActionForever(action2)) sprite3.runAction(SKAction.repeatActionForever(action2)) } else { sprite2.runAction(SKAction.repeatActionForever(action)) sprite3.runAction(SKAction.repeatActionForever(action)) } } }
-
Admin almost 10 yearsyeah it works you are the best, but I want to move while I'm touching left half of screen rotate to left, If I don't touch stop and if I touch right half of screen rotate to right
-
Admin almost 10 yearsIf i touch left half of screen rotate to left if stop touching left stop de rotation, no move .If i touch right half of screen rotate to right if stop touching right stop de rotation, no move.
-
T. Benjamin Larsen almost 10 yearsNot quite sure what you are trying to achieve: Do you want the rotation to STOP if you touch a second time on the same half of the screen? Or do you want the rotation to stop when touching the opposite side?
-
Admin almost 10 yearsthe rotation should end If I lift my finger from the screen
-
T. Benjamin Larsen almost 10 yearsOK, then you need to remove the
else if currentRotationDirection == newRotationDirection
and implementcurrentRotationDirection = .none
and call thestopRotation()
function intouchesEnded