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
JSONencoder and Propertylistencoder Don't Conform to Encoder
How to Get Rid of Array Brackets While Printing
Swift Protocol Property in Protocol - Candidate Has Non-Matching Type
How to Create a Portal Effect in Arkit Just Using the Scenekit Editor
Swift:Difference in '!' and '' in Swift
Using Codable to Encode/Decode from Strings to Ints with a Function in Between
Swift 3: Int Is Not Convertible to Bool in Bitwise Operation
Limiting Concurrent Access to a Service Class with Rxswift
What Does T Equals T Mean in Generics
Replace Exactly One Pixel in an Image and Put It in Another Image via Swift
[_Nscftimer Copywithzone:]: Unrecognized Selector Sent to Instance
Type a Requires That Type B Be a Class Type Swift 4
I Can't Include ' Symbol to Regular Expressions