Search code examples
iosswiftsprite-kitinitializationskscene

Creating SKScene, init(fileNamed:) vs init(size:)


If you make a new game template project in Xcode, the default GameViewController will use the following initializer to instantiate the game scene:

let scene = SKScene(fileNamed: "GameScene")

The initializer's use in the template file suggests that this is Apple's recommended way for creating an SKScene. However, I have seen many examples on Stack Overflow that use the init(size:) initializer or simply SKScene().

I am wondering which is the best way to create an instance of SKScene and what are the advantages/disadvantages of each way, as well as various pitfalls to look out for when using one approach versus another.

My reason for asking is that I used init(fileNamed:) to create my game's scene and build level 1. When I later tried to create another instance of the scene for level 2 using init(size:), I ran into problems. Namely, some positional calculations using UIScreen and the scene's frame seem to produce different results if I create the scene using init(size:) instead of init(fileNamed:).

In a more general sense, I would like to hear the opinion of someone who is very familiar with using iOS and SpriteKit about their preferred way of initializing a new SKScene and the pros & cons of using different approaches.


Solution

  • I very strongly recommend not using init(size:) when it comes to creating your scenes that you use as a part of your game. You really should try to keep design separate from structure. This allows for you to change how the layout of your game is, without changing any code, thus reducing the potential for bugs.

    With that being said, there is a very common practice tutorials use that looks like this init(size:view.size). This one causes all kinds of trouble with game designers, and destroys the simple handling of multiple devices that SpriteKit offers. People tend to end up in a 0..1 coordinate system, placing divides everywhere when positioning their nodes, and this too leads to bugs because people may end up forgetting a divide somewhere, or using width when they meant height.

    SKScenes have 4 scale modes that handle how a scene should look on every device, and it should always be taken into consideration when developing a game with this tool. It really should be the first thing that gets discussed so that people can understand the power behind it.

    The only time I would recommend using init(size:) is when you need to create a dynamic scene that cannot be achieved via the sprite kit builder, and when you already have a static size of the window established.