Reputation: 41
Apples docs state that the nodeAtPoint method on SKNode returns the deepest node in the tree. I take this to mean that if you draw out the tree with the scene node at the top, the answer should be expected as one of the nodes at the bottom-most position in the tree. That isn't happening for me. Here's what my tree looks like:
scene
|
world
|
+------------+----+---------+------------+
| | | |
leftArrow rightArrow boardLayer statusLayer
|
+-----------+-----------+--------+-+---------------+
| | | | |
arrow highlight trough rotating(0) testDump
(21) |
+--------+----------+
| | |
guides board playerPiece
(24) (20) (13)
The numbers in parens are the z-position of the nodes. When I ask the scene for for "nodesAtPoint" and give it a calculated point corresponding to the location of the playerPiece I get: "world, boardLayer, rotating, highlight, board, playerPiece". This is what I expect. However when I query the scene for the "nodeAtPoint" using the same point I get back "highlight". I expected playerPiece. Why didn't that node get returned? What am I overlooking?
I'm not sure what good the code will do but here it is. This code is in Board.m (bottom of the tree).
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]);
The output is:
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
Upvotes: 0
Views: 1064
Reputation: 1030
From the docs:
In a scene, when Sprite Kit processes touch or mouse events, it walks the scene to find the closest node that wants to accept the event. If that node doesn’t want the event, Sprite Kit checks the next closest node, and so on. The order in which hit-testing is processed is essentially the reverse of drawing order.
In other words, hit testing starts from the last child added to a node to the first (as you stated). However, zPosition not only overrides the draw order but also the hit-test order:
Sprite Kit uses the zPosition value only to determine the hit testing and drawing order.
The node with the highest z value will be selected first if multiple nodes overlap at the tap point.
Upvotes: 1