SpriteKit:添加UIGestureRecognizer并检测哪个节点被刷过

时间:2023-01-22 21:16:55

In which method do I add a UIGestureRecognizer to my SKScene. And how do I detect which node was swiped? This doesn't seem to work:

我在哪种方法中为我的SKScene添加了一个UIGestureRecognizer。我如何检测哪个节点被刷过?这似乎不起作用:

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

4 个解决方案

#1


30  

You add the UISwipeGestureRecognizer in this method:

您在此方法中添加UISwipeGestureRecognizer:

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


And that's how you detect which SKNode was swiped:

这就是你如何检测滑动的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


3  

Swift 3 version inspired by S.E.'s answer:

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


2  

For 2017...

Say you have a scene with various sprites.

假设你有一个有各种精灵的场景。

Tap on one of them. You need to know which one was tapped ...

点击其中一个。你需要知道哪一个被点击了......

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


0  

You can check of the nodes at a location include a node you're looking for using this:

您可以使用以下方法检查某个位置的节点是否包含您要查找的节点:

nodes(at: touchLocation).contains(nodeYouAreLookingFor)

#1


30  

You add the UISwipeGestureRecognizer in this method:

您在此方法中添加UISwipeGestureRecognizer:

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


And that's how you detect which SKNode was swiped:

这就是你如何检测滑动的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


3  

Swift 3 version inspired by S.E.'s answer:

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


2  

For 2017...

Say you have a scene with various sprites.

假设你有一个有各种精灵的场景。

Tap on one of them. You need to know which one was tapped ...

点击其中一个。你需要知道哪一个被点击了......

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


0  

You can check of the nodes at a location include a node you're looking for using this:

您可以使用以下方法检查某个位置的节点是否包含您要查找的节点:

nodes(at: touchLocation).contains(nodeYouAreLookingFor)