Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SpriteKit : Keep consistent sizes and speeds across devices

TL;DR : I want to find a method to give an impulse to an object so that the speed of this object is precisely proportional to the scene size.

I am currently building a SpriteKit game that will be available on many different screen sizes, my scene resizes itself to be the same size in points as its view (scene.scaleMode = .ResizeFill), when I launched my game on other devices than the one which I had developed it, I noticed that :

  • The size of nodes was too small

  • The speed of the objects was too low (the way I give speed to my objects is by calling applyImpulse(:_) on their physics body).

I think I fixed the size issue with a simple proportionality operation : I looked at the objectArea/sceneArea ratio of the scene that had the correct object size and than, instead of giving fixed dimensions to my objects, I simply gave them dimensions so that the ratio is always the same regardless of the scene area.

For the object speed, it was trickier...
I first thought it was due to the physics body mass being higher since the object itself was bigger, but since I attributed to objects their mass directly via their mass property, the objects would have the exact same mass regardless of their size.

I finally figured out that it was just due to the screen size being different therefore, an object, even by moving at the same speed, would seem to move slower on a bigger screen.

My problem is that I don't know exactly how to tune the strength of my impulse so that it is consistent across different scene sizes, my current approach is this one :

force = sqrt(area) * k

Where k is also a proportionality coefficient, I couldn't do the proportionality on the area, otherwise, speed would have grown exponentially (so I did it with the square root of the area instead).

While this approach works, I only found this way of calculating it with my intuition. While I know that objects areas are correctly proportional to the scene size, I can't really know if the speed can be considered as equivalent on all screen sizes

Do you know what I should do to ensure that the speed will always be equivalent on all devices ?

like image 321
Pop Flamingo Avatar asked Aug 29 '16 21:08

Pop Flamingo


1 Answers

Don't do it

Changing the physics world in relation of the screen of the device is wrong.

The physics world should be absolutely agnostic about its graphics representation. And definitively it should have the same properties (size, mass, distance, ...) regardless of the screen.

I understand you don't want the scene to be smaller of the screen when the game runs on a iPad Pro instead of an iPhone 5 but you need to solve this problem in another way.

I suggest you to try another scaleMode like aspectFill (capitalized if you're on Xcode 7: AspectFill). This way the scene is zoomed and all your sprites will appear bigger.


Another point of view

In the comments below @Knight0fDragon pointed out some scenarios where you might actually want to make some properties of the Physics World depending on the UI. I suggest the reader of this answer to take a look at the comments below for a point of view different from mine.

like image 175
Luca Angeletti Avatar answered Nov 03 '22 00:11

Luca Angeletti