如何在不同分辨率的 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 来保存用户可以看到的框架,您可以将它用于其他事情,例如确保对象不会或不能离开边界等。对于这个屏幕截图,我用它来防止用户将宇宙飞船移出设备。
我最初使用 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 来保存用户可以看到的框架,您可以将它用于其他事情,例如确保对象不会或不能离开边界等。对于这个屏幕截图,我用它来防止用户将宇宙飞船移出设备。