2017-01-11 49 views
4

这是我的问题:的HitTest为SKSpriteNode

我SpriteKit工作,我希望当一些矩形时它忽略触摸事件(防止调用touchesBegan)。我想如何做到这一点就像“重写的UIView”。但我找不到任何可以忽略事件并阻止呼叫touchesBeganSKSpriteNode的任何类似方法。

当然

  • 我可以设置isUserInteractionEnabled为假,但它会禁用整个精灵不只是一个部分。
  • 我可以在touchesBegan方法中检查触摸的位置,但这是迟到的 - 其他位于相同位置下的精灵将不会再收到此事件。
  • 我也尝试使用SKCropNode,但它只是防止显示精灵和事件处理即使在不可见的区域。

有没有人知道如何防止部分精灵 处理事件?

回答

1

open func nodes(at p: CGPoint) -> [SKNode]可用于检测您已触摸某个点的哪些节点。在此之后,您可以排除CGRect区为您希望每个节点..

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 
       } 
      } 
     } 
    } 
} 

输出(我画一个白色矩形warningZone只能告诉你在哪儿呢..): enter image description here

+0

谢谢你的回答,但我认为这是我寻求的解决方案非常淘气的解决方法。这种方法需要手动检查场景中的每个spripte :(想象一下场景中有几十个或者几个精灵 - 这个开关会有多混乱。我正在寻找解决方案,您可以在其中启用特定sprite的用户交互并覆盖它的命中测试方法。这种方法允许你对SKSpriteNode进行子类化处理,并且充分处理子类定义中子类的类型。 – ukaszm

+0

那么,你提出的这种做法实际上是不可能的,因为你可以触摸一个不直接知道你想要触摸的节点的节点,因为你是在这个子类中,或者它知道他的父节点,但父母不知道正确的节点。换句话说,如果你在堆上拍摄,你必须知道所有堆:在这种情况下,你的触摸就像一颗子弹。 –