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

时间:2014-06-16 13:59:16

标签: ios sprite-kit hittest zposition

编辑:Apple在iOS8中对此进行了修复,因此肯定没有预期/预期,但这是一个错误。

当用于渲染节点时,zPosition的解释似乎与用于确定触摸哪个节点的情况有所区别。

当我创建父节点和子节点的层次结构(全部使用zPosition集)时,渲染的最顶层节点由通向节点的所有zPosition的总和确定,因此来自不同父节点的节点可以交错。
然而,当确定用于接收触摸的最顶层节点时,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行注释掉的情况下运行时,会得到以下结果:
 without zPosition

正如预期的那样,第一个容器1被渲染(带有黄色和红色方块),并且顶部容器2被渲染(带有蓝色方块),因此红色方块被隐藏。 在黄色“边框”内部单击时,输出为yellow hit,在蓝色sqaure内部单击打印blue hit,所有内容均按预期进行。

然而,当插入zPosition行时,您会得到以下内容:
 with zPosition

如您所见,container2中的蓝色方块与container1的两个方格交错,当您在红色方块内部单击时,您会得到blue hit
在确定哪个节点最接近触摸时,来自container2的所有内容仍然位于容器1之上。

这是预期的行为吗?如果是这样,有没有一种常见的方法可以解决这个问题,而不会失去一个人的理智?

2 个答案:

答案 0 :(得分:1)

我不知道自你的帖子以来是否有任何改变,或者你是否做错了什么,但在我的情况下它有效。

我只是将您的代码复制粘贴到一个新项目中并进行测试。

如果红色方块位于顶部,我会被红色击中,如果蓝色方块位于顶部,我会得到蓝色方块。

enter image description here

enter image description here

答案 1 :(得分:0)

是的,这是预期的行为。绘图和触摸的z位置不相同。虽然有一个类似于全局z位置的东西,用于绘制一个用于确定触摸哪个节点相对于父节点(以及它们彼此的z-关系)。