【问题标题】:Why is SKNode nodeAtPoint returning wrong node?为什么 SKNode nodeAtPoint 返回错误的节点?
【发布时间】:2014-08-17 21:03:40
【问题描述】:

Apples 文档指出 SKNode 上的 nodeAtPoint 方法返回树中最深的节点。我认为这意味着,如果您在顶部绘制场景节点的树,则答案应该是树中最底部位置的节点之一。这不会发生在我身上。这是我的树的样子:

                           scene
                             |
                           world
                             |
           +------------+----+---------+------------+
           |            |              |            |
       leftArrow    rightArrow    boardLayer   statusLayer
                                       |
      +-----------+-----------+--------+-+---------------+ 
      |           |           |          |               |
    arrow     highlight     trough     rotating(0)    testDump
                (21)                     |
                                +--------+----------+
                                |        |          |
                             guides   board    playerPiece
                              (24)     (20)      (13)

括号中的数字是节点的 z 位置。当我向场景询问“nodesAtPoint”并给它一个与 playerPiece 位置相对应的计算点时,我得到:“world, boardLayer, rotation, highlight, board, playerPiece”。这是我所期望的。但是,当我使用同一点查询场景中的“nodeAtPoint”时,我会返回“突出显示”。我期待playerPiece。为什么那个节点没有返回?我忽略了什么?

我不确定该代码有什么用处,但就是这样。此代码位于 Board.m(树的底部)中。

    CGPoint pt = [CheckerUtilities locationFromColumn:column row:row];
    CGPoint p = [self.parent.parent convertPoint:pt toNode:[Globals sharedGlobals].scene];
    NSArray *nodes = [[Globals sharedGlobals].scene nodesAtPoint:p];
    for (SKNode *node in nodes)
      NSLog(@"%@, %@, %f", [node class], node.name, node.zPosition);
    SKNode *checker = [[Globals sharedGlobals].scene nodeAtPoint:p];
    NSLog(@"node: %@", [checker class]);

输出是:

SKNode, world, 0.000000
BoardLayer, boardLayer, 0.000000
SKSpriteNode, rotating, 0.000000
Highlight, highlight, 21.000000
Board, board, 20.000000
CheckerSprite, checker, 13.000000
node: Highlight

【问题讨论】:

  • 发布您的相关代码。

标签: ios objective-c sprite-kit sknode


【解决方案1】:

来自文档:

在一个场景中,当 Sprite Kit 处理触摸或鼠标事件时,它会行走 场景中找到想要接受事件的最近节点。如果 该节点不想要该事件,Sprite Kit 检查下一个最近的 节点等等。 命中测试的处理顺序是 基本上与绘制顺序相反。

换句话说,命中测试从添加到节点的最后一个子节点开始到第一个子节点(如您所述)。但是,zPosition 不仅会覆盖绘制顺序,还会覆盖命中测试顺序:

Sprite Kit 仅使用 zPosition 值来确定命中测试 和绘图顺序。

如果多个节点在分接点重叠,将首先选择具有最高z值的节点。

【讨论】:

  • 我认为命中测试只涉及物理类型的接触和碰撞。这也不是任何人点击任何东西的情况 - 这是一个以编程方式计算的点(参见第一行代码 sn-p)。此外,根据 z 值进行滚动,z 是否仅在其对等节点(树的同一级别的节点)中具有相对意义?根据您的 z 事实,那么“nodeAtPoint”不会与“board”一起返回 - 假设我的同行假设是正确的)?
  • OK - 我刚刚通过删除“突出显示”精灵进行了一个小测试。答案确实作为支持 z 声明的“板”返回。但是,Apple 对 'nodeAtPoint' 函数的描述:“子树中与该点相交的后代,如果没有节点与该点相交,则为接收者。如果多个后代与该点相交,则返回树中最深的节点。如果多个节点在同一层,返回z位置最小的相交节点。"
  • 命中测试与碰撞和接触无关。这是搜索视图层次结构以找到可以接受用户触摸的视图的过程。这也适用于 SKNode。
  • 我也看了这个“如果多个节点在同一级别,则返回z位置最小的相交节点。”这是不正确的。从最高到最低的 z 命中测试搜索(更有意义,对吧?)。您可以创建一个简单的测试程序来向自己证明这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-20
  • 1970-01-01
  • 2014-05-09
  • 1970-01-01
相关资源
最近更新 更多