在iOS上的SpriteKit中,缩放纹理的精灵会产生不正确的帧?

Won*_*ter 5 scaling ios sprite-kit swift

我正在学习SpriteKit游戏开发的乐趣,我遇到了一个看似简单的问题让我感到难过.

基本上,在我缩放纹理化的SKSpriteNode之后,框架不是我所期望的.我已经找到了一些黑客来强迫它达到我想要的水平,但我正在努力了解发生了什么.任何想法赞赏!

这是我的代码WITHOUT SCALING:

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

    let debugFrame = SKShapeNode.init(rect: spaceship.frame)
    debugFrame.strokeColor = SKColor.greenColor()
    spaceship.addChild(debugFrame)

    spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) - 150)

    self.addChild(spaceship)


}
Run Code Online (Sandbox Code Playgroud)

我的应用程序看起来像这样: 与绿色调试框架的未缩放的船

现在,如果我在缩放它的代码行中发表评论(spaceship.setScale(0.50)),我得到这个:

与绿色调试框架的缩放的船

请注意,宇宙飞船在第二张图像中按比例缩小,但帧缩放甚至更小.为什么?

如果我移动缩放线我的飞船添加到场景中,它做什么,我期待,但似乎是错误的:

这是在将太空船添加到场景后调用setScale的代码:

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

    let debugFrame = SKShapeNode.init(rect: spaceship.frame)
    debugFrame.strokeColor = SKColor.greenColor()
    spaceship.addChild(debugFrame)

    spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) - 150)

    self.addChild(spaceship)
    spaceship.setScale(0.50)


}
Run Code Online (Sandbox Code Playgroud)

以下是运行我的应用程序的内容:

添加到场景后缩放

这样可行,但为什么有必要?

下面有人建议,这是SKShapeNode的一个错误.但是,用SKLabelNode替换SKShapeNode具有相同的问题:

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

    let scoreNode = SKLabelNode(text: "100")
    scoreNode.position = CGPointMake(CGRectGetMidX(spaceship.frame), CGRectGetMaxY(spaceship.frame))

    scoreNode.fontColor = SKColor.redColor()
    scoreNode.fontSize = 15.0
    scoreNode.fontName = "Monaco"
    scoreNode.zPosition = 10.0
    spaceship.addChild(scoreNode)


    spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) - 150)

    self.addChild(spaceship)
}
Run Code Online (Sandbox Code Playgroud)

这给了我们:

与SKLabelNode相同的问题

目的是让得分标签(scoreNode)居中于火箭上方,但正如您所看到的那样,它位于顶部舷窗的顶部.在我打电话给spaceship.setScale之后,宇宙飞船的框架出了问题.

我做了一个额外的发现:在我将太空船添加到场景之后,不需要进行setScale调用.它只需要在我将debugFrame/scoreNode添加到太空船之后.如果我在那之后设置了Scale,一切都很好:

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

    let scoreNode = SKLabelNode(text: "100")
    scoreNode.position = CGPointMake(CGRectGetMidX(spaceship.frame), CGRectGetMaxY(spaceship.frame))

    scoreNode.fontColor = SKColor.redColor()
    scoreNode.fontSize = 15.0
    scoreNode.fontName = "Monaco"
    scoreNode.zPosition = 10.0
    spaceship.addChild(scoreNode)

    spaceship.setScale(0.50)

    spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) - 150)

    self.addChild(spaceship)
}
Run Code Online (Sandbox Code Playgroud)

这导致:

这很有效

Jea*_*nès 5

您的问题可能是这两行的顺序:

  spaceship.setScale(0.50)
  let debugFrame = SKShapeNode.init(rect: spaceship.frame)
Run Code Online (Sandbox Code Playgroud)

你缩小了宇宙飞船,然后用缩放的太空船计算矩形的大小.然后,当渲染时,矩形缩小到原始太空船大小的四分之一.

如果你交换行,它应该按预期工作.

通常,最好在实际尺寸中进行构图,然后在将其添加到场景之前缩放整体.

  • 它没有缩放两次!假设你的宇宙飞船大小等于Ws,Hs.你缩小宇宙飞船的尺寸,现在它的尺寸为Ws/2,Hs/2.然后你计算调试帧Wd,Hd的初始大小,Wd = Ws/2和Hd = Hs/2,现在你将debugframe设置为宇宙飞船的子级,因此它按比例缩小0.5并用大小Wd /表示2,Hd/2,它给你Ws/4,Hs/4.如果你将debugframe设置为场景的子节点,由于场景没有比例因子,你的调试帧用大小Ws/2,Hs/2来表示你想要的. (3认同)