Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom SKSpriteNode not detected during touch

Tags:

ios

sprite-kit

In learning SpriteKit, I am trying to make a small adventure game. I am creating a hero, and adding it to the scene, and then later, during touchesBegan:, I detect if the touch originated on the hero, and take actions accordingly.

If I add the hero as a SKSpriteNode the touch detects him. If I add him as a subclass of SKSpriteNode the touch does not! The difference in adding:

_heroNode = [SKSpriteNode spriteNodeWithImageNamed:@"hero.png"];

vs

_heroNode = [[ADVHeroNode alloc] init];

The init looks like this:

- (id) init {
    if (self = [super init]) {

        self.name = @"heroNode";
        SKSpriteNode *image = [SKSpriteNode spriteNodeWithImageNamed:@"hero.png"];
        [self addChild:image];
    }
    return self;
}

Adding the hero as a subclass of SKSpriteNode works in the sense that it is added to the scene, but the touch doesn't detect him. My touchesBegan: looks like this:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    /* Called when a touch begins */

    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];
    SKNode *node = [self nodeAtPoint:location];
    if (YES) NSLog(@"Node name where touch began: %@", node.name);

    //if hero touched set BOOL
    if ([node.name isEqualToString:@"heroNode"]) {
        if (YES) NSLog(@"touch in hero");
        touchedHero = YES;
    }
}

Frustratingly, this code works just fine when adding a straight up SKSpriteNode, and not my own subclass of it. Any suggestions?

like image 595
zeeple Avatar asked Oct 21 '13 00:10

zeeple


1 Answers

Here are some example ways to subclass your Hero

SKNode

Subclass an SKNode this method requires your node to monitor for touches, hence the self.userInteractionEnabled property.

@implementation HeroSprite

- (id) init {
    if (self = [super init]) {
        [self setUpHeroDetails];
        self.userInteractionEnabled = YES;
    }
    return self;
}

-(void) setUpHeroDetails
{
    self.name = @"heroNode";
    SKSpriteNode *heroImage = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
    [self addChild:heroImage];
}


-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint locationA = [touch locationInNode:self];
    CGPoint locationB = [touch locationInNode:self.parent];
    NSLog(@"Hit at, %@ %@", NSStringFromCGPoint(locationA), NSStringFromCGPoint(locationB));
}

@end

SKSpriteNode

The other "easier" way, if you just want to subclass a SKSpriteNode. This will work essentially the same as you are use to (before you wanted to subclass your Hero). So your touchesBegan, as set up in your question will work.

@implementation HeroSprite

- (id) init {
    if (self = [super init]) {
        self = [HeroSprite spriteNodeWithImageNamed:@"Spaceship"];
        [self setUpHeroDetails];

    }
    return self;
}

-(void) setUpHeroDetails {
    self.name = @"heroNode";
}

@end
like image 105
DogCoffee Avatar answered Oct 18 '22 09:10

DogCoffee