Swift 带有zPosition的SpriteKit问题
我在SpriteKit场景中遇到了节点位置问题 我正在构建一个管理器节点,它支持对节点zPosition进行“类似层”的管理,基本上可以让您摆脱对zPosition属性的手动管理,而是使用Swift 带有zPosition的SpriteKit问题,swift,sprite-kit,Swift,Sprite Kit,我在SpriteKit场景中遇到了节点位置问题 我正在构建一个管理器节点,它支持对节点zPosition进行“类似层”的管理,基本上可以让您摆脱对zPosition属性的手动管理,而是使用addNodeUnder(node:SKNode)等方法添加节点,还可以创建组 下面是我制作的一个测试场景: 问题是,对于我所做的操作,绿色和黄色节点应该位于红色节点的顶部 我制作了自己的小调试器,按层次顺序显示SceneKit“场景图”: Node of type LMManagerNode has zP
addNodeUnder(node:SKNode)
等方法添加节点,还可以创建组
下面是我制作的一个测试场景:问题是,对于我所做的操作,绿色和黄色节点应该位于红色节点的顶部 我制作了自己的小调试器,按层次顺序显示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
- 黄色和绿色节点包含在组节点内,其本身包含在具有
zPosition=100
zPosition=0
,而包含绿色和黄色节点的节点具有zPosition=100
,这两个节点不应该位于红色节点的顶部吗
顺便说一下,我的SKView
的ignoresSiblingOrder
设置为false
编辑:这很奇怪:yellowNode.zPosition=1000确实使黄色节点位于红色节点的顶部。怎么可能呢
编辑#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框架方法来显示它,因此我的调试器的输出绝对正确。下面是您现在对代码的期望
-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只是从父节点中减去,然后屏幕将绘制所有节点
为了解决这个问题,您需要创建一个自定义类来重写
addChild
函数,并在另一个变量(可能是字典)中跟踪zPosition
,然后将子zPosition设置为零,并使用insertChild(node:,atIndex:)
使用此新变量在子数组中按顺序排列子对象,以保持顺序。然后,如果你变得更疯狂,你必须跟踪孩子何时改变其位置,并使用上面的样式在数组中正确设置它
z位置是节点相对于其父节点的高度,就像节点的“位置”属性表示其相对于父节点位置的x和y位置一样。因此,可以使用z位置将节点放置在父节点位置的上方或下方
及
当您考虑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)
从最高全局z位置到最低全局z位置(基于规则1和规则2),节点在场景中的显示顺序为
red
yellow
green / blue
其中红色显示在黄色的顶部,黄色显示在绿色/蓝色的顶部。由于绿色和蓝色具有相同的全局z值,因此使用同级顺序(规则3)来确定图形顺序。在本例中,green的顶级LMWarpperNode
节点(即其曾祖父母)被添加到LMManagerNode
节点中,位于blue的LMWarpperNode
节点之后,因此首先绘制蓝色,然后在蓝色上方绘制绿色
这是最终(反向)抽签顺序
red 0
yellow -50
green -100
blue -100 (parent was added to scene before green's great grandparent)
我认为情况发生了变化,父节点内的节点不再以某种方式尊重zPosition,您是否尝试设置黄色和绿色节点zPosition而不是父节点zPosition,并查看它是否位于顶部?这是有线的:
yellowNode.zPosition=1000
使黄色节点位于红色节点的顶部。怎么可能?回答?你的意思是评论,我目前正在为你键入一个答案我建议你阅读标题为@TrevörAnneDenise的部分是的,我理解,我的意思是,你可以将普通的SKNode作为容器节点来模拟问题,将SKSpriteNode作为精灵,而不是使用真正的代码…哦,非常感谢你的回答!这是一种天生的行为。。。但这是基于性能的原因。实际上,我已经在使用字典了,因为它们的计算成本不会随着场景中节点的数量成比例增加。我想我会用它来计算我应该给孩子们的位置。
red 0
yellow -50
green -100
blue -100 (parent was added to scene before green's great grandparent)