我正在学习iOS中的SpriteKit,并进行了大量的阅读和实验。在坐标、框架和子节点方面,我发现了一些令人困惑的问题。
考虑以下代码片段,我试图在我的宇宙飞船精灵周围绘制一个绿色的框以进行调试:
func addSpaceship()
{
let spaceship = SKSpriteNode.init(imageNamed: "rocketship.png")
spaceship.name = "spaceship"
// VERSION 1
spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
let debugFrame = SKShapeNode(rect: spaceship.frame)
debugFrame.strokeColor = SKColor.greenColor()
spaceship.addChild(debugFrame)
// VERSION 2
// spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
spaceship.setScale(0.50)
self.addChild(spaceship)
}
如果我在标记为“版本1”的行上添加宇宙飞船精灵,我会得到这个:
显然是错误的。但是如果我注释掉上面标记为“版本1”的那一行,并使用标记为“版本2”的那一行,我就能得到我想要的结果:
请注意,标记为版本1和版本2的实际代码是相同的:spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
那么,为什么设置宇宙飞船精灵的位置很重要呢?
在我看来,宇宙飞船精灵的位置与debugFrame的放置无关,因为debugFrame是宇宙飞船精灵的子级,因此,它的坐标应该相对于宇宙飞船精灵的框架。
谢谢 WM
*这与我昨天提出的一个问题有些相关:
在iOS上的SpriteKit中,缩放纹理精灵会产生错误的帧?
但是,a)我现在明白了那个问题,b)这个问题足够不同,值得提出自己的问题。
更新:
嗯-谢谢,大家提供的想法,但我仍然不明白,也许这会有所帮助。
我修改了我的代码以打印相关位置和框架:
func addSpaceship()
{
let spaceship = SKSpriteNode.init(imageNamed: "rocketship.png")
spaceship.name = "spaceship"
println("Spaceship0 Pos \(spaceship.position) Frame = \(spaceship.frame)")
// VERSION 1 (WRONG)
spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
println("Spaceship1 Pos \(spaceship.position) Frame = \(spaceship.frame)")
let debugFrame = SKShapeNode(rect: spaceship.frame)
println("DEBUG Pos \(debugFrame.position) Frame = \(debugFrame.frame)")
debugFrame.strokeColor = SKColor.greenColor()
spaceship.addChild(debugFrame)
// VERSION 2 (RIGHT)
// spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
// println("Spaceship2 Pos \(spaceship.position) Frame = \(spaceship.frame)")
spaceship.setScale(0.50)
self.addChild(spaceship)
}
接下来,我分别运行了两种方式,并得到了以下结果。由于我理解"版本2",让我们从那里开始。
使用"版本2(右侧)"的代码运行后,我得到了以下结果:
Spaceship0 Pos (0.0,0.0) Frame = (-159.0,-300.0,318.0,600.0)
DEBUG Pos (0.0,0.0) Frame = (-159.5,-300.5,319.0,601.0)
Spaceship2 Pos (384.0,512.0) Frame = (225.0,212.0,318.0,600.0)
默认情况下,宇宙飞船节点(Spaceship0)的位置在屏幕左下角。它的框架也是根据其锚点(中心)设置在屏幕左下角来表示的,因此其框架矩形的原点为负数。
然后创建调试框架,其位置默认设置为0, 0,其框架设置与宇宙飞船相同。
接下来的代码(Spaceship2)将宇宙飞船节点移动到视图坐标系中的一个位置(384.0,512.0),并通过将新位置添加到旧原点来移动其框架的原点(即384 + -159 = 225)。
一切都很好。
不幸的是,我仍然无法理解版本1。
当我运行“版本1(错误)”时,得到以下结果:
Spaceship0 Pos (0.0,0.0) Frame = (-159.0,-300.0,318.0,600.0)
Spaceship1 Pos (384.0,512.0) Frame = (225.0,212.0,318.0,600.0)
DEBUG Pos (0.0,0.0) Frame = (0.0,0.0,543.5,812.5)
如上所述,飞船节点(Spaceship0)默认从屏幕左下角开始。其框架也是以锚点(中心)设置在屏幕左下角表示的,因此框架矩形的原点为负数。
代码(Spaceship1)将飞船节点移动到视图坐标为(384.0,512.0)的位置,并通过将新位置添加到旧原点来移动其框架的原点(即384 + -159 = 225)。
然后创建调试框架,其位置默认设置为0,0,框架设置为奇怪的宽度(543.5)和奇怪的高度(812.5)。由于我正在使用spaceship.frame初始化debugFrame.frame,所以我希望新的debugFrame.frame与飞船的frame相同 - 但实际上不是!调试框架的宽度和高度值似乎来自于将实际宽度和高度添加到飞船节点框架的原点(543.5 = 225 + 318.5)。但如果是这样,为什么t的框架矩形原点仍然是0,0而不是添加(225.0 + 0 = 225.0)后的值?
我不明白。