2017-01-11 3 views
4

Ceci est mon problème:HitTest pour SKSpriteNode

Je travaille avec SpriteKit et je veux ignorer l'événement touche quand il se produit dans un certain rectangle (empêcherons l'touchesBegan). La façon dont je voudrais le faire est quelque chose comme "remplaçant le hitTestWithEvent de UIView". Mais je ne peux pas trouver une méthode similaire pour SKSpriteNode qui pourrait ignorer l'événement et empêcher l'appel touchesBegan.

Bien sûr

  • je pouvais mettre isUserInteractionEnabled false mais il désactive l'image-objet non seulement toute une partie.
  • Je pourrais vérifier l'emplacement du toucher dans la méthode touchesBegan, mais ceci est à la fin - d'autres sprites sous la même position ne recevront plus cet événement.
  • J'ai également essayé d'utiliser SKCropNode, mais cela empêche simplement l'affichage de l'image-objet et les événements sont traités même sur la zone invisible.

Quelqu'un a-t-il une idée sur la façon d'empêcher une partie de l'image-objet de gérer un événement?

Répondre

1

Le open func nodes(at p: CGPoint) -> [SKNode] peut être utile pour détecter les nœuds que vous avez touchés à un point. Après cela, vous pouvez exclure la zone CGRect pour chaque nœud que vous voulez ..

import SpriteKit 
class GameScene: SKScene { 
    var warningZone = CGRect(x: -80, y: -60, width: 100, height: 100) 
    override func didMove(to view: SKView) { 
     let nodeRed = SKSpriteNode.init(color: .red, size: CGSize(width:300,height:200)) 
     nodeRed.name = "nodeRed" 
     addChild(nodeRed) 
     nodeRed.position = CGPoint(x:self.frame.midX,y:self.frame.midY) 
     let nodeBlue = SKSpriteNode.init(color: .blue, size: CGSize(width:300,height:200)) 
     nodeBlue.name = "nodeBlue" 
     addChild(nodeBlue) 
     nodeBlue.position = CGPoint(x:self.frame.midX+100,y:self.frame.midY+20) 
    } 
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
     for touch in touches { 
      let location = touch.location(in: self) 
      let nodesTouched = self.nodes(at: location) 
      for node in nodesTouched { 
       guard let n = node.name else { return } 
       print("Node touched: \(node.name) at point:\(location)") 
       switch n { 
       case "nodeRed": 
        // do your exclusions for the nodeRed 
        print("\(node.frame)") 
        if !warningZone.contains(location) { 
         print("you have touch a safe red zone") 
        } 
       case "nodeBlue": 
        // do your exclusions for the nodeBlue 
        print("\(node.frame)") 
       default: 
        break 
       } 
      } 
     } 
    } 
} 

sortie (je l'ai dessiner le warningZone avec un rectangle blanc que pour vous montrer où est-il ..): enter image description here

+0

Merci pour votre réponse, mais je pense que c'est une solution de contournement très vilaine de la solution que je cherche. Cette approche nécessite de vérifier manuellement chaque spripte dans la scène :(Imaginez scène avec des dizaines ou des centaines de sprites - comment désordre ce commutateur serait.Je cherche une solution où vous pouvez activer l'interaction de l'utilisateur de sprite particulier et remplacer sa méthode de test de succès Cette approche vous permet de sous-classer SKSpriteNode et de gérer adéquatement le type de sous-classe à l'intérieur de la définition de la sous-classe – ukaszm

+0

Eh bien, ce que vous proposez est pratiquement impossible car vous pourriez toucher un noeud qui ne connait pas directement le noeud que vous voulez toucher parce que vous êtes à l'intérieur de cette sous-classe, ou il connait son noeud parent mais le parent ne connait pas le bon noeud .. autrement dit si vous filmez sur le tas, vous devez connaître tout le tas: votre contact dans ce cas est comme une balle .. –