在SpriteKit中,zPosition如何用于渲染和命中testing?

编辑:苹果公司在iOS8中解决了这个问题,所以这肯定不是预期的,而是一个错误。

看起来zPosition在用于渲染节点时与在用于确定哪个节点被触摸时的解释是不同的。

当我创build父节点和子节点的层次结构(全部使用zPosition集合)时,渲染的最顶层节点由通向节点的所有zPositions的总和决定,因此来自不同父节点的节点可以交错。
但是,当确定接收触摸的最顶层节点时,zPosition仅用于区分同一父节点的同胞,当节点具有不同的父节点时,其父节点z顺序优先。 (一个父母的所有孩子都在一个不同的父母的节点之下或之上)

为了说明,一些带有结果的示例代码:

 #import "MyScene.h" @interface NodeWithHitTest : SKSpriteNode -(instancetype)initWithColor:(UIColor *)color size:(CGSize)size; -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; @end @implementation NodeWithHitTest -(instancetype)initWithColor:(UIColor *)color size:(CGSize)size { self = [super initWithColor:color size:size]; self.userInteractionEnabled = YES; return self; } -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"%@ hit", self.name); } @end @implementation MyScene -(id)initWithSize:(CGSize)size { if (self = [super initWithSize:size]) { SKNode* container1 = [SKNode new]; SKNode* container2 = [SKNode new]; NodeWithHitTest* sprite1 = [NodeWithHitTest spriteNodeWithColor:[UIColor yellowColor] size:CGSizeMake(200, 200)]; sprite1.name = @"yellow"; sprite1.position = CGPointMake(self.size.width/2, self.size.height/2); NodeWithHitTest* sprite2 = [NodeWithHitTest spriteNodeWithColor:[UIColor blueColor] size:CGSizeMake(150, 150)]; sprite2.name = @"blue"; sprite2.position = sprite1.position; NodeWithHitTest* sprite3 = [NodeWithHitTest spriteNodeWithColor:[UIColor redColor] size:CGSizeMake(100, 100)]; sprite3.name = @"red"; sprite3.position = sprite1.position; [container1 addChild:sprite1]; [container1 addChild:sprite3]; [container2 addChild:sprite2]; [self addChild:container1]; [self addChild:container2]; // sprite1.zPosition = 1; // sprite2.zPosition = 2; // sprite3.zPosition = 3; } return self; } @end 

当用zPosition行注释运行时,会得到以下结果:
没有zPosition

正如所料,第一个容器1呈现(与一个黄色和红色正方形),顶部容器2呈现(与蓝色方形),所以红色的方块被隐藏。 当在黄色“边框”内部点击时,输出为yellow hit ,蓝色方块内部点击打印blue hit ,如预期的那样。

然而,当插入zPosition线时,您将得到以下结果:
与zPosition

正如你所看到的,container2中的蓝色方块与container1的两个方块交错,当你点击红色方块内部的时候,你会得到blue hit
当确定触摸的哪个节点是最顶层时,container2中的所有内容仍位于container1上方。

这是预期的行为? 如果是这样,有没有一个共同的方式来处理这个问题,而不会失去理智?

我不知道你的post是否有任何改变,或者如果你做错了什么,但在我的情况下,它的工作。

我只是复制粘贴你的代码在一个新的项目,并进行testing。

如果红色方块在顶部,我会得到红色,如果蓝色方块在顶部,我会得到蓝色方块。

在这里输入图像说明

在这里输入图像说明

是的,这是预期的行为。 绘图和触摸的z位置不相同。 虽然有一个像全球z位置绘制一个确定哪个节点被触摸是相对于父(和他们的z关系彼此)。