Scene size in Xcode 6 / SpriteKit / Swift
You have to edit the GameViewController:
Cut everything from viewDidLoad()
except super.viewDidLoad()
Overwrite viewWillLayoutSubviews
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
// Configure the view.
var skView = self.view as SKView
skView.showsFPS = true
skView.showsNodeCount = true
/* Sprite Kit applies additional optimizations to improve rendering performance */
skView.ignoresSiblingOrder = true
/* Set the scale mode to scale to fit the window */
scene.size = skView.bounds.size
scene.scaleMode = .AspectFill
skView.presentScene(scene)
}
}
Also you should set the scene size as you can see
scene.size = skView.bounds.size
Hope this helps
There is also a great Tutorial where this is explained better:
http://www.raywenderlich.com/49721/how-to-create-a-breakout-game-using-spritekit
(Chapter 1 or 2)
How to change SKscene size
1) If you use .sks files (the spriteKit visual editor)
Just go to the GameScene.sks file (not swift) in you project where you can change the scene size in the inspector on the right.
You can check this article here where they show this if you scroll down a tiny bit. Its a good tutorial you should ready if you plan on working with the visual editor.
https://www.raywenderlich.com/118225/introduction-sprite-kit-scene-editor
2) Not using .sks files, loading scenes in code
If you dont use .sks files you can delete the GameScene.sks file and load the scene like so.
override func viewDidLoad() {
super.viewDidLoad()
// Configure the view.
guard let skView = self.view as? SKView else { return }
let scene = GameScene(size: CGSize(width: 1920, height: 1080))
skView.showsFPS = true
skView.showsNodeCount = true
/* Sprite Kit applies additional optimizations to improve rendering performance */
skView.ignoresSiblingOrder = true
scene.scaleMode = .AspectFill
skView.presentScene(scene)
}
Hope this helps
How to make SKScene have fixed width?
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
SpriteKit - Can't understand what size to make background
When dealing with scenes for Sprite Kit, try not to focus on the screen size, because screen size is no longer a factor (now this is not 100% absolute fact, this is a general rule to go by)
Instead, treat your SKScene as if it was a virtual screen. The size of your SKScene is the "resolution" of your SKScene, and the OS will work in the background to figure out how to convert 1 virtual pixel (From here on out we will call point) to screen pixels( referred to here on out as pixels)
Now there is only 1 special case where the OS will change the resolution (scene size) to match the screen, and that is .resizeFill
The other 3 will never change resolution on you.
.aspectFill
and .aspectFit
will ensure that your point to pixel conversion keeps and equal width and height (e.g. 1 point could equal 4x4 pixels) The only difference is .aspectFill
will expand to fill the entire screen, meaning that excess points will be rendered outside the native screen bounds [ so (0,0) may lie 20 pixels left of the left most pixel, thus not being visible] and .aspectFit will fill till it hits a screen border, leaving black bars to fill the unused pixels.
Now .fill
does not keep and equal width and height point to pixel ratio, and in the case of a 4:3 going to a 16:9 screen, you will notice that your point to pixel will be 5:4 because a 16:9 screen is 25% wider than a 4:3. This gets you the fatty effect.
So when dealing with your game you need to figure out the desired effect. If you set your scene size to 1024x768, then all non retina iPads will have a 1:1 pixel to point ratio, where retina has 2:1 pixels to point ratio. For an iphone 5, you would get roughly 1.14 pixels to every point (iphone is 1168 and your scene is 1024, so you do 1168/1024) then of the 768, you would be loosing 25%, because the ipad is 25% taller than an iphone in landscape. This means only 576 points will be showing, and the rest are in invisible screen space.
Basically, you can never get a 1:1 with both an iPad and an iPhone doing a universal app because you are working with 2 different aspect ratios. You are going to have to make 2 different sets of assets, or take some creative liberties that doesn't alter the gaming experience. This depends entirely on the game and unfortunately nobody will be able to answer it till they have an understanding of your game.
How do I size sprites in a universal sprite kit game
What we usually do in SpriteKt is to give the SKScene a fixed size and let SpriteKit do the scaling for you on different devices.
So basically we 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 have/show some extra background at the top/bottom (landscape) or left/right (portrait) on iPads which gets cropped on iPhones.
Examples of games that show more on iPads / crop on iPhones:
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.
You would use the Universal asset slot and/or device specific images. This way you will have a consistent experience on all devices
Spritekit scale full game to iPad
How to make SKScene have fixed width?
Hope this helps
Sprite Kit Scene Editor GameScene.sks scene width and height
Pixel density
First of all the size of the Scene is defined in Points
not Pixels
.
Let's see how the devices that support iOS 9 deal with this:
- 1 point = 1x1 pixel: iPad 2, iPad mini
- 1 point = 2x2 pixels: iPhone 4s, iPhone 5, iPhone 5c, iPhone 5s, iPhone 6, iPhone 6s, iPad mini 2, iPad mini 3, iPad mini 4, iPad 3,
iPad 4, iPad Air, iPad Air 2, iPad Pro, iPod touch 5, iPod touch 6- 1 point = 3x3 pixels: iPhone 6 Plus, iPhone 6s Plus
This allow you to specify a size that is automatically converted for the pixel density of a particular device.
Screen size
There are several screen sizes available on the iPhone/iPad supported by iOS 9.
With SpriteKit you can easily face this problem setting the scaleMode
property of your Scene
.
You can chose among 4 options:
- Fill: Scale the SKScene to fill the entire SKView.
- AspectFill: Scale the SKScene to fill the SKView while preserving the scene's aspect ratio. Some cropping may occur if the view has a
different aspect ratio.- AspectFit: Scale the SKScene to fit within the SKView while preserving the scene's aspect ratio. Some letterboxing may occur if
the view has a different aspect ratio.- ResizeFill: Modify the SKScene's actual size to exactly match the SKView.
You probably want to set AspectFill
but it really depends on your game.
To set the property open GameViewController.swift
(or .m
if you use Objective-C), in viewDidLoad
you'll find this line. Just change it to mach your preference.
/* Set the scale mode to scale to fit the window */
gameScene.scaleMode = .AspectFill
How to get the proper dimensions of the scene
Use self.view.bounds
to get the size of the screen (assuming your view is fullscreen)
The view shows a portion of your scene. You can move the view around the scene to scroll your game. Therefore the scene dimensions are different than the screen dimensions.
Related Topics
Fibonacci Calculator Stack Overflows at 93Nd Number in Swift
How to Upload Zip Data with Alamofire
Read Data Firebase Assign Value
Firebase Observe Called After Following Command
Implicit Return in a Closure Causing an Error
How to Add Kerning to a Textfield in Swiftui
Call Completion Block When Two Other Completion Blocks Have Been Called
Declaration Is Only Valid at File Scope (Extension)
Swift: How to Delete Part of Audio
Beginner Swift Sprite Kit - Node Collision Detection Help (Skphysicscontact)
Swift Http Request Use Urlsession
Compare Textfield.Text to Firebase String Swift
Lazy Loading Properties in Swift
Today Extension Failed to Inherit Coremedia Permissions From
How to Convert PDF to Png Efficiently
"Unrecognized Selector Sent to Instance" in Swift
How to Include Assets/Resources in a Swift Package Manager Library