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

Posted

技术标签:

【中文标题】在 SpriteKit 中处理不同的 iOS 设备分辨率【英文标题】:Dealing with different iOS device resolutions in SpriteKit 【发布时间】:2014-10-02 01:46:46 【问题描述】:

我在 Xcode 6、ios 8 beta 5 中使用 SpriteKit。一切都在 iPhone 4S 模拟器上布置并完美运行,但是当切换到 5S 时,屏幕底部的元素被剪切离开。

据我了解,iPhone 屏幕的左下角应该是 CGPoint(0, 0) 但在通过将坐标打印到控制台检查位置后,我可以单击的左下角的最低点在附近(5, 44)。我的场景设置是否有问题导致此问题?

没有对 GameViewController 文件进行任何更改,即使我剥离了 GameScene 文件,问题仍然存在。

谁能至少指出我正确的方向?

【问题讨论】:

以防万一,尝试执行 CMD+1,对我有用。一些元素被切断,因为它们根本没有在模拟器中显示 - 我强调这一点,这只是一个模拟器功能(如果你问我,这是一个错误,浪费了几个小时的时间来解决这个问题)。 CMD+2、CMD+3 视图有时可以隐藏部分场景。 【参考方案1】:

添加以下代码解决您的问题(代码在 Swift 中):

scene.scaleMode = SKSceneScaleMode.ResizeFill

现在,如果您想知道为什么这可以解决您的问题、您的问题究竟是什么,以及如何处理多种解决方案——我建议您继续阅读。

有三件事会影响场景中节点的位置。

1) 锚点 确保场景的锚点设置为左下角的 (0,0)。默认情况下,场景的锚点从 (0,0) 开始,所以我假设这不会导致问题。

2) 大小 检查场景的大小。我通常使我的场景大小与设备的大小相匹配(即 iPad、iPhone 4 英寸、iPhone 3.5 英寸),然后我在场景中放置另一个层来存储我的节点。这使我能够为分辨率较小的设备制作滚动效果,但这当然取决于您的游戏。我的猜测是您的场景大小可能设置为 320、480,这可能会导致 iPhone 5s 出现定位问题。

3) 缩放模式 缩放模式对场景中节点的定位有很大的影响。确保将缩放模式设置为对您的游戏有意义的设置。当您的场景大小与视图大小不匹配时,缩放模式就会启动。所以缩放模式的目的就是让 Sprite Kit 知道如何处理这种情况。我的猜测是您将场景大小设置为 320,480,并且正在缩放场景以匹配 iPhone 5 视图,这将导致与您描述的相同的定位问题。以下是您可以为场景设置的各种缩放模式。

SKSceneScaleMode.AspectFill

计算每个维度的比例因子,取较大者 两个被选中。场景的每个轴都缩放相同 比例因子。这保证了视图的整个区域 填充,但可能会导致部分场景被裁剪。

SKSceneScaleMode.AspectFit

计算每个维度的比例因子,取较小者 两个被选中。场景的每个轴都缩放相同 比例因子。这保证了整个场景是可见的,但是 可能需要在视图中添加信箱。

SKSceneScaleMode.Fill

场景的每个轴都是独立缩放的,因此每个轴都在 场景精确映射到视图中该轴的长度。

SKSceneScaleMode.ResizeFill

场景未缩放以匹配视图。取而代之的是场景 自动调整大小,使其尺寸始终与 视图。

结论 看起来您想要删除场景的缩放,这样您在场景中的位置将与视图中的实际位置相匹配。您可以设置场景的大小以匹配视图大小,在这种情况下不会发生缩放。或者,您可以将场景的缩放模式设置为 ResizeFill,这将始终使场景的大小与您的视图大小相匹配,并且不会缩放任何内容。一般来说,我会远离任何缩放,而是调整界面和场景大小以最适合每个设备。您可能还需要添加缩放和/或滚动功能,以允许分辨率较小的设备获得相同的视野。


