在学习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
时工作得很好,而不是我自己的子类。有什么建议吗?
答案 0 :(得分:23)
以下是一些子类化Hero
的示例方法<强> 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
子类化。这将基本上与您使用的相同(在您想要继承您的Hero之前)。所以你的touchesBegan,在你的问题中设置将起作用。
@implementation HeroSprite
- (id) init {
if (self = [super init]) {
self = [HeroSprite spriteNodeWithImageNamed:@"Spaceship"];
[self setUpHeroDetails];
}
return self;
}
-(void) setUpHeroDetails {
self.name = @"heroNode";
}
@end
答案 1 :(得分:10)
请务必在init方法中添加此内容。
self.userInteractionEnabled = YES;
由于某些原因,在子类化时默认情况下不启用此选项。至少对我来说,它只在手动启用时才有效。
答案 2 :(得分:3)
我经常检查被触摸的节点的父节点,直到找到我要控制的类。 这是一个代码段。
while (touchedNode.parent)
{
if ([touchedNode isKindOfClass:[GameObject class]])
break;
else
touchedNode = (SKSpriteNode*)self.touchedNode.parent;
}
答案 3 :(得分:1)
它只是检测到了这个精灵的触摸。
创建对象SKSpriteNode时,它将自行控制。这意味着,当触摸开始时,它意味着此对象接收此触摸而不是SKView。
因此,如果要检测此触摸,则必须在此对象上编写此代码,而不是在SKView上。如果您想在SKSpriteNode上触摸时在SKView上执行任何操作,则可以使用委托执行此操作。
如果你无法理解我的答案,请随时提出更多问题。
答案 4 :(得分:0)
您的ADVHeroNode是SkNode或没有图像的SkSpriteNode。它们都没有任何范围,它们可以说是重点。 nodeAtPoint将找不到它们:但是图像子SKSpriteNode将会找到它们。由于您明确检查节点的名称,因此检查失败。
您可以为图像指定一个名称,然后检查它,然后引用它的父项来获取ADVHeronode实例。或者直接检查node.parent的名称。