iOS Universal Device App with SpriteKit, how to scale nodes for all views?
I initially tried to do the scaling myself with 2 games and it was just madness (scene size = view size or scene scale mode = .ResizeFill). You have to adjust all values e.g font size, sprite sizes, impulses etc for all devices and it will never be consistent.
So you have 2 options basically
1) Set scene size to 1024X768 (landscape) or 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 (7501334-Portait, 1337750-Landscape). This setting will crop your game on iPads.
Examples of games that show less on iPads:
Lumino City, Robot Unicorn Attack
Chosing between the 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.
To adjust specific things such as labels etc you can do it this way
if UIDevice.current.userInterfaceIdiom == .pad {
...
}
You can try the scene scaling yourself, create a new SpriteKit sample game project. Run on all iPhones and you will notice the HelloWorld label looks perfect on all devices.
Now change the default settings to scene size = frame or use .ResizeFill, the HelloWorld label is not scaled properly anymore on all devices.
As a side note, the line
if let scene = GameScene(fileNamed: "GameScene")
references the GameScene.sks file. You said you do everything programatically, therefore you can probably delete the GameScene.sks file and change the line to
let skView = view as! SKView!
let scene = GameScene(size: CGSize(width: 1024, height: 768)) // 768 x 1024 if portrait
Update:
I am now using a slightly different variant as I had problems adapting my game to iPhoneX. I set scene size to 1334x750 and use aspect fit as scale mode. I than run some code to remove the black bars if needed e.g. on iPads or iPhone X. It’s based on this great article (link no longer works).
http://endlesswavesoftware.com/blog/spritekit-skscene-scalemode/
How to scale/position nodes Swift SpriteKit? Custom View?
To keep my games universal I make all my node
s sizes and positions dependant on SKScene
size
Instead of using hardcoded numbers try using proportions from your SKScene
size. For example:
Instead of writing this:
node.position = CGPointMake(100, 100)
Write somthing like this:
node.position = CGPointMake(world.frame.size.width / 32 * 16, world.frame.size.height / 18 * 9)
world -
SKNode
of exactly same size as yourSKScene
Same for sizes
let blackSquare = SKSpriteNode(texture: nil, color: UIColor.blackColor(), size: CGSizeMake(world.frame.size.width / 32, world.frame.size.width / 32))
Also GameViewController
should look something like this:
override func viewDidLoad() {
super.viewDidLoad()
// Configure the view
let skView = view as! SKView
skView.multipleTouchEnabled = false
// Create and configure the scene
let scene = GameScene(size: skView.bounds.size)
scene.scaleMode = .AspectFill
scene.size = skView.bounds.size
skView.presentScene(scene);
}
Was this helpfull?
Universal app background SpriteKit
The devices's screen size ratios are different, and one will have to stretch dimensions to fit the screen, and this may look weird. But you can use .Fill if you are sure you like this option. The smoothest alternative is to remain using .AspectFill and create an image for each screen dimension. Be creative! Good luck!
SkSpriteNode position in universal game
How can I set SkSpriteNode's position relative to visible area, so
that it'll be for example 50x50 from the corner on every device?
The "visible area" is simply the view.
So you can make your positions relative to the view, and not the scene. I actually do this a lot in my game, which is universal and runs on both OS X and iOS.
In my case I typically do this for the user-interface, so I might have a scaled scene but I want to set some positions not relative to the scaled scene but relative to the visible area (i.e. the view).
To do this, you can write a function that converts view coordinates to the corresponding scene coordinates.
Here is my function that I use. Note that I subtract my desired y-position from height of view so that I can treat (0,0) as the bottom-left like sprite-kit does instead of the top-left like UIKit does.
func convert(point: CGPoint)->CGPoint {
return self.view!.convert(CGPoint(x: point.x, y:self.view!.frame.height-point.y), to: self)
}
Here is an example of using this function:
self.node.position = convert(CGPoint(x: 50, y: 50))
This will always force the position of the node to be at (50,50) relative to the view (the visible portion of the screen) regardless of how your scene is scaled and sized.
iOS SpriteKit Get All nodes in a current scene and make the application universal.
- in Scene.m, you can use
self.children
to get all the SKSprite Nodes - http://www.raywenderlich.com/49695/sprite-kit-tutorial-making-a-universal-app-part-1
Related Topics
Drawing Class Drawing Straight Lines Instead of Curved Lines
Nsurlconnection Sendasynchronousrequest Can't Get Variable Out of Closure
Capturing and Storing a Picture Taken with the Camera into a Local Database/Phonegap/Cordova/Ios
Uidatepicker Select Month and Year
Changing Vc Issue in Swift. How to Pass Data Between Views in Tab Bar Controller
What Is the '' Is or the ':' at the Equation When Coding in Swift
How to Log a Method's Execution Time Exactly in Milliseconds
Custom Installed Font Not Displayed Correctly in Uilabel
Using Multiple Storyboards in iOS
iOS 7 - Difference Between Viewdidload and Viewdidappear
Change Tab Bar Item Selected Color in a Storyboard
Iphone: Hide Uitableview Search Bar by Default
How to Use Avcapturephotooutput
Location Services Not Working in iOS 11
Record and Play Audio Simultaneously
Swift Equivalent to '[Nsdictionary Initwithobjects: Forkeys:]'