2017-03-31 4 views
0

Wie kann ich einen SpriteKit-Knoten an einem festen Punkt mit Touch drehen. Es dreht sich also, wenn der Benutzer seinen Finger zieht. Ich möchte auch die Drehzahl abrufen können. (Diese Frage wurde vorher gestellt, aber ich möchte wissen, wie man es mit SpriteKit macht) Swift 3 PlaygroundsWie man SpriteNode mit Berührung dreht?

Ich habe das bis jetzt funktioniert, aber manchmal bekomme ich einen Fehler für var deltaAngle = angle - startingAngle! ERROR - "gefunden unerwartet null, während optionalen Wert auspackt"

class GameScene: SKScene { 
var startingAngle:CGFloat? 
var startingTime:TimeInterval? 


override func didMove(to view: SKView) { 
    let wheel = SKSpriteNode(imageNamed: "IMG_6797.PNG") 

    wheel.position = CGPoint(x: 200, y: 200) 

    wheel.name = "wheel" 
    wheel.setScale(0.5) 
    wheel.physicsBody = SKPhysicsBody(circleOfRadius: wheel.size.width/2) 
    // Change this property as needed (increase it to slow faster) 
    wheel.physicsBody!.angularDamping = 4 
    wheel.physicsBody?.pinned = true 
    wheel.physicsBody?.affectedByGravity = false 
    addChild(wheel) 
} 

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
    for touch in touches { 
     let location = touch.location(in:self) 
     let node = atPoint(location) 
     if node.name == "wheel" { 
      let dx = location.x - node.position.x 
      let dy = location.y - node.position.y 
      // Store angle and current time 
      startingAngle = atan2(dy, dx) 
      startingTime = touch.timestamp 
      node.physicsBody?.angularVelocity = 0 
     } 
    } 
} 

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 
    for touch in touches{ 
     let location = touch.location(in:self) 
     let node = atPoint(location) 
     if node.name == "wheel" { 
      let dx = location.x - node.position.x 
      let dy = location.y - node.position.y 


      let angle = atan2(dy, dx) 
      // Calculate angular velocity; handle wrap at pi/-pi 
      var deltaAngle = angle - startingAngle! 
      if abs(deltaAngle) > CGFloat.pi { 
       if (deltaAngle > 0) { 
        deltaAngle = deltaAngle - CGFloat.pi * 2 
       } 
       else { 
        deltaAngle = deltaAngle + CGFloat.pi * 2 
       } 
      } 
      let dt = CGFloat(touch.timestamp - startingTime!) 
      let velocity = deltaAngle/dt 

      node.physicsBody?.angularVelocity = velocity 

      startingAngle = angle 
      startingTime = touch.timestamp 
     } 
    } 
} 



override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 

    startingAngle = nil 
    startingTime = nil 
} 

}

+0

Was Sie bisher versucht haben? ;) – Whirlwind

+0

Ich wollte zunächst UIKit (UiGestureRecogniser) verwenden, habe aber zu wenig von SpriteKit in meinem wwdc playground verwendet und muss noch mehr hinzufügen. Ich bin neu in SpriteKit, also nicht sicher, wie es geht @Whirlwind –

+0

Sie sollten die Berührungen touchesBegan und touchesMoved verwenden, um den Berührungsort zu erhalten, und dann den Tangentenwinkel berechnen, bei dem sich Ihr Knoten drehen sollte. Stellen Sie zunächst sicher, dass das Grafikobjekt Ihres Knotens nach rechts ausgerichtet ist, andernfalls sind Ihre Blickwinkel deaktiviert. Beginne dort und komm zurück mit Code, wenn du noch Hilfe brauchst. – TheValyreanGroup

Antwort

0

Dieser Fehler bedeutet genau das, was es sagt. Höchstwahrscheinlich wird "rad" nicht in touchesBegan berührt, aber dann in touchesMoved registriert, was bewirkt, dass startingAngle auf nichts und null gesetzt wird.

Da Sie wahrscheinlich Ihr Rad drehen wollen nicht, dass, wenn der Benutzer nicht auf dem Rad gestartet wurde zu berühren, würde ich eine Wache in touchedMoved hinzufügen

... 
let angle = atan2(dy, dx) 

guard startingAngle != nil else {return} //Exit the function if starting angle was never set 

var deltaAngle = angle - startingAngle! 
... 
+0

Der Code dreht das Rad, wenn der Benutzer es dreht, wie können Sie es drehen, wie der Benutzer seinen Finger schleppt? –