0

my problem is I don't know how to rotate a sprite by swipe. I want to rotate it clockwise when I swipe to the left, and other way when I swipe to the right. And how fast I swipe is how fast it rotate, then it slow down and stop. I tried to look for the answer but no hope. Can anyone please help me?

This is the code I used. When I touch left, sprite rotates clockwise around center, and touch right for others way. I just don't know how to calculate the speed of swipe and use it to calculate speed of rotation.

import SpriteKit
enum State {
case Stopped
case Clockwise
case CounterClockwise }

let two_pi = CGFloat(M_PI*2.0)
let pi = CGFloat(M_PI)

// These are useful vector/point operators
func * (left:CGPoint, right:CGFloat) -> CGPoint {
return CGPointMake(left.x*right, left.y*right)
}

func += (inout left:CGPoint, right:CGPoint) {
left = CGPointMake(left.x+right.x, left.y+right.y)
}

func * (left:CGVector, right:CGFloat) -> CGVector {
return CGVectorMake(left.dx*right, left.dy*right)
}

func / (left:CGVector, right:CGFloat) -> CGVector {
return CGVectorMake(left.dx/right, left.dy/right)
}

class GameScene: SKScene {

let shape = SKShapeNode(circleOfRadius: 7)
let radius:CGFloat = 30
var center = CGPointZero
var currentAngle = -pi/2
let angleIncr = two_pi / 60.0
var state:State = .Stopped
let rotationOffset: CGFloat = -CGFloat(M_PI/2.0)
private var targetZRotation: CGFloat = 0

override func didMoveToView(view: SKView) {
    scaleMode = .ResizeFill
    // Set the center of the sling
    center = CGPointMake (CGRectGetMidX(view.frame),CGRectGetMidY(view.frame))
    addBall()
    let circle = SKShapeNode(circleOfRadius: radius)
    circle.position = CGPointMake (CGRectGetMidX(view.frame),CGRectGetMidY(view.frame))
    addChild(circle)
}

// Adds a circle shape node at the bottom of the sling
func addBall() {
    currentAngle = -pi/2
    shape.fillColor = SKColor.blueColor()
    shape.strokeColor = SKColor.clearColor()
    shape.position = CGPointMake (center.x, center.y-radius)
    shape.physicsBody = SKPhysicsBody(circleOfRadius: 7)
    shape.physicsBody?.affectedByGravity = false
    shape.physicsBody?.mass = 0.5
    shape.zPosition = 1
    addChild(shape)
}

func calculateAngleToTouch(touch: UITouch) {
    let position = touch.locationInNode(self)
    let angle = atan2(position.y-shape.position.y, position.x-shape.position.x)

    targetZRotation = angle + rotationOffset
}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    let touch : UITouch = (touches.first as UITouch?)!
    let touchPosition = touch.locationInNode(self)

    let newRotationDirection : State = touchPosition.x < CGRectGetMidX(self.frame) ? .Clockwise : .CounterClockwise

    if state != newRotationDirection && state != .Stopped {

        state = newRotationDirection
    } else if state == newRotationDirection {
        state = .Stopped
    }
    else if (state == .Stopped){
        state = newRotationDirection
    }

    calculateAngleToTouch((touches.first as UITouch?)!)
}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
    calculateAngleToTouch((touches.first as UITouch?)!)
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    if (state == .Clockwise || state == .CounterClockwise) {
        state = .Stopped
    }
}

override func update(currentTime: CFTimeInterval) {
    var point = angleToPoint(currentAngle) * radius
    point += center
    shape.position = point
    switch (state) {
    case .CounterClockwise:
        currentAngle -= -angleIncr
    case .Clockwise:
        currentAngle -= angleIncr
    default:
        break
    }
    // Wrap at 2 pi
    currentAngle %= two_pi
}

func angleToPoint(angle:CGFloat) -> CGPoint {
    return CGPointMake(cos(angle), sin(angle))
}

func magnitude(v1:CGVector) -> CGFloat {
    return sqrt(v1.dx*v1.dx+v1.dy*v1.dy)
}
}
Thanh
  • 65
  • 2
  • 10
  • This may be what you're looking for http://stackoverflow.com/questions/32143382/drag-rotate-a-node-around-a-fixed-point – 0x141E Oct 27 '15 at 07:50
  • it's not like what I want, but I figured out from his calculation. Thanks a lots for your help. – Thanh Oct 28 '15 at 00:44
  • I just reread your question, and it seems like it's exactly what you're asking for. What's different? – 0x141E Oct 28 '15 at 00:48
  • my node is rotated around a fix point. and that is rotated itself. So I used his calculation from angularVelocity and apply it to angle of my node. It's useful, but I have to modify it. – Thanh Oct 28 '15 at 00:54
  • You can create an SKNode, add the sprite (with a non-zero x position) to the SKNode, and rotate the SKNode (using the existing code) to achieve the same effect. – 0x141E Oct 28 '15 at 01:01
  • how couldn't I think this way. I made everything more complicated. Thanks for point that out. – Thanh Oct 28 '15 at 01:07

2 Answers2

0

Can't you apply an SKAction to rotate your sprite?

            let action = SKAction.rotateByAngle(100, duration: 0.1)
            yourSprite.runAction(action, completion: {})

Calculate the SKAction parameters for degrees and duration depending on your swipe speed.

Stefan
  • 5,203
  • 8
  • 27
  • 51
  • I used func update to rotate. I just added my code in my question. I don't know to calculate the speed – Thanh Oct 26 '15 at 05:24
  • I've create a short tutorial about sprite movement and rotation. Maybe it is useful for you: http://stefansdevplayground.blogspot.de/2014/11/how-to-implement-space-shooter-with.html – Stefan Oct 26 '15 at 22:50
0

You can use the SKSpriteNode.zRotation property to rotate the sprite. And use the touchesBegan and touchesMoved function to track the swiped distance.

var previousPoint : CGPoint!

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {

   previousPoint = (touches.anyObject() as UITouch).locationInView(self.view)
}

override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {

    let currentPoint = (touches.anyObject() as UITouch).locationInView(self.view)

    let distance = currentPoint.x - previousPoint.x

    previousPoint = currentPoint

    sprite.zRotation = sprite.zRotation + distance/100.0

}
rakeshbs
  • 24,392
  • 7
  • 73
  • 63
  • I just edit and added my code. Sorry, I didn't mention in my question that I want to rotate sprite around a center point. Can you help me with this? – Thanh Oct 26 '15 at 05:19