我们开发一个App的时候, 通常希望它在 iPhone, iPad, Mac上同时能运行, 尤其是游戏。
这样就需要我们考虑不同设备不同的分辨率,处理起来比较麻烦。
比如说,按照官方的做法,我们需要提供诸如 xx.png, [email protected], [email protected], xx~iPad.png, and [email protected] 这样不同的图片,
另外还有在程序中写大量 if (...){...} else if {...}这样的代码来区分不同的设备, 想想就觉得烦。
尤其是像我这样的个体开发者... 弄那么多套图片. 简直要命。
所以我的做法是, 固定一个大小, 来兼容不同的设备。
这里, 我把我需要的图片, 都按照屏幕大小为 2048 * 1536 来绘制。 也就是说, 我们的背景图的大小是 2048 * 1536, 其他图片也是依照这个比例来绘制。
然后,加载每个场景的时候, 都设置场景大小为 2048 * 1536,并且显示方式为 AspectFill。
如下, 默认的SpriteKit项目, 做简单的修改: (GameViewController.swift)
// // GameViewController.swift // ZombieConga // // Created by Colin on 14/12/21. // Copyright (c) 2014年 icephone. All rights reserved. // import UIKit import SpriteKit class GameViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let myScene = GameScene(size:CGSize(width: 2048, height: 1536)) myScene.scaleMode = .AspectFill let myView = self.view as SKView myView.showsFPS = true myView.showsNodeCount = true myView.ignoresSiblingOrder = true myView.presentScene(myScene) } override func prefersStatusBarHidden() -> Bool { return true } }
我们知道. 2048 * 1536 是iPad Retina 的分辨率。也是我们需要适配的设备里面分辨率最高的。 所以我选择了这个大小。让它来兼容分辨率低的设备。(不会导致图片失真, 当然,造成不必要的开销是在所难免的,但是相对为每个设备准备一套图片还是更加优秀的)
也就是说, 2048 * 1536 在iPad Retina上是完美显示的。 那在其他设备上呢? 这里就要依靠 AspectFill了。
简单看一下下面这张图:
橙色整体区域表示我们场景的真实大小。 黑色线框内的区域表示场景展示在设备上的真实大小。
看下iPad Retina。 他的橙色区域和 黑色线框内的区域是完美吻合的,也就是说在设备上能完整显示。
再看下iPhone4S。 它的真实分辨率应该是 960 * 640 (这里是横屏显示), 但是黑色线框内的区域确实2048 * 1136,是原来的2.1倍。
这要归功于 AspectFill了。 接触过iOS开发的应该都知道, AspectFill是图片显示的一种模式。它保持纵横比缩放图片,图像可能不完全显示。(可以理解成两个方向一起放缩,当两个方向都达到屏幕大小时候,才停止放缩。这时候先达到屏幕大小的那个因为之后的继续放缩,会导致那个方向上的图像被截去。故显示不完全)
同理,iPhone6 的显示效果如图所示。
• iPad Retina [4:3 or 1.33]: Displayed as-is to fit the 2048x1536 screen size.
• iPad Non-Retina [4:3 or 1.33]: Aspect fill will scale a 2048x1536 playable area by 0.5 to fit the 1024x768 screen size.
• iPhone 4S [3:2 or 1.5]: Aspect fill will scale a 2048x1366 playable area by 0.47 to fit the 960x640 screen size.
• iPhone 5 [16:9 or 1.77]: Aspect fill will scale a 2048x1152 playable area by 0.56 to fit the 1136x640 screen size.
• iPhone 6 [16:9 or 1.77]: Aspect fill will scale a 2048x1152 playable area by 0.64 to fit the 1334x750 screen size.
• iPhone 6 Plus [16:9 or 1.77]: Aspect fill will scale a 2048x1152 playable area by 0.93 to fit the 1920x1080 screen size.
总的来说, 使用这样的方法,相对来说让不同设备间的操作统一了(我们的操作都以场景大小 2048*1536为准)。
但是从图片上也能很直观的看出,场景中有些区域是显示不完整的。 比如看iPhone6,如果把一个精灵放在 (0, 0)点, 那么就有可能看不到了,如果那个精灵不够大的话,因为(0,0)点不再设备屏幕显示区域内。
但是,相对与一般的逐个适配,我还是比较推崇上述做法。