SKNode nodeAtPoint:/ containsPoint:SKSpriteNode和SKShapeNode的行为不同

时间:2015-08-14 16:13:17

标签: sprite-kit skspritenode hittest skshapenode

如果使用nodeAtPoint:SKShapeNodeSKSpriteNode会得到不同的结果。如果我是正确的nodeAtPoint:将使用containsPoint:来检查哪些节点位于给定点。

docu表示containsPoint:将使用其边界框。

我设置了一个简单的场景,其中在情境1中,圆圈是紫色节点的父节点,在情境2中,绿色节点是紫色节点的父节点。 我在两个案例中都点击了父母的边界框应该是。

结果不同。如果我使用SKSpriteNode nodeAtPoint:将给我父母。如果我使用SKShapeNode,则会返回SKScene

(我用鼠标按下的十字标记。)

enter image description here enter image description here

代码:

首先设置:

-(void)didMoveToView:(SKView *)view {
self.name = @"Scene";

SKShapeNode* circle = [SKShapeNode node];
circle.path = CGPathCreateWithEllipseInRect(CGRectMake(0, 0, 50, 50), nil);
circle.position = CGPointMake(20, 20);
circle.fillColor =  [SKColor redColor];
circle.name = @"circle";

SKSpriteNode* pnode = [SKSpriteNode node];
pnode.size = CGSizeMake(50, 50);
pnode.position = CGPointMake(50, 50);
pnode.color =  [SKColor purpleColor];
pnode.name = @"pnode";


[self addChild: circle];
[circle addChild: pnode];
}

第二次设置:

-(void)didMoveToView:(SKView *)view {
self.name = @"Scene";

SKSpriteNode* gnode = [SKSpriteNode node];
gnode.size = CGSizeMake(50, 50);
gnode.position = CGPointMake(30, 30);
gnode.color =  [SKColor greenColor];
gnode.name = @"gnode";

SKSpriteNode* pnode = [SKSpriteNode node];
pnode.size = CGSizeMake(50, 50);
pnode.position = CGPointMake(30, 30);
pnode.color =  [SKColor purpleColor];
pnode.name = @"pnode";


[self addChild: gnode];
[gnode addChild: pnode];

}

点击鼠标致电:

-(void)mouseDown:(NSEvent *)theEvent {
CGPoint location = [theEvent locationInNode:self];
NSLog(@"%@", [self nodeAtPoint: location].name);
}

我错过了什么吗?这是SpriteKit中的错误吗?是否意味着以这种方式工作?

1 个答案:

答案 0 :(得分:1)

答案简短:是的,不,是的

答案很长......

nodeAtPoint的文档说明了

  

返回与点相交的最深的后代

和讨论部分

  

如果一个点位于calculateAccumulatedFrame方法返回的矩形内,则该点被认为是在节点中

第一个语句适用于SKSpriteNodeSKShapeNode个节点,而第二个语句仅适用于SKSpriteNode个节点。对于SKShapeNode,Sprite Kit会忽略节点的边界框,并使用path属性来确定某个点是否与CGPathContainsPoint的节点相交。如下图所示,每个像素选择形状,其中白点代表点击点。

Bounding Box for Shape Node

图1.形状(蓝色)和形状+方形(棕色)的边界框

containsPoint Test

图2. nodeAtPoint

的结果

calculateAccumulatedFrame返回一个相对于其父级的边界框(BB),如下图所示(棕色框是方形的BB)。因此,如果您未适当调整CGPoint containsPoint,则结果将不符合您的预期。要将点从场景坐标转换为父坐标(反之亦然),请使用convertPoint:fromNodeconvertPoint:toNode。最后,containsPoint使用形状path代替其nodeAtPoint的边界框。

enter image description here