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:
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
Alamofireimage Disk Cache Not Working
How to Add a Ibaction to a Button Programmatically in Swift 4
iOS Keyboard Active But Invisible When Uisearchbar Is Tapped
Get Latitude and Longitude Center of Google Map
App Crash on Device But Works on Simulator iOS
How to Pass in a Void Block to Objc_Setassociatedobject in Swift
Swift: Memory Not Clearing When I Segue to Another View Controller, Recieving Memory Warning
How to Convert Date (Without Knowing the Kind) to String
Transforming a Cashapelayer to a Specific Size in Swift
Swift 3 - Nsfetchrequest Distinct Results
Uisearchbar Out of Screen Bounds When Navigation Bar Translucent = False
Get All List of Uiviewcontrollers in iOS Swift
Get Center Coordinates from Mapkit and Display in Uilabel
Display UI (Storyboard Possibly) with Broadcast UI Extension
Customise Uitabbar Height in Xcode11/Ios13 or 13.1