如何在不同分辨率的 SpriteKit 游戏中正确显示 HUD?

How to properly display a HUD on a SpriteKit game across different resolutions?

我最初使用 iOS 8 创建我的游戏并在我的 iPhone 6S 上测试。游戏在 5、5S、6、6 Plus、6S 和 6S Plus 上看起来不错(因为所有设备都具有相同的比率 16:9)。从图中可以看出,音乐按钮偏离了右上角。图像被此代码偏移:

 muteButton.position = CGPoint(x: CGRectGetMidX(self.frame) + 920, y: CGRectGetMidY(self.frame) + 480)

我遇到的问题是,如果有人在 iPad 上玩过这个游戏,它就会显示这个。如您所见,底部图形和静音按钮从侧面偏移了很多。

我想让对象始终靠近 frame/view 的两侧。在 xCode 上制作应用 "universal" 也无法解决问题。或者我只是为 iPad 构建一个全新的项目?

不要忘记 4s,您会遇到与 iPad 相同的问题。 SpriteKit 没有像 UI 构建器那样的限制,所以你将不得不通过应用一些数学来适应 4:3 和 16:9 设备,或者强制 4:3 使用 .AspectFit 缩放方法 16:9 带有黑色边框。

现在我不确定 920 和 480 是从哪里来的,但是在检测设备时可能必须在此代码中调整这些数字。确定宽高比的最简单方法是 UIScreen.mainScreen().bounds.width/UIScreen.mainScreen().bounds.height,然后从那里开始工作。

解决!我想到了!对于那些来自未来的人,也可能需要帮助。这适用于横向和纵向。

注意:您必须将 scene.scaleMode 设置为 .AspectFill 才能在所有场景中使用,并且场景大小必须为 2048x1536 或 1536x2048。这将使它也可以扩展到 iPad。

我在 class.

的顶部声明了以下变量
class StartScene: SKScene {
     let playableArea: CGRect
}

然后,我在 override init() 函数中有以下代码。

override init(size: CGSize) {

    //1. Get the aspect ratio of the device
    let deviceWidth = UIScreen.mainScreen().bounds.width
    let deviceHeight = UIScreen.mainScreen().bounds.height
    let maxAspectRatio: CGFloat = deviceWidth / deviceHeight

    //2. For landscape orientation, use this*****
    let playableHeight = size.width / maxAspectRatio
    let playableMargin = (size.height - playableHeight) / 2.0
    playableArea = CGRect(x: 0, y: playableMargin, width: size.width, height: playableHeight)

    //3. For portrait orientation, use this*****
    let playableWidth = size.height / maxAspectRatio
    let playableMargin = (size.width - playableWidth) / 2.0
    playableArea = CGRect(x: playableMargin, y: 0, width: playableWidth, height: size.height)

    super.init(size: size)
}

从这里开始,我然后使用变量 playableArea 来定位我的对象。

titleChild.position = CGPoint(x: CGRectGetMidX(playableArea), y: CGRectGetMaxY(playableArea) - (titleChild.size.height * 0.90))

效果惊人。在 iPhone 4S、5、5S、6、6 Plus、6S、6S Plus 和 iPad 中看起来不错。

如果您想在应用程序中看到该框以确保您做对了,请使用以下功能。

func drawPlayableArea() {
    let shape = SKShapeNode()
    let path = CGPathCreateMutable()
    CGPathAddRect(path, nil, playableArea)
    shape.path = path
    shape.strokeColor = SKColor.redColor()
    shape.lineWidth = 8
    addChild(shape)
}

然后调用didMoveToView()函数中的函数查看红框,确保代码正确。这将创建一个红色框,其大小与用户可见的视图大小相同。现在您有了 playableArea 来保存用户可以看到的框架,您可以将它用于其他事情,例如确保对象不会或不能离开边界等。对于这个屏幕截图,我用它来防止用户将宇宙飞船移出设备。