5

I am making a spriteKit based game and wonder if I can make the SKScene fixed width (to make it easier to layout the sprites), and let it resize to the actual screen width while keeping the aspect ratio. Is it possible to achieve this goal and is it recommended (will sprites not be rendered clearly due to resizing)?

user1615898
  • 1,185
  • 1
  • 10
  • 20

2 Answers2

5

Giving the scene a fixed size is actually what we want to do in SpriteKit games. SpriteKit will than scale the game for each device using the scaleMode settings (defaults to .aspectFill). Its not a good idea to make the scene the size of the device or use .resizeFill for scale mode as that will lead to massive inconsistencies on different devices. I have been there before with 1 game and it was an absolute nightmare.

So we basically have 2 ways to do it correctly

1) Set scene size to iPad (e.g 1024x768 -landscape, 768x1024 - portrait. This was the default setting in Xcode 7.

You than usually just show some extra background at the top/bottom (landscape) or left/right (portrait) on iPads.

Examples of games that show more on iPads:

Altos Adventure, Leos Fortune, Limbo, The Line Zen, Modern Combat 5.

2) Apple changed the default scene size in xCode 8 to iPhone 6/7 (750*1334-Portait, 1337*750-Landscape). This setting will crop your game on iPads.

Examples of games that show less on iPads:

Lumino City, Robot Unicorn Attack

Choosing between those 2 options is up to you and depends what game you are making. I usually prefer to use option 1 and show more background on iPads.

Regardless of scene size scale mode is usually best left at the default setting of .aspectFill. This way you will have a consistent experience on all devices.

I would not try to do some random hacks where you manually change scene or node sizes/scales on difference devices, you should let xCode/SpriteKit do it for you.

In code you would initialise a SKScene with your preferred size like so

let gameScene = GameScene(size: CGSize(width: 1024, height: 768))

If you use the visual scene editor you set the scene size directly in the inspector panel on the right.

Hope this helps

crashoverride777
  • 10,581
  • 2
  • 32
  • 56
  • Thanks. I also build the UI (button, menu) of the game using UIKit (because it's hard to do these things with SpriteKit). Can the same technique be applied with UIKit? – user1615898 Mar 21 '17 at 16:07
  • 1
    You should not use UIKit in SpriteKit, its not a good idea. UIKit stuff gets added to your GameViewController. That GameViewController will handle all your SKScenes, which means your UIButtons/UILabels will show in all SKScenes. So you have to manage this by removing/adding UI for each Scene and it will be madness. All your UI should be created with SpriteKit APIs such as SKLabelNodes, SKSpriteNodes, SKNodes etc directly in the relevant scene. There is plenty tutorials to google for example how to create buttons in SpriteKit. I strongly recommend you do not continue with this approach. – crashoverride777 Mar 21 '17 at 16:11
  • I mean if you only have 1 SKScenes than I guess its fine but it is still not a very good idea. – crashoverride777 Mar 21 '17 at 16:12
0

Any resizing comes with a performance penalty and resizing artifacts such as blurred edges or others.

Scene size is defined by the ViewController when it instantiates the scene before presenting it. Isn't it better to create the scene with the same size as the actual screen size and don't resize it any further?

Stoyan
  • 320
  • 1
  • 9
  • I guess the final outcome is better but it makes my layout code harder (because it needs to take care of different screen size.) – user1615898 Mar 18 '17 at 19:36
  • 2
    That would be the case if you hardcoded the sprite positions. A terrible thing to do. You never know what other resolutions or aspect ratios are coming down from Apple's production lines. Here's a nice approach - create a helper constant to keep the screen's view size. Then populate your sprites on screen by using fractions of this view size. For instance, if your view size is 1024x768 (e.g. iPad), instead of putting a sprite on CGPoint(x: 102, y: 77), put it at CGPoint(x: viewSize / 10, y: viewSize / 10). This will keep it in place on all device resolutions. – Stoyan Mar 18 '17 at 19:45
  • Setting the scene size to the actual size of the device is quite a bad idea, it will lead to massive inconsistencies on difference devices (physics, fontSizes, sprite sizes etc). You should set a fixed scene size and let SpriteKit do the scalling for you, usually via .aspectFill. – crashoverride777 Mar 20 '17 at 10:58
  • What kind of inconsistencies do mean? If your math takes into account your device's view size then I don't see which would cause such an inconsistency. For instance, the font size can be calculated as a fraction of the view.height and this will guarantee that the font is always sized relatively to the actual view size. – Stoyan Mar 20 '17 at 11:51
  • @Stoyan Not to take over, but doing it that way makes the textures noticeably stretched out on iPad because of the massive aspect ratio difference compared to iPhone. Letting .aspectFill do the work makes the same aspect ratio for all devices, and you will only need to add some extra background for larger devices (iPads). This is easily done, and is shown in this answer: http://stackoverflow.com/a/34878528/6728196 – Nik Mar 20 '17 at 20:20
  • @Nik No one really suggests stretching textures at all. What I proposed was a way to deliver crisp, pixel-perfect and non-stretched graphics by building the scene with size corresponding to the actual screen size. This doesn't imply textures would be stretched. It would behave the same way as .aspectFill does. – Stoyan Mar 21 '17 at 16:08
  • @Stoyan You're right, but your way only works properly on non-iPad devices that have the same/a similar width to height ratio. The way you're saying would stretch textures on iPad because the view size would be wider (or taller) than that of an iPhone. So using a percentage of that would create a different aspect ratio for the texture compared to on iPhone – Nik Mar 21 '17 at 20:55
  • @Nik The percentage is the same across both dimensions, which means no stretching. It means some of the edges will get cut off screen depending on the target aspect ratio. But this is an acceptable trade-off when dealing with multiple device aspects. And this mostly applies to backgrounds. – Stoyan Mar 23 '17 at 20:23