2014-11-09 14 views
5

Wie kann ich im Swift-Code eine kontinuierliche Benutzerberührung erkennen? Mit Continuous meine ich, dass der Benutzer seinen Finger auf dem Bildschirm hat. Ich möchte einen Sprite-Kit-Knoten in die Richtung der Berührung des Benutzers verschieben, solange der Benutzer den Bildschirm berührt.Wie erkennen Sie kontinuierliche Berührung in Swift?

Antwort

10

Das Schwierigste an diesem Prozess einzelne Berührungen innerhalb einer Multi-Touch-Umgebung verfolgt. Das Problem mit der "einfachen" Lösung für dieses Problem (dh, "istouched" in touchesBegan einschalten und in touchesEnded ausschalten) ist, dass, wenn der Benutzer einen anderen Finger auf dem Bildschirm berührt und hebt es dann die Aktionen der ersten Berührung ab .

Um dies kugelsicher zu machen, müssen Sie einzelne Berührungen über ihre Lebensdauer hinweg verfolgen. Wenn die erste Berührung erfolgt, speichern Sie den Ort dieser Berührung und verschieben Sie das Objekt an diesen Ort. Alle weiteren Berührungen sollten mit der ersten Berührung verglichen werden und sollten ignoriert werden, wenn sie nicht die erste Berührung sind. Mit diesem Ansatz können Sie auch mit Multitouch arbeiten, bei dem das Objekt zu einem beliebigen Finger auf dem Bildschirm bewegt werden kann, und dann zum nächsten Finger gehen, wenn der erste Finger abgehoben wird, und so weiter.

Es ist wichtig zu beachten, dass UITouch Objekte über touchesBegan konstant sind, touchesMoved und touchesEnded. Sie können sich ein UITouch Objekt vorstellen, das in touchesBegan erstellt, in touchesMoved geändert und in touchesEnded zerstört wurde. Sie können die Phase einer Berührung im Laufe ihrer Lebensdauer verfolgen, indem Sie einen Verweis auf das Berührungsobjekt in einem Wörterbuch oder einem Array speichern, wie es in touchesBegan erstellt wird, dann können Sie unter touchesMoved die neue Position aller vorhandenen Berührungen überprüfen und ändern der Verlauf des Objekts, wenn der Benutzer seinen Finger bewegt (Sie können Toleranzen anwenden, um Jitter zu vermeiden, z. B. wenn der X/Y-Abstand kleiner als eine Toleranz ist, ändern Sie nicht den Kurs). In touchesEnded können Sie prüfen, ob die fokussierte Berührung beendet ist, und die Bewegung des Objekts abbrechen oder es so einstellen, dass es sich zu einer anderen Berührung bewegt, die noch immer auftritt. Dies ist wichtig, als ob Sie nur nach einem alten Touch-Objekt-Ende suchen, das andere Berührungen ebenfalls abbricht, was zu unerwarteten Ergebnissen führen kann.

Dieser Artikel ist in Obj-C, aber der Code ist leicht portiert Swift und zeigt Ihnen, was Sie tun müssen, nur die Materialkontrolle heraus unter „einer komplexen Multitouch-Sequenz Handling“: https://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/multitouch_background/multitouch_background.html

16

Die grundlegenden Schritte

  1. Shop die Lage der Berührungsereignisse (touchesBegan/touchesMoved)
  2. Verschieben Sprite Knoten in Richtung dieser Position (update)
  3. Stop, um den Knoten, wenn Berührung Bewegen nicht mehr erkannt wird (touchesEnded)

Hier ist ein Beispiel dafür, wie das zu tun,

Xcode 8

let sprite = SKSpriteNode(color: SKColor.white, size: CGSize(width:32, height:32)) 
var touched:Bool = false 
var location = CGPoint.zero 

override func didMove(to view: SKView) { 
    /* Add a sprite to the scene */ 
    sprite.position = CGPoint(x:0, y:0) 
    self.addChild(sprite) 
} 

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
    touched = true 
    for touch in touches { 
     location = touch.location(in:self) 
    } 
} 

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 
    for touch in touches { 
     location = touch.location(in: self) 
    } 
} 

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 
    // Stop node from moving to touch 
    touched = false 
} 

override func update(_ currentTime: TimeInterval) { 
    // Called before each frame is rendered 
    if (touched) { 
     moveNodeToLocation() 
    } 
} 

// Move the node to the location of the touch 
func moveNodeToLocation() { 
    // Compute vector components in direction of the touch 
    var dx = location.x - sprite.position.x 
    var dy = location.y - sprite.position.y 
    // How fast to move the node. Adjust this as needed 
    let speed:CGFloat = 0.25 
    // Scale vector 
    dx = dx * speed 
    dy = dy * speed 
    sprite.position = CGPoint(x:sprite.position.x+dx, y:sprite.position.y+dy) 
} 

Xcode 7

let sprite = SKSpriteNode(color: SKColor.whiteColor(), size: CGSizeMake(32, 32)) 
var touched:Bool = false 
var location = CGPointMake(0, 0) 

override func didMoveToView(view: SKView) { 
    self.scaleMode = .ResizeFill 
    /* Add a sprite to the scene */ 
    sprite.position = CGPointMake(100, 100) 
    self.addChild(sprite) 
} 

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 
    /* Start moving node to touch location */ 
    touched = true 
    for touch in touches { 
     location = touch.locationInNode(self) 
    } 
} 

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { 
    /* Update to new touch location */ 
    for touch in touches { 
     location = touch.locationInNode(self) 
    } 
} 

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { 
    // Stop node from moving to touch 
    touched = false 
} 

override func update(currentTime: CFTimeInterval) { 
    /* Called before each frame is rendered */ 
    if (touched) { 
     moveNodeToLocation() 
    } 
} 

// Move the node to the location of the touch 
func moveNodeToLocation() { 
    // How fast to move the node 
    let speed:CGFloat = 0.25 
    // Compute vector components in direction of the touch 
    var dx = location.x - sprite.position.x 
    var dy = location.y - sprite.position.y 
    // Scale vector 
    dx = dx * speed 
    dy = dy * speed 
    sprite.position = CGPointMake(sprite.position.x+dx, sprite.position.y+dy) 

}