2016-01-06 7 views
4

Я столкнулся с проблемой с zPosition узлов на моей сцене SpriteKit.Проблема с SpriteKit с zPosition

Я создаю узел менеджера, который позволяет управлять «узлами» на узлах zPosition, по сути, позволяя вам избавиться от ручного управления свойством zPosition и вместо этого добавлять узлы с помощью методов, таких как addNodeUnder(node:SKNode), а также создавать группы ,

Вот тестовая сцена я сделал:
We can see a blue node, itself under a green node, itself under a yellow node, itself under a red node.

Проблема заключается в том, что с операциями я сделал, зеленый и желтый узел должен быть сверху красного узла.

Я сделал свой собственный маленький отладчик, отображающий SceneKit «графа сцены» в иерархическом порядке:

Node of type LMManagerNode has zPosition = 0.0 and has children : 
      Node of type LMWarpperNode has zPosition = 0.0 and has children : 
        Node of type SKSpriteNode ('Red node') has zPosition = 0.0. 

      Node of type LMWarpperNode has zPosition = -100.0 and has children : 
        Node of type SKSpriteNode ('Blue node') has zPosition = 0.0. 

      Node of type LMWarpperNode has zPosition = 100.0 and has children : 
        Node of type LMGroupNode ('Test group') has zPosition = 0.0 and has children : 
           Node of type LMWarpperNode has zPosition = -150.0 and has children : 
             Node of type SKSpriteNode ('Yellow node') has zPosition = 0.0. 

           Node of type LMWarpperNode has zPosition = -200.0 and has children : 
             Node of type SKSpriteNode ('Green node') has zPosition = 0.0. 

Как вы можете видеть:

  • Красный узел находится внутри узла, который имеет zPosition = 0
  • Синий узел содержится внутри узла, который имеет zPosition = -100
  • В желтом и зеленом узлах содержатся i Nside узел группы, сам содержится внутри узла, который имеет zPosition = 100

Поскольку узел, который содержит красный узел имеет zPosition = 0 и узел, который содержит зеленый и желтые узлы имеет zPosition = 100, не должен эти два узла будет наверх красного узла?

ignoresSiblingOrder моего SKView установлен в false, кстати ...

EDIT: Это странно: yellowNode.zPosition = 1000 делает желтый узел идти на верхней части красного узла. Как это возможно?

EDIT # 2 Вот код моей функции отладки:

func renderNodeHieararchyForNode(node:SKNode, index:Int) { 

    var i = 0 
    var beginning = "" 
    while i != index { 
     beginning += "   " 
     i++ 
     if i == index { 
      beginning += " " 
     } 
    } 

    print("\(beginning)Node of type \(node.dynamicType) \(node.name != nil ? "('\(node.name!)')" : "") has zPosition = \(node.zPosition)\(node.children.count > 0 ? " and has children :" : ".")") 
    for (i,child) in node.children.enumerate() { 
     renderNodeHieararchyForNode(child, index: index+1) 

     if i == node.children.count-1 { 
      print("") 
     } 
    } 

} 

func renderNodeHiearchyForNode(node:SKNode) { 
    renderNodeHieararchyForNode(node, index: 0) 
} 

Как вы можете видеть, я использую только рамочные SpriteKit методы для его отображения, поэтому выход из моего отладчика, безусловно, правильно.

+0

Я считаю, что вещи не были изменены, а узлы внутри родительских узлов больше не уважают zPosition в некотором роде, вы пробуйте установить желтые и зеленые узлы zPosition а не родители zPosition, и посмотреть, если он на вершине? – Knight0fDragon

+0

Это проводное: 'yellowNode.zPosition = 1000' делает желтый узел на вершине красного узла. Как это возможно? –

+0

@ TrevörAnneDenise: Вы должны показать свой код. –

ответ

2

Вот как вы ожидаете ваш код прямо сейчас

-100: Node 
    # 0: Node 
     # 0: Blue 
    0 : Node 
    # 0: Node 
     # 0:Red 
100 : Node 
    # 0: Node 
     # -200:Green 
     # -150:Yellow 

Но что на самом деле происходит это

-100: Node 
    : Node 
    : Blue 
    : Green 
-50 : Yellow 
    0 : Node 
    : Node 
    : Red 
100 : Node 
    : Node 

Это происходит потому, что zPosition просто вычитается из родителей, и экран затем рисует в 1 проход всех узлов.

Для борьбы с этим, необходимо создать пользовательский класс, который переопределяет функцию addChild и сделать нечто, что следить за своим zPosition в другой переменной (вероятно, словарь), затем установите ребенка zPosition к нулю, и использовать insertChild(node:, atIndex:) для поместите своих детей по порядку в массив children, используя эту новую переменную, чтобы сохранить свой заказ. Тогда, если вы собираетесь еще более сумасшедшие, вы должны следить, когда ребенок меняет zPosition и использовать выше стиль, чтобы установить его правильно в массиве

+0

О, спасибо вам большое за ваш ответ! Это проводное поведение ИМО ... но это оправдано соображениями производительности. –

+0

Фактически, я уже использую словари, поскольку их вычислительная стоимость не увеличивается пропорционально количеству узлов в сцене. Я думаю, что буду использовать его для вычисления zPosition, которые я должен дать детям. –

4

Из документации Apple,

z - высота узла относительно его родительского узла, так как свойство позиции узла представляет собой его позицию x и y относительно позиции родителя. Таким образом, вы используете позицию z для размещения узла выше или ниже позиции родителя.

и

Когда вы Z позиции во внимание, вот как дерево узел визуализации:

  1. глобальное положение г каждого узла вычисляется.
  2. Узлы рисуются в порядке от наименьшего значения z до наибольшего значения z.
  3. Если два узла имеют одно и то же значение z, предки визуализируются первыми, а братья и сестры отображаются в порядке возрастания.

где

node's global z position = node's z position + node's parent's z position + node's parent's parent's z position + ... 

С помощью этой формулы, глобальные Z позиции ваших узлов являются

red is 0  (0 + 0 + 0) 
blue is -100 (0 + -100 + 0) 
yellow = -50 (-150 + 0 + 100 + 0) 
green = -100 (-200 + 0 + 100 + 0) 

От высшего к низшему глобальные позиции г (на основе правил 1 и 2) , порядок, в котором узлы появляются в сцене, составляет

red 
yellow 
green/blue 

, где красный цвет появляется поверх желтого и желтого цветов, находится сверху зеленого/синего. Поскольку зеленый и синий имеют одинаковое глобальное значение z, для определения порядка рисования используется порядок брака (правило 3). В этом случае узел LMWarpperNode верхнего уровня зеленого цвета (то есть его прадедушка) был добавлен к узлу LMManagerNode после узласинего, поэтому синий сначала нарисован, а зеленый - на синем.

Вот окончательный (в обратном порядке) сделать заказ

red    0 
yellow   -50 
green   -100 
blue   -100 (parent was added to scene before green's great grandparent) 
Смежные вопросы