2017-01-11 3 views
4

Это моя проблема:HitTest для SKSpriteNode

Я работаю с SpriteKit, и я хочу, чтобы игнорировать сенсорное событие, когда это происходит в некотором прямоугольнике (предотвращения вызова touchesBegan). То, как я хотел бы это сделать, это нечто вроде «переопределения hitTestWithEventUIView». Но я не могу найти какой-либо подобный метод для SKSpriteNode, который мог бы игнорировать событие и предотвращать вызов touchesBegan.

Конечно

  • я мог установить 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 в сцене: (Представьте себе сцену с десятками или hundrets sprites - насколько беспорядочным будет этот переключатель). Я ищу решение, в котором вы можете включить взаимодействие пользователя с конкретным спрайтом и переопределить его метод теста на удар Этот подход позволяет подклассифицировать SKSpriteNode и адекватно обрабатывать тип подкласса внутри определения подкласса. – ukaszm

+0

Ну, что вы предлагаете, это невозможно, потому что вы можете касаться узла, который не знает непосредственно узла, которого вы хотите коснуться, потому что вы внутри этого подкласса, или он знает свой родительский узел, но родитель не знает нужного узла .. другими словами, если вы стреляете в кучу, вы должны знать всю кучу: ваше прикосновение в этом случае похоже на пулю. –