Swift 将节点定位在屏幕底部下方(Spritekit)

Swift 将节点定位在屏幕底部下方(Spritekit),swift,xcode,sprite-kit,Swift,Xcode,Sprite Kit,您好,我正在尝试在屏幕底部生成项目符号以向上移动,但我的当前代码在屏幕顶部生成项目符号。我试着将高度设为负值,但什么也没发生。这是我正在使用的代码,谢谢 let randomBulletPosition = GKRandomDistribution(lowestValue: -300, highestValue: 300) let position = CGFloat(randomBulletPosition.nextInt()) bullet.position = CGPoin

您好,我正在尝试在屏幕底部生成项目符号以向上移动,但我的当前代码在屏幕顶部生成项目符号。我试着将高度设为负值,但什么也没发生。这是我正在使用的代码,谢谢

let randomBulletPosition = GKRandomDistribution(lowestValue: -300, highestValue: 300)
    let position = CGFloat(randomBulletPosition.nextInt())
    bullet.position = CGPoint(x: position, y: self.frame.size.height + bullet.size.height)

一些很好的转换将帮助你

现在,不要一直这样做,这应该是一个一次完成类型的交易,就像在
lazy
属性中一样

首先,我们想弄清我们的观点

let viewBottom = CGPoint(x:scene!.view!.midX,y:scene!.view!.frame.maxY)  //In a UIView, 0,0 is the top left corner, so we look to bottom middle
其次,我们要将位置转换为场景

let sceneBottom = scene!.view!.convert(viewBottom, to:scene!)
let nodeBottom = scene!.convert(sceneBottom,to:node)
最后,我们希望转换为您需要它成为其中一部分的任何节点。(如果要将其放置在场景中,这是可选的)

代码应该如下所示:

let viewBottom = CGPoint(x:scene!.view!.midX,y:scene!.view!.frame.maxY)  
let sceneBottom = scene!.view!.convert(viewBottom!, to:scene!)
let nodeBottom = scene!.convert(sceneBottom,to:node)
let sceneBottom = scene.convertPoint(from:CGPoint(x:scene!.view!.midX,y:scene!.view!.frame.maxY))
let nodeBottom = node.convert(sceneBottom,from:scene!)
当然,这有点难看

谢天谢地,我们有convertPoint和convert(_from:)来清理一些东西

let sceneBottom = scene.convertPoint(from:viewBottom)
这意味着我们可以清理代码,使其看起来像这样:

let viewBottom = CGPoint(x:scene!.view!.midX,y:scene!.view!.frame.maxY)  
let sceneBottom = scene!.view!.convert(viewBottom!, to:scene!)
let nodeBottom = scene!.convert(sceneBottom,to:node)
let sceneBottom = scene.convertPoint(from:CGPoint(x:scene!.view!.midX,y:scene!.view!.frame.maxY))
let nodeBottom = node.convert(sceneBottom,from:scene!)
然后我们可以将其设为1行,如下所示:

let nodeBottom = node.convert(scene.convertPoint(from:CGPoint(x:scene!.view!.midX,y:scene!.view!.frame.maxY),from:scene!)
只要该节点对类可用,我们就可以将其设置为惰性:

lazy var nodeBottom = self.node.convert(self.scene!.convertPoint(CGPoint(x:self.scene!.view!.midX,y:self.scene!.view!.frame.maxY),from:self.scene!)
这意味着您第一次调用nodeBottom时,它将为您执行这些计算并将其存储到内存中。每次之后,这个数字都会被保留下来

现在,您已经知道屏幕底部在要使用的坐标系中的位置,可以将x值指定给随机生成的任何对象,并且可以减去(node.height*(1-node.anchorPoint.y))以从场景中完全隐藏节点

现在请记住,如果您的节点在不同的父节点之间移动,那么该节点将不会更新


另外请注意,我用!,您可能想使用?首先检查它是否存在。

这在很大程度上取决于您将要看到的容器节点。将节点添加到父节点时,将使用父节点的坐标系对其进行定位。此外,定位取决于父对象的定位点。因此,向我们显示父节点(打印其定位点、位置和大小)。如果父节点是场景,则position属性不相关,但您可以告诉我们视图大小,以及
scene.scaleMode
(以及我上面提到的其他数据)…通常,如果场景(以及节点)的锚点为0.5,则默认为0.5,位置设置为
CGPoint.zero
的节点将放置在屏幕中央。因此,要将一个节点放在顶部边缘的正后方(因此它不可见),您应该这样做:
node.position=frame.size.height/2+node.frame.size.height/2
@whirwind,感谢您的响应,我真的不明白您所说的父节点是什么意思(这是非常新的),我尝试了你上面给出的代码,它给了我一个错误:“没有“+”候选者生成预期的上下文结果类型“CGPoint”父节点是你的节点作为子节点添加到的节点。如果这对你有意义。当你这样做时,
nodeA.addChild(nodeB)
,nodeA被设置为
nodeB
的父节点。因此,如果您检查
nodeB.parent
,您将看到我所说的内容。此外,节点只能有一个父节点。如果您尝试将一个节点添加到另一个父节点,您将收到错误。是的,您收到的错误是因为我犯了错误。您应该使用
node.position.y
,而不是
node.position
…node.position是
CGPoint
。输入错误…感谢您的回复,我收到了一个错误,错误是“无法使用类型为”(CGFloat,to:SKScene?)的参数列表调用'convert'”。您能告诉我在哪一行上吗?“let sceneBottom=scene!。看法convert(viewBottom,to:scene)“line没问题,此转换将在任何定位点上工作,并通过具有子节点的任何节点工作,因此无需担心定位点或父节点。它甚至有助于在使用纵横比填充时对场景进行裁剪