简体   繁体   中英

How to check if an SKSpriteNode has been tapped

I have been trying to make a simple app where when you tap a circle, it will disappear, and a new one will come up somewhere else.

Here is all my code, edited, but it still does not work.

#import "GameScene.h"

@implementation GameScene

-(void)didMoveToView:(SKView *)view {



[self LabelShow];
}

int Count = 0;
int CountCheck = 0;

-(void) LabelShow {

//Nothing yet

}



-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {


while (CountCheck == Count) {

int FNum1 = 350;
int TNum1 = 650;
int newx = (arc4random()%(TNum1-FNum1))+FNum1;

NSLog(@"RandomXCoord: %i", newx);

int FNum2 = 100;
int TNum2 = 700;
int newy = (arc4random()%(TNum2-FNum2))+FNum2;
NSLog(@"RandomYCoord: %i", newy);

//Location to newx and newy
CGPoint location =  CGPointMake(newx, newy);


SKSpriteNode *Circle = [SKSpriteNode spriteNodeWithImageNamed:@"Circle.png"];

Circle.xScale = 0.2;
Circle.yScale = 0.2;
Circle.position = location;


//Shows chircle

[self addChild:Circle];
CountCheck++;




for (UITouch *touch in touches)
        {
            CGPoint locationTouch = [touch locationInNode:self];

            if ([Circle containsPoint:locationTouch]) {

                    NSLog(@"Success!");
                    [Circle runAction:[SKAction fadeOutWithDuration:0]];
                    Count++;
            }
        }

}
}
@end

As I stated, I have the code that puts the circle on the screen in another method. But whenever I run this code (click the circle), the if statement at the bottom does not get executed.

I tried all the things in this thread: Can't tap SKSpriteNode - no touch detected ios , but I can't get it to work still, and have changed the code back to the original.

Could anyone tell me how I could be able to get the if statement executed when you tap the SKSpriteNode?

Thank you for reading this question.

Edit I changed the code, but it still doesn't work

Add the following above your Circle.xScale = 0.2; statement

Circle.name = @"Circle";

and replace your for-loop with the following

for (UITouch *touch in touches) {
    CGPoint location = [touch locationInNode:self];

    SKNode *node = [self nodeAtPoint:location];
    if ([node.name isEqualToString:@"Circle"]) {
        NSLog(@"Success!");
        [node removeFromParent];
        ++Count;
    }
}

What you need is containsPoint method.

Here is the touchesBeganWithEvent: method you are looking for:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    for (UITouch *touch in touches)
        {
            CGPoint location = [touch locationInNode:self];

            if ([circle containsPoint:location] {
               // executed when you touch a circle
            }
        }
}

Note that you can add more statements and conditions.

I created a game for myself, and I had to do the same thing for a character in it. I subclassed SKNode, and added the character details (SKSpriteNode, name, SKAction, etc) in the subclassed model. Then I added the UITouchBegin method to the subclass, so my character would listen to touches.

It is a lot easier to use subclassing, as you can leave all the legwork to the subclass, and focus on the rest of your game. Adding this code to your subclass will take care of it all:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self removeFromParent];
}

You can even set your scene as your character class's delegate, and as soon as the character is removed from parentview, you can create a new one.

If you get stuck on the subclass issues, this answer really helped me out. Let me know if any questions and good luck :)

The other responses seem to detect touches on a SKSpriteNode, not a tap. This code detects tap events.

Edit TapMaxDelta to change how much movement is allowed before cancelling the tap gesture.

class TapNode : SKSpriteNode {

    // Tap Vars
    var firstPoint : CGPoint?
    var TapMaxDelta = CGFloat(10)


    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }


    init() {
        let texture = SKTexture(imageNamed: "Test.png")
        super.init(texture: texture, color: UIColor.clear, size: texture.size())

        isUserInteractionEnabled = true
    }


    // ================================================================================================
    // Touch Functions
    // ================================================================================================
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let firstTouch = touches.first {
            firstPoint = firstTouch.location(in: self)
        }
    }


    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {}


    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let firstTouch = touches.first, let firstPoint = firstPoint {
            let curPoint = firstTouch.location(in: self)

            if abs(curPoint.x - firstPoint.x) <= TapMaxDelta && abs(curPoint.y - firstPoint.y) <= TapMaxDelta {
                print("tap yo")
            }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM