SpriteKit: добавьте UIGestureRecognizer и определите, какой node был взят

В каком методе я добавляю UIGestureRecognizer к моему SKScene. И как определить, какой node был взят? Это не работает:

-(id)initWithSize:(CGSize)size {    
    if (self = [super initWithSize:size]) {

    ...

    UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)];
    recognizer.direction = UISwipeGestureRecognizerDirectionUp;
    [[self view] addGestureRecognizer:recognizer];

    }
    return self;
}

Ответы

Ответ 1

Вы добавляете UISwipeGestureRecognizer в этот метод:

- (void)didMoveToView:(SKView *)view
{
    UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)];
    recognizer.direction = UISwipeGestureRecognizerDirectionUp;
    [[self view] addGestureRecognizer:recognizer];
}


И это то, как вы обнаруживаете, какой SKNode был выбит:

- (void)handleSwipe:(UISwipeGestureRecognizer *)sender
{
    if (sender.state == UIGestureRecognizerStateEnded)
    {
        CGPoint touchLocation = [sender locationInView:sender.view];
        touchLocation = [self convertPointFromView:touchLocation];
        SKSpriteNode *touchedNode = (SKSpriteNode *)[self nodeAtPoint:touchLocation];

        NSLog(@"%@", touchedNode);
    }
}

Ответ 2

версия Swift 3, вдохновленная S.E. Ответ:

func didSceneViewPan(_ sender: UIPanGestureRecognizer) {
    if sender.state == .began {

        let touchPoint = sender.location(in: sender.view)
        let touchLocation = convertPoint(fromView: touchPoint)

        if isPointInNode(point: touchLocation, node: testNode) { 
            print("yes, node touched!")
        } else {
            print("no bueno :(")
        }
     }
 }


fileprivate func isPointInNode(point: CGPoint, node: SKNode) -> Bool {
    // Get all nodes intersecting <point>
    let nodes = self.nodes(at: point)

    // Return true on first one that matches <node>
    for n in nodes {
        if n == node {
            return true
        }
    }

    // If here, <point> not inside <node> so return false
    return false
}

Ответ 3

В течение 2017...

Скажите, что у вас сцена с различными спрайтами.

Нажмите на один из них. Вам нужно знать, какой из них был использован...

class YourScene: SKScene {
    override func didMove(to view: SKView) {

        super.didMove(to: view)

        // your setup for the scene - example, add objects etc

        setupTapDetection()
    }

    func setupTapDetection() {

        let t = UITapGestureRecognizer(target: self, action: #selector(tapped(_:)))
        view?.addGestureRecognizer(t)
    }

    @objc func tapped(_ tap: UITapGestureRecognizer) {

        // critical...
        if tap.state != .ended { return }

        // Note: you actually do NOT "invert the Y axis",
        // these two calls in fact take care of that properly.
        let viewPoint = tap.location(in: tap.view)
        let scenePoint = convertPoint(fromView: viewPoint)

        // technically there could be more than one node...
        let nn = nodes(at: scenePoint)

        if nn.count == 0 {

            print("you very like tapped 'nowhere'")
            return
        }

        if nn.count != 1 {

            // in almost all games or physics scenes,
            // it is not possible this would happen
            print("something odd happened - overlapping nodes?")
            return
        }

        // you must have a custom class for your sprites
        // Say it is class YourSprites: SKSpriteNode

        if let dotSpriteTapped = nn.first! as? YourSprites {

            // we are done. dotSpriteTapped is the YourSprite,
            // which was tapped. now do whatever you want.

            let nm = String(describing: dotSpriteTapped.name)
            print("   \(nm)")

            // you can now access your own properties:

            let whichTank = dotSpriteTapped.someID
            print("   \(whichTank)")

            let tankPower = dotSpriteTapped.sheildStrength
            print("   \(tankPower)")
        }
    }

Enjoy

Ответ 4

Вы можете проверить узлы в местоположении, включая node, который вы ищете, используя это:

nodes(at: touchLocation).contains(nodeYouAreLookingFor)