带有SpriteKit的iOS通用设备应用程序,如何为所有视图缩放节点?

Posted

技术标签:

【中文标题】带有SpriteKit的iOS通用设备应用程序,如何为所有视图缩放节点?【英文标题】:iOS Universal Device App with SpriteKit, how to scale nodes for all views? 【发布时间】:2016-04-24 04:52:06 【问题描述】:

我想让 横向 应用 成为通用,以便精灵节点与运行应用的任何视图大小成比例地缩放.我想要一个完全编程的解决方案,因为我不喜欢 IB。

我的游戏非常简单,我不需要任何形式的滚动或缩放,因此整个游戏将始终呈现并占据整个视图。

我正在寻找的可能是更改场景的大小以始终适合视图吗?如果是这样,您能否彻底解释一下,因为我已尝试更改视图控制器的这一部分

    if let scene = GameScene(fileNamed:"GameScene")

成为以大小为参数的构造方法,但 Xcode 不喜欢这样。


我尝试过的事情

    使用 self.view.bounds.width/height 的分数。这通常会使所有 iPhone 看起来都不错,但在 iPad 上会拉伸和倾斜节点以及视图周围的边界框。 在所有四种类型中更改 scaleMode。我想保持良好的做法,感觉 .AspectFill(默认)是我应该让我的应用程序使用的那个,但对建议持开放态度。笔记;我不希望在任何设备上出现黑边,只希望整个视图按比例显示/缩放。 应用编程约束。现在我对此很陌生,并不完全理解约束,但我什至从 RayWenderlich 看到的教程都没有谈论节点上的约束,所以我没有深入研究。

    使用这样的方法在视图之间转换点。这实际上对于节点的点定位非常有效,如果可能的话,我希望这种方法能够解决,但是我仍然遇到节点大小的问题。此外,当我使用这种方法为 iPad 构建时,视图似乎以纵向开始,节点看起来很好,但随后我必须手动将其切换为横向,精灵和视图边界再次变得混乱。方法如下:

    func convert(point: CGPoint)->CGPoint 
        return self.view!.convertPoint(CGPoint(x: point.x, y:self.view!.frame.height-point.y), toScene:self)
    
    

    关于 RW 和互联网上其他任何地方的无数视频教程。

提前致谢!我很感激帮助。我知道这个话题很奇怪,因为很多人对此提出了问题,但每个人的情况似乎都不同,以至于一个解决方案并不适合所有人。

【问题讨论】:

【参考方案1】:

我最初尝试用 2 个游戏自己进行缩放,这简直太疯狂了(场景大小 = 视图大小或场景缩放模式 = .ResizeFill)。您必须调整所有设备的所有值,例如字体大小、精灵大小、脉冲等,而且它永远不会保持一致。

所以你基本上有两个选择

1) 将场景大小设置为 1024X768(横向)或 768x1024(纵向)。这是 Xcode 7 中的默认设置。

您通常只是在 iPad 上的顶部/底部(横向)或左侧/右侧(纵向)有/显示一些额外的背景,而这些背景会在 iPhone 上被裁剪。

在 iPad 上显示更多/在 iPhone 上裁剪的游戏示例:

Altos Adventure、Leos Fortune、Limbo、The Line Zen、Modern Combat 5。

2) Apple 将 xCode 8 中的默认场景大小更改为 iPhone 6/7(7501334-Portait、1337750-Landscape)。此设置将裁剪您在 iPad 上的游戏。

在 iPad 上显示较少的游戏示例:

Lumino City,机器人独角兽攻击

这两个选项之间的选择取决于您,并且取决于您正在制作的游戏。我通常更喜欢使用选项 1 并在 iPad 上显示更多背景。

无论场景大小,缩放模式通常最好保留默认设置 .aspectFill。

要调整标签等特定的东西,你可以这样做

 if UIDevice.current.userInterfaceIdiom == .pad 
   ...
 

您可以自己尝试场景缩放,创建一个新的 SpriteKit 示例游戏项目。在所有 iPhone 上运行,您会发现 HelloWorld 标签在所有设备上看起来都很完美。

现在将默认设置更改为场景大小 = 帧或使用 .ResizeFill,HelloWorld 标签不再在所有设备上正确缩放。

作为旁注,这条线

 if let scene = GameScene(fileNamed: "GameScene")

引用 GameScene.sks 文件。您说您以编程方式执行所有操作,因此您可以删除 GameScene.sks 文件并将行更改为

 let skView = view as! SKView!
 let scene = GameScene(size: CGSize(width: 1024, height: 768)) // 768 x 1024 if portrait

更新:

我现在使用稍微不同的变体,因为我在将我的游戏适应 iPhoneX 时遇到了问题。我将场景大小设置为 1334x750,并使用宽高比作为缩放模式。如果需要,我会运行一些代码来删除黑条,例如在 iPad 或 iPhone X 上。它基于这篇很棒的文章(链接不再有效)。

http://endlesswavesoftware.com/blog/spritekit-skscene-scalemode/

【讨论】:

感谢您的帮助!我将此标记为正确,因为它包含对我的问题的有效解决方案。但是我只是用另一种方法解决了它,并将坚持这种方法:在我的 info.plist 中,我注意到 iphone 和 ipad 的屏幕方向在那里,ipad 的纵向视图也仍然在那里。我只是将它们从列表中删除。之后,我还需要将 scene.size 设置为 skView.bounds.size 并且这两件事修复了它(一个没有另一个会破坏程序)。现在我继续相对于视图定位和缩放节点,一切正常。 感谢您的标记。是的,我没有意识到您正在寻找 plist 中的景观材料。即使您在 Xcode 中取消选择肖像,这两个条目仍然存在,这有点奇怪,一开始让我很头疼。快乐编码

以上是关于带有SpriteKit的iOS通用设备应用程序,如何为所有视图缩放节点?的主要内容,如果未能解决你的问题,请参考以下文章

在 SpriteKit 中,如何制作我的英雄精灵的裁剪(带有透明段)图像?

如何使用 swift 使用带有 spriteKit 的情节提要

在 SpriteKit 中处理不同的 iOS 设备分辨率

iOS 7 之前的 Sprite Kit 可用性

带有 SpriteKit 的着色器仅注册黑色的 alpha

SpriteKit 设备方向改变导致 SKLabelNode 变形 Swift