How to make universal SpriteKit game in Swift

Having universal game is almost must have today. Nobody likes rescaled app with “2x” circle on iPad. When I started making my game, I just jumped into coding without any thought about this. Basically I was testing it mostly on iPhone 6 simulator. Now it’s time to make my game looking nice and consistent on all iOS devices. With new iPhones, we have many different screen sizes now, which means we should have different images for each one of them. But fortunately there’s another approach.

In GameViewController I’m creating scene like this:

As you can see, my game is in portrait mode, so for landscape just switch the values. Take a look at this image:

iDeviceUniversalBackground

It has resolution 1536×2048, and if I set this as a background, with above scaleMode on iPad it’s displayed in its full size, however on iPhones the .AspectFill will crop it. On iPhone 4S you’ll see green rectangle with blue stripes(1366×2048) and on newer iPhones only green rectangle is visible(1152×2048). So it works perfectly fine on all devices, and only one background image is needed.

Problem is when you want to set position of some SKSpriteNode such as UI, relative to device’s screen. Because self.frame.size always returns 1536×2048, even if we’re using iPhone 6 and view’s resolution is “only” 1152×2048. I was quite struggling with this, so I asked question on stackoverflow. Big shout-out to Epic Byte, who solved this issue.

We just need to add this function to our scene class:

This function converts view coordinates to the corresponding scene coordinates. And so now everytime we need to set position of some node, we’ll do this:

Setting anchorPoint to (0,0) is not mandatory, but at least in case of UI it’ll be easier to position node properly, as (10×10) will be space between view’s edges and our node.

That’s it. For any questions, contact me on twitter.

Update: An example project was requested. Here it is: UniversalGame.zip