2014-11-09 12 views
5

Come riconoscere il tocco continuo dell'utente nel codice Swift? Per continuo intendo che l'utente ha il dito sullo schermo. Mi piacerebbe spostare un nodo del kit sprite nella direzione del tocco dell'utente fintanto che l'utente sta toccando lo schermo.Come riconoscere il tocco continuo in Swift?

risposta

10

La cosa più difficile di questo processo sta monitorando singoli tocchi all'interno di un ambiente multitouch. Il problema con la soluzione "semplice" (es., Girare "istouched" su e disattivarlo in touchesEnded) è che se l'utente tocca un altro dito sullo schermo e poi lo solleva, annullerà le azioni del primo tocco .

Per rendere questo a prova di proiettile, è necessario tenere traccia dei singoli tocchi nel corso della loro vita. Quando si verifica il primo tocco, si salva la posizione di quel tocco e si sposta l'oggetto verso quella posizione. Eventuali ulteriori tocchi dovrebbero essere confrontati con il primo tocco e dovrebbero essere ignorati se non sono il primo tocco. Questo approccio consente anche di gestire il multitouch, in cui è possibile spostare l'oggetto verso un dito attualmente sullo schermo, quindi passare al dito successivo se il primo viene sollevato e così via.

E 'importante notare che UITouch oggetti sono costanti in tutto touchesBegan, touchesMoved e touchesEnded. È possibile pensare a un oggetto UITouch come creato in touchesBegan, modificato in touchesMoved e distrutto in touchesEnded. È possibile tenere traccia della fase di un tocco nel corso della sua vita salvando un riferimento all'oggetto touch su un dizionario o un array mentre viene creato in touchesBegan, quindi in touchesMoved è possibile controllare la nuova posizione di eventuali tocchi esistenti e alterare la rotta dell'oggetto se l'utente muove il dito (è possibile applicare tolleranze per evitare jitter, ad esempio, se la distanza x/y è inferiore a qualche tolleranza, non alterare la rotta). In touchesEnded è possibile verificare se il tocco a fuoco è quello che è terminato e annullare il movimento dell'oggetto, oppure impostarlo per spostarsi verso qualsiasi altro tocco ancora in corso. Questo è importante, come se si controllasse la fine di qualsiasi oggetto vecchio tocco, questo annullerebbe anche altri tocchi, che possono produrre risultati imprevisti.

Questo articolo è in Obj-C, ma il codice è facilmente portato su Swift e mostra ciò che devi fare, basta controllare la roba in "Gestione di una sequenza Multitouch Complex": https://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/multitouch_background/multitouch_background.html

16

I passaggi fondamentali

  1. Conservare la posizione degli eventi di tocco (touchesBegan/touchesMoved)
  2. Sposta nodo sprite verso quella posizione (update)
  3. smettono di muoversi il nodo in cui non è più rilevata tocco (touchesEnded)

Ecco un esempio di come fare

0.123.

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) 

} 
Problemi correlati