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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25205882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:46:06  来源:igfitidea点击:

Dealing with different iOS device resolutions in SpriteKit

iossprite-kitxcode6

提问by Sawyer05

I'm playing around with SpriteKit in Xcode 6, iOS 8 beta 5. Everything is all laid out and working perfectly on the iPhone 4S simulator, however when switching to the 5S, the elements at the bottom of the screen are cut off.

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

It was to my understanding that the bottom left corner of the iPhone screen should be CGPoint(0, 0) but after checking the location by printing the coordinates to the console that the lowest point of the left corner I could click was around (5, 44). Is there something wrong in my scene setup thats causing this?

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

No changes have been made to the GameViewController file and even after I strip the GameScene file the problem persists.

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

Can anyone at least point me in the right direction with this?

任何人都可以至少指出我正确的方向吗?

回答by Epic Byte

Adding the following code willfix your problem (code is in Swift):

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

scene.scaleMode = SKSceneScaleMode.ResizeFill

Now if you want to know why this fixes your problem, what your problem actually is, and how to handle multiple resolutions – I suggest you continue reading.

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

There are three things that can impact the position of nodes in your scene.

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

1) Anchor Point
Make sure your scene's anchor point is set to (0,0) bottom left. By default the scene's anchor point starts at (0,0) so i'm assuming that is not causing the issue.

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

2) Size
Check the size of your scene. I typically make my scene size match the size of the device (i.e. iPad, iPhone 4-inch, iPhone 3.5 inch), then I place another layer in the scene for storing my nodes. This makes me able to do a scrolling effect for devices with smaller resolutions, but it depends on your game of-course. My guess is that your scene size might be set to 320, 480 which could be causing the positioning problems on your iPhone 5s.

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

3) Scale Mode
The scale mode has a huge effect on the positioning of nodes in your scene. Make sure you set the scale mode to something that makes sense for your game. The scale mode kicks in when your scene size does not match the size of the view. So the purpose of the scale mode is to let Sprite Kit know how to deal with this situation. My guess is that you have the scene size set to 320,480 and the scene is being scaled to match the iPhone 5 view which will cause positioning problems identical to what you described. Below are the various scale modes you can set for your scene.

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

SKSceneScaleMode.AspectFill

The scaling factor of each dimension is calculated and the larger of the two is chosen. Each axis of the scene is scaledby the same scaling factor. This guarantees that the entire area of the view is filled, but may cause parts of the scene to be cropped.

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



SKSceneScaleMode.AspectFit

The scaling factor of each dimension is calculated and the smaller of the two is chosen. Each axis of the scene is scaledby the same scaling factor. This guarantees that the entire scene is visible, but may require letterboxing in the view.

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



SKSceneScaleMode.Fill

Each axis of the scene is scaledindependently so that each axis in the scene exactly maps to the length of that axis in the view.

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



SKSceneScaleMode.ResizeFill

The scene is not scaled to match the view. Instead, the scene is automatically resizedso that its dimensions always matches those of the view.

场景未缩放以匹配视图。相反,场景会自动调整大小,使其尺寸始终与视图的尺寸相匹配。



Conclusion
It looks like you want to remove the scaling of your scene, that way your positions in the scene will match the actual positions in the view. You can either set your scene's size to match the view size, in which case no scaling will take place. Or you can set your scene's scale mode to ResizeFill which will always make the scene's size match your view's size and it won't scale anything. In general I would stay away from any scaling and instead adjust the interface and the scene size to best suit each device. You may also want to add zoom and/or scrolling to allow devices with smaller resolutions to achieve the same view field.

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



But what if I want to scale my scene?
If however you need to scale your scene, but you still want positions to be relative to the view (i.e. You want (0,0) to be the bottom left of screen even when scene is cutoff) then see my answer here

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



Additional Info
See answer herefor sample code showing how I layout nodes dynamically.

附加信息
请参阅此处的答案以获取显示我如何动态布局节点的示例代码。

See answer herefor more details about scaling to support multiple devices.

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

回答by Tokuriku

If you want to preserve the size of your scene (usually desired when you work with a fixed size and coordinates system), you might want to add padding to either side of your scene. This would remove the letter boxing and preserve all the physics and dynamics of your app on any platform.

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

I created a small Framework to help with this:

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

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

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

Just:

只是:

  1. Download the ZIP file for the Repository
  2. Open the "SceneSizer" sub-folder
  3. Drag the SceneSizer.framework "lego block" in your project
  4. Make sure that the Framework in Embedded and not just Linked
  5. Import the Framework somewhere in your code import SceneSizer
  1. 下载存储库的 ZIP 文件
  2. 打开“SceneSizer”子文件夹
  3. 在您的项目中拖动 SceneSizer.framework “lego block”
  4. 确保框架是嵌入式的,而不仅仅是链接的
  5. 在代码中的某处导入框架 import SceneSizer

And you're done, you can now call the sizer Class with: SceneSizer.calculateSceneSize(#initialSize: CGSize, desiredWidth: CGFloat, desiredHeight: CGFloat) -> CGSize

大功告成,现在可以使用以下命令调用 sizer 类: SceneSizer.calculateSceneSize(#initialSize: CGSize, desiredWidth: CGFloat, desiredHeight: CGFloat) -> CGSize

回答by Vladimir Despotovic

Just in case, try doing CMD+1, worked for me. Some of the elements were cut off because they were simply not displayed in Simulator - I stress this, this is just a simulator feature (and a bug if you ask me, wasted hours of time to solve this). CMD+2, CMD+3 views can sometimes hide parts of the scene.

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