As you may know when using SpriteKit, applyImpulse
does not work well on all screens.
On an iPhone SE
, my ball moves extremely fast, but on the iPad Pro 2nd gen
the ball goes really slow.
Is there a way I can make this equal on all screens, in comparison to something like the width of the screen?
Say for example, I want my ball to move across the screen in 5 seconds on EVERY device, what formula would I use?
I have tested out the relation between screen sizes and time for my applyImpulse
to make the ball move to the edge of the screen:
Note: Points per second
is calculated by Half screen size
divided by Time to move
. The graph shows that the pixels per second
decreases with a bigger screen size.
How could I change my applyImpulse
to work on all screens? (not including making it specifically for every device, as I want this to be sustainable for the future)
If this is possible, please show a small swift
function, or if this cannot be done, please give me any suggestions (links to docs, forums, etc).
I appreciate any help by anyone.
EDIT: My GameViewController.swift
override for loading the scene:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Layout guides
guide = UIApplication.shared.keyWindow?.safeAreaInsets
if let view = self.view as! SKView? {
// Load scene
let scene = GameScene(size: view.frame.size)
// Set the scale mode to scale to fit the window
scene.scaleMode = .aspectFill
// Set (0, 0) as the centre of the screen
scene.anchorPoint = CGPoint(x: 0.5, y: 0.5)
// Present the scene
view.presentScene(scene)
view.ignoresSiblingOrder = true
view.showsFPS = true
view.showsNodeCount = true
view.showsPhysics = true
}
}
Sprite kit is designed in a way that you only have to create your game once.
The concept of a "Screen" should not really exist, Your scene is your screen, and your screen is just how you are viewing it.
As we discussed in the chat, you wanted to have a play area of 7:9, and you wanted the scene to flush along the sides of it.
To do this, pick a scene size that is taller then wide. I would recommend using 375:812 since that is iPhone X .@1x. Then place a node inside of it at size 375:482 since that is 7:9.
What will happen is on a regular 9:16 device, the top and bottom areas will get cropped, but it will still show the entire playing field since a 9:16 device has a height of 667.
This means 145 points will be cropped vertically from your main playing area.
Now we come across the issue of iPad, where it is fatter than a 9:16 device.
Our visible scene area becomes 375:500, which our play area barely fits into.
We only have 18 points to work with for a hud or what not.
To combat this, we need to go into the storyboard and change the constraints of the view.
We basically need to force the view to not exceed a certain aspect ratio.
By restricting the size the view is allowed to become, we can control how much cropping will happen on an iPad. We can then add another view behind the SKView to control whatever graphics we want the user to see.
We now have the game setup in a way where we can place all of our play area content inside of the 375:482 play area node.
These dimension will carry across all devices, and the hardware will do the scaling for you, meaning you will have less code and less math to do. less code and less math means less chance for bugs to get into your game, plus the game is exactly the same gameplay wise, meaning iPad users do not get an advantage over iPhone users because you gave them a bigger play area.