但是如果我想缩放我的场景呢? 但是,如果您需要缩放场景,但仍希望位置相对于视图(即,即使场景被截断,您也希望 (0,0) 位于屏幕的左下角),请查看我的答案here


其他信息 请参阅答案here 以获取显示我如何动态布局节点的示例代码。

有关扩展以支持多个设备的更多详细信息,请参阅答案 here。

【讨论】:

感谢史诗字节。我们必须为通用游戏设计多大的游戏?我们必须按照 iPhone 6+ 或 iPhone 4 的尺寸进行设计,然后再针对其他设备尺寸进行缩放? @nmokkary 这真的取决于你想如何布局你的游戏。我会给你一个我所做的例子。我有一个适用于 iOS 和 OS X 的 rts 游戏。对于 iOS,我根本不缩放场景。我总是使场景与视图大小相同。现在在我的游戏中,我拥有一个带有滚动功能的大世界。所以这意味着更大屏幕的 iOS 用户将看到更多内容,因为没有缩放。屏幕越大,他们能看到的越多。然而,在 OS X 上,我将所有内容缩放到 iPad 大小。这是因为如果我不进行缩放,大型桌面屏幕会看到太多我的世界。 @nmokkary 很难规划您的游戏在各种尺寸下的外观。我建议您在编辑器中绘制所有屏幕尺寸,并计划您的游戏在每个屏幕上的外观。然后看看你需要在代码中做什么来解决问题。例如,某些屏幕尺寸可能具有相同的纵横比,因此您可以简单地缩放资产。其他尺寸会有不同的比例,因此您需要以某种方式调整布局或使用滚动。希望这可以帮助。也可以在这里查看我的答案***.com/a/30820076/2158465 感谢@Epic Byte。我的游戏界面就像2048游戏。什么是最好的选择? @nmokkary 在这样的游戏中,您可能没有任何滚动或缩放功能,因此您的界面必须完全适合屏幕。问题是每个设备都有不同的尺寸和纵横比。在我看来,我会布置你的按钮,使它们填满屏幕。因此,某些设备(如 iPad)上的按钮应该更大,而其他设备上的按钮应该更小。您根本不需要缩放场景。而是设置精灵的大小,使它们对齐并适合屏幕。你需要想出一些数学布局规则来实现这一点。该规则将直接取决于屏幕尺寸。【参考方案2】:

如果您想保留场景的大小(通常在使用固定大小和坐标系统时需要),您可能需要在场景的任一侧添加填充。这将删除信箱并在任何平台上保留您的应用的所有物理和动态。

我创建了一个小框架来帮助解决这个问题:

https://github.com/Tokuriku/tokuriku-framework-stash

只是:

    下载存储库的 ZIP 文件 打开“SceneSizer”子文件夹 将 SceneSizer.framework “乐高积木”拖到您的项目中 确保框架处于嵌入式而不是链接中 在代码中的某处导入框架import SceneSizer

你已经完成了,你现在可以调用 sizer 类: SceneSizer.calculateSceneSize(#initialSize: CGSize, desiredWidth: CGFloat, desiredHeight: CGFloat) -> CGSize

【讨论】:

【参考方案3】:

以防万一,尝试执行 CMD+1,对我有用。一些元素被切断,因为它们根本没有在模拟器中显示 - 我强调这一点,这只是一个模拟器功能(如果你问我,这是一个错误,浪费了数小时的时间来解决这个问题)。 CMD+2、CMD+3 视图有时可以隐藏部分场景。

【讨论】:

以上是关于在 SpriteKit 中处理不同的 iOS 设备分辨率的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SpriteKit 中的不同设备上使 SKSpriteNode 的速度相同?

iOS - 基于设备的不同图像或缩放相同的图像?

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

如何在 iOS7 SpriteKit 中为不同大小的图像设置动画?

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

iOS 7 之前的 Sprite Kit 可用性