【问题标题】:HitTest for SKSpriteNodeSKSpriteNode 的 HitTest
【发布时间】:2017-01-11 15:31:42
【问题描述】:

这是我的问题:

我使用 SpriteKit,我想在某个矩形中发生触摸事件时忽略它(防止调用 touchesBegan)。我想这样做的方式类似于“覆盖UIViewhitTestWithEvent”。但是我找不到任何类似的SKSpriteNode 方法可以忽略事件并阻止调用touchesBegan

当然

  • 我可以将isUserInteractionEnabled 设置为false,但它会禁用整个精灵而不仅仅是一部分。
  • 我可以在touchesBegan 方法中检查触摸位置,但这已经太晚了 - 同一位置下方的其他精灵将不再接收此事件。
  • 我也尝试使用SKCropNode,但它只是阻止显示精灵并且即使在不可见区域也处理事件。

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

【问题讨论】:

    标签: ios sprite-kit skspritenode hittest


    【解决方案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
                    }
                }
            }
        }
    }
    

    输出(我用白色矩形绘制了警告区,只是为了告诉你它在哪里..):

    【讨论】:

    • 感谢您的回答,但我认为这是我寻求的解决方案非常顽皮的解决方法。这种方法需要手动检查场景中的每个精灵 :( 想象一下有几十个或数百个精灵的场景 - 这个开关会有多混乱。我正在寻找可以启用特定精灵的用户交互并覆盖它的命中测试方法的解决方案. 这种方法允许您继承 SKSpriteNode 并充分处理子类定义中的子类类型。
    • 好吧,你提出的建议实际上是不可能的,因为你可以触摸一个不直接知道你想触摸的节点的节点,因为你在那个子类中,或者它知道他的父节点但父节点不知道'不知道正确的节点..换句话说,如果你在堆上射击,你必须知道所有的堆:在这种情况下你的触摸就像一颗子弹..
    猜你喜欢
    • 2020-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多