Search code examples
sprite-kitrotationgame-physics

Rotate a sprite along an axis


In SpriteKit I need to rotate a sprite along an axis (e.g. the one that passes through the center of the sprite) just like a wheel to be spinned by the user.

I tried to use applyTorque function (to apply a force that is only angular and not linear), but I cannot handle the different forces caused by different movements on the screen (longer the touch on the screen, stronger the force to apply).

Can someone help me to understand how to deal with this problem?


Solution

  • Here is an answer that spins a ball according to how fast you swipe left / right:

    class GameScene: SKScene {
    
      let speedLabel = SKLabelNode(text: "Speed: 0")
      let wheel      = SKShapeNode(circleOfRadius: 25)
    
      var recognizer:  UIPanGestureRecognizer!
    
      func pan(recognizer: UIPanGestureRecognizer) {
        let velocity = recognizer.velocity(in: view!).x
    
        // Play with this value until if feels right to you.
        let adjustor = CGFloat(60)
    
        let speed = velocity / adjustor
        wheel.physicsBody!.angularVelocity = -speed
      }
    
      // Scene setup:
      override func didMove(to view: SKView) {
        removeAllChildren()
    
        physicsBody = SKPhysicsBody(edgeLoopFrom: frame)
    
        wheel.fillColor = .blue
        wheel.physicsBody = SKPhysicsBody(circleOfRadius: 25)
        wheel.physicsBody!.affectedByGravity = false
        let wheelDot = SKSpriteNode(color: .gray, size: CGSize(width: 5, height:5))
        wheel.addChild(wheelDot)
        wheelDot.position.y += 20
        wheel.setScale(3)
    
        speedLabel.setScale(3)
        speedLabel.position.y = (frame.maxY - speedLabel.frame.size.height / 2) - 45
    
        recognizer = UIPanGestureRecognizer(target: self, action: #selector(pan))
        view.addGestureRecognizer(recognizer)
    
        addChild(wheel)
        addChild(speedLabel)
      }
    
      override func didSimulatePhysics() {
        speedLabel.text = "Speed: \(abs(Int(wheel.physicsBody!.angularVelocity)))"
      }
    }