关于坐标,框架和混乱的困惑iOS上的SpriteKit中的子节点? [英] Confusion about coordinates, frames & child nodes in SpriteKit on iOS?

查看:108
本文介绍了关于坐标,框架和混乱的困惑iOS上的SpriteKit中的子节点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我还在玩iOS和Android中的SpriteKit。一直在做很多阅读和阅读大量的实验。我发现*关于坐标,框架和其他的东西我很困惑子节点。



考虑这段代码,我试图在我的宇宙飞船精灵周围绘制一个绿色框用于调试目的:

  func addSpaceship()
{
let spaceship = SKSpriteNode.init(imageNamed:rocketship.png)
spaceship .name =spaceship

//版本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(太空船)
}

如果我添加太空船精灵集在上面标有VERSION 1的行中,我得到了这个:





这显然是错误的。但是如果我在 out 上面标记为VERSION 1的行,而是使用标记为VERSION 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(错误)
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。 ())

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(太空船)
}

然后,我以两种方式运行它得到了这些结果。由于我理解版本2,让我们从那里开始。



使用VERSION 2(RIGHT)代码运行,我得到:

  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.



当我使用VERSION 1(WRONG)代码运行时,我获取

  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)。 / p>

然后创建调试帧,其位置设置为0,0默认情况下为&它的框架设置为具有奇怪的宽度(543.5)&一个奇怪的高度(812.5)。由于我正在使用spaceship.frame初始化debugFrame.frame(我认为这是默认的初始化程序所做的),我希望新的debugFrame.frame与宇宙飞船的框架相同 - 但它不是!调试帧宽度&高度值显然来自添加实际宽度&高度到太空船节点框架的原点(543.5 = 225 + 318.5)。但如果是这种情况,为什么t的框架矩形原点仍然是0,0和0。不一样的添加(225.0 + 0 = 225.0)???



我不明白。

解决方案

您正在使用精灵的框架创建形状节点,该框架位于场景坐标中。因为形状将是精灵的子元素,所以应该在精灵的坐标中创建节点。例如,如果您使用太空船的大小创建 SKShapeNode

 让debugFrame = SKShapeNode(rectOfSize:spaceship.size)

而不是使用太空船的框架, debugFrame 都将以太空飞船为中心。此外, debugFrame 将随船舶适当缩放/移动。


I'm still playing around with learning SpriteKit in iOS & have been doing lots of reading & lots of experimenting. I'm confused by something else I've found* regarding coordinates, frames & child nodes.

Consider this snippet of code, in which I'm trying to draw a green box around my spaceship sprite for debugging purposes:

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)
}

If I add the set the spaceship sprite with the line marked "VERSION 1" above, I get this:

which is clearly wrong. But if I comment out the line marked "VERSION 1" above, and instead use the line marked "VERSION 2", I get what I want:

Notice that the actual code for the lines marked Version 1 & Version 2 is identical: spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))

So why does it matter when I set the position of the spaceship sprite?

To my way of thinking, the position of the spaceship sprite is irrelevant to the placement of the the debugFrame, because the debugFrame is a child of the spaceship sprite & thus, it's coordinates should be relative to the spaceship sprite's frame - right?

Thanks WM

*This is somewhat related to a question I asked yesterday:

In SpriteKit on iOS, scaling a textured sprite produces an incorrect frame?

but a) I understand that one now, and b) this is a different enough that it deserves its own question.

UPDATE:

Hmmm - thanks, guys for the ideas below, but I still don't get it & maybe this will help.

I modified my code to print out the relavant positions & frames:

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)
}

Then, I ran it both ways got these results. Since I understand Version 2, let's start there.

Running with the "VERSION 2 (RIGHT)" code, I got:

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)

The spaceship node starts, by default, with its position at the bottom left of the screen (Spaceship0). Its frame is also expressed in terms of its anchor point (center) being set in the bottom left of the screen, hence the negative numbers for the origin of its frame rect.

The debug frame is then created with its position set to 0, 0 by default & its frame set to be the same as the spaceship's.

The code (Spaceship2) then moves the spaceship node to a position in the view's coordinates (384.0,512.0), and its frame's origin is moved by adding the new position to the old origin (i.e. 384 + -159 = 225).

All is well.

Unfortunately, I still don't get Version 1.

When I run with the "VERSION 1 (WRONG)," code, I get

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)

As above, the spaceship node starts, by default, with its position at the bottom left of the screen (Spaceship0). Its frame is also expressed in terms of its anchor point (center) being set in the bottom left of the screen, hence the negative numbers for the origin of its frame rect.

The code (Spaceship1) then moves the spaceship node to a position in the view's coordinates (384.0,512.0), and its frame's origin is moved by adding the new position to the old origin (i.e. 384 + -159 = 225).

The debug frame is then created with its position set to 0, 0 by default & its frame set to have a strange width (543.5) & a strange height (812.5). Since I'm initializing the debugFrame.frame with spaceship.frame (i think that's what the default initializer does), I would expect the new debugFrame.frame to be the same as the spaceship's frame - but it isn't! The debug frame width & height values apparently come from adding the actual width & height to the origin of the spaceship node frame (543.5 = 225 + 318.5). But if that is the case, why is t's frame rect origin still 0, 0 & not the same adding (225.0 + 0 = 225.0)???

I don't get it.

解决方案

You are creating the shape node using the sprite's frame, which is in scene coordinates. Because the shape will be a child of the sprite, you should create the node in the sprite's coordinates. For example, if you create the SKShapeNode with spaceship's size

let debugFrame = SKShapeNode(rectOfSize: spaceship.size)

instead of using the spaceship's frame, debugFrame will be centered on the spaceship regardless of when you set the ship's position. Also, debugFrame will scale/move appropriately with the ship.

这篇关于关于坐标,框架和混乱的困惑iOS上的SpriteKit中的子节点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