HitTest for SKSpriteNode

That's my problem:

I work with SpriteKit, and I want to ignore the touch event when it occurs in some rectangle (call barring touchesBegan). The way I would like to do this is something like "overriding hitTestWithEventof UIView". But I can not find a similar method for SKSpriteNodewhich could ignore the event and prohibit the call touchesBegan.

Of course,

  • I could set isUserInteractionEnabledto false, but it disables the entire sprite, not only for the part.
  • I could check the location of the touch in the method touchesBegan, but it's already late - the other sprites below at the same position will no longer receive this event.
  • I also tried to use it SKCropNode, but it just prevents the display of the sprite, and events are processed even in the invisible area.

Does anyone know how to prevent part of a sprite from processing an event?

+4
source share
1 answer

open func nodes(at p: CGPoint) -> [SKNode]May be useful for determining which nodes you touched a point. After that, you can exclude the zone CGRectfor each node that you want.

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

Exit (I drew a warningZone with a white rectangle just to show you where it is) .: enter image description here

+1
source

Source: https://habr.com/ru/post/1666519/


All Articles