简体   繁体   中英

Detect double tap on SKNode

Okay, so I have code that will pick a random number between 1 and 2 and based on that spawn a metalCrate: or just a crate:. The metal crate, I would like, should take 2 taps to disappear. Unfortunately, with the code I have, this is not working.

@interface MyScene () <SKPhysicsContactDelegate>

@property (nonatomic) NSTimeInterval lastSpawnTimeInterval;
@property (nonatomic) NSTimeInterval lastUpdateTimeInterval;
@property (nonatomic) SKSpriteNode *crate;
@property (nonatomic) SKSpriteNode *metalCrate;
@property (nonatomic) SKLabelNode *scoreLabel;
@property (nonatomic) int score;

@end

@implementation MyScene

-(id)initWithSize:(CGSize)size {

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

        self.backgroundColor = [SKColor whiteColor];
        _score = 0;

        _scoreLabel = [SKLabelNode labelNodeWithFontNamed:@"Helvetica Neue"];
        _scoreLabel.text = [NSString stringWithFormat:@"%d", self.score];
        _scoreLabel.fontSize = 25;
        _scoreLabel.fontColor = [SKColor blackColor];
        _scoreLabel.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;
        _scoreLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeLeft;
        _scoreLabel.position = CGPointMake(20, 27);
        [self addChild:_scoreLabel];
    }

    return self;
}

- (void)addCrate:(SKColor*)color withDuration:(int)duration withSize:(CGSize)size withMinX:(int)minX withMaxX:(int)maxX {
    self.crate = [SKSpriteNode spriteNodeWithColor:color size:size];
    self.crate.color = color;

    int rangeX = maxX - minX;
    int actualX = (arc4random_uniform(rangeX)) + minX;

    self.crate.position = CGPointMake(actualX, self.frame.size.height + self.crate.size.height/2);
    [self addChild:self.crate];
    self.crate.size = size;

    SKAction * actionMove = [SKAction moveTo:CGPointMake(actualX, -self.crate.size.height/2) duration:duration];
    SKAction * actionMoveDone = [SKAction removeFromParent];
    [self.crate runAction:[SKAction sequence:@[actionMove, actionMoveDone]]];
}

- (void)addMetalCrate:(SKColor*)color withDuration:(int)duration withSize:(CGSize)size withMinX:(int)minX withMaxX:(int)maxX {
    self.metalCrate = [SKSpriteNode spriteNodeWithColor:color size:size];
    self.metalCrate.color = color;

    int rangeX = maxX - minX;
    int actualX = (arc4random_uniform(rangeX)) + minX;

    self.metalCrate.position = CGPointMake(actualX, self.frame.size.height + self.metalCrate.size.height/2);
    [self addChild:self.metalCrate];
    self.metalCrate.size = size;

    SKAction * actionMove = [SKAction moveTo:CGPointMake(actualX, -self.metalCrate.size.height/2) duration:duration];
    SKAction * actionMoveDone = [SKAction removeFromParent];
    [self.metalCrate runAction:[SKAction sequence:@[actionMove, actionMoveDone]]];
}

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

    UITouch *touch = [touches anyObject];
    CGPoint touchLocation = [touch locationInNode:self];
    SKNode *touchedNode = [self nodeAtPoint:touchLocation];

    if (touchedNode != self && touchedNode != self.scoreLabel && [self nodeAtPoint:touchLocation] == self.crate) {
        NSLog(@"Node has been touched. Single tap.");
        [touchedNode removeFromParent];
        [self updateScore:1];
    } else if (touchedNode != self && touchedNode != self.scoreLabel && [self nodeAtPoint:touchLocation] == self.metalCrate && [touch tapCount] == 2) {
        NSLog(@"Node has been touched.  Double tap.");
        [touchedNode removeFromParent];
        [self updateScore:2];
    }
}

- (void)updateScore:(int)amount {

    _score += amount;
    _scoreLabel.text = [NSString stringWithFormat:@"%d", self.score];
}

- (void)update:(NSTimeInterval)currentTime {
    // Handle time delta.
    // If we drop below 60fps, we still want everything to movbe the same distance.
    CFTimeInterval timeSinceLast = currentTime - self.lastUpdateTimeInterval;
    self.lastUpdateTimeInterval = currentTime;
    if (timeSinceLast > 1) { // more than a second since last update
        timeSinceLast = 1.0 / 60.0;
        self.lastUpdateTimeInterval = currentTime;
    }

    [self updateWithTimeSinceLastUpdate:timeSinceLast];
}

- (void)updateWithTimeSinceLastUpdate:(CFTimeInterval)timeSinceLast {

    self.lastSpawnTimeInterval += timeSinceLast;
    if (self.lastSpawnTimeInterval > 0.5) {

        self.lastSpawnTimeInterval = 0;

        //Modify instance properties here

        int random = (arc4random() % 2) + 1;
        //NSLog(@"%d", random);

        if (random == 1) {

            [self addCrate:[SKColor grayColor] withDuration:3.75 withSize:CGSizeMake(45, 45)
                  withMinX:self.crate.size.width / 2 withMaxX:self.frame.size.width - self.crate.size.width / 2];

        } else {

            [self addMetalCrate:[SKColor redColor] withDuration:3 withSize:CGSizeMake(50, 50)
                  withMinX:self.crate.size.width / 2 withMaxX:self.frame.size.width - self.crate.size.width / 2];
        }

        //Modify instance properties here
    }
}

@end

To explain, I think the problem lies in detecting whether the touch is on a metalCrate or just a crate, and I am comparing git to the location of the touch.

Thank you in advance!

You can give a name to your crate and metal crate nodes and simply use that for comparison.

[self.crate setName:@"crate"];
[self.metalCrate setName:@"metalCrate"];

Edit your -touchesBegan: method as follows:

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

    UITouch *touch = [touches anyObject];
    CGPoint touchLocation = [touch locationInNode:self];
    SKNode *touchedNode = [self nodeAtPoint:touchLocation];

    if ([touchedNode.name isEqualToString:@"crate"] && [touch tapCount] == 1) {
        NSLog(@"Crate node has been touched. Single tap.");
        [touchedNode removeFromParent];
        [self updateScore:1];
    } else if ([touchedNode.name isEqualToString:@"metalCrate"] && [touch tapCount] == 2) {
        NSLog(@"Metal crate node has been touched.  Double tap.");
        [touchedNode removeFromParent];
        [self updateScore:2];
    }
}

Figured it out.

All I did was use the idea of comparing a string. In this case I compared the size of the nodes to determine which it was.

Thanks for your help!

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