在触摸过程中未检测到自定义SKSpriteNode

在学习SpriteKit时,我正在尝试做一个小型的冒险游戏。 我正在创造一个英雄,并将其添加到现场,然后在touchesBegan:我检测是否触摸源于英雄,并采取相应的行动。

如果我添加英雄作为SKSpriteNode触摸检测到他。 如果我将他添加为SKSpriteNode的子类,则触摸不会! 不同之处在于:

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

VS

 _heroNode = [[ADVHeroNode alloc] init]; 

init看起来像这样:

 - (id) init { if (self = [super init]) { self.name = @"heroNode"; SKSpriteNode *image = [SKSpriteNode spriteNodeWithImageNamed:@"hero.png"]; [self addChild:image]; } return self; } 

添加英雄作为SKSpriteNode的子类的作用在于它被添加到场景,但触摸不检测他。 我的touchesBegan:看起来像这样:

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

SKSpriteNode沮丧的是,这个代码在向上直接添加SKSpriteNode时工作得很好,而不是我自己的子类。 有什么build议么?

这里有一些示例方法来描述你的英雄

SKNode

SKNode子类,这个方法需要你的节点监视触摸,因此self.userInteractionEnabled属性。

 @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

另一个“更容易”的方法,如果你只是想子类SKSpriteNode 。 这将基本上和你用的一样(在你想要inheritance你的英雄之前)。 所以你的触摸开始,如在你的问题设置将起作用。

 @implementation HeroSprite - (id) init { if (self = [super init]) { self = [HeroSprite spriteNodeWithImageNamed:@"Spaceship"]; [self setUpHeroDetails]; } return self; } -(void) setUpHeroDetails { self.name = @"heroNode"; } @end 

只要确保在你的init方法中join这个。

 self.userInteractionEnabled = YES; 

由于某些原因,子类化时默认情况下不启用。 至less对我来说,只有手动启用时才起作用。

我通常检查触摸的节点的父母,直到我find我想要控制的类。 这是一个代码片段。

 while (touchedNode.parent) { if ([touchedNode isKindOfClass:[GameObject class]]) break; else touchedNode = (SKSpriteNode*)self.touchedNode.parent; } 

它只是检测到这个精灵触摸。

当你创build一个Object SKSpriteNode时,它会控制自己。 这意味着,当一个触摸开始时,这意味着这个对象接受这个触摸而不是SKView。

所以,如果你想检测这个触摸,你必须写在这个对象不在SKView上的代码。 如果您想在SKSpriteNode发生触摸时对SKView执行任何操作,可以使用委托来执行此操作。

随意问更多,如果你不明白我的回答。

您的ADVHeroNode是无图像的SkNode或SkSpriteNode。 也不会有任何的程度,他们可以这么说。 它们不会被nodeAtPointfind:但图像子SKSpriteNode会。 由于您显式检查节点的名称,检查失败。

你可以给图像一个名字,然后检查它,然后引用它的父节点来获取ADVHeronode实例。 或者直接检查node.parent的名字。