Ethanon Engine games aim multiple platforms, from smartphones and tablets to desktop. For that reason, games should be able to run on an infinity of screen resolutions and aspects.
By default, Ethanon uses one-by-one pixel scale over scene sizes. For example, if we're running our game on 1280 x 720
pixels resolution window, an entity which is 360
pixels tall will fill half of screen height by default.
If the entity mentioned above is really supposed to have half the size of the screen height, and were only running the game on that 1280 x 720
pixels window, we're fine. But what if we want that 360
pixels tall entity to always fill half of any screen, no matter what that resolution it is?
Well, its easy, we could simply get the actual screen height and do some math to find how much we should scale that entity in scene, in order to make it fill the exact amount of space we're expecting as if the screen size was 1280 x 720
.
Easy, right? Actually, not so much. Scaling it manually will force us to scale every entity in scene using the same scale factor, and not only their sizes but also their actual position in space, since it must expand the entire scene. Not to mention their motion events should also consider a different scale.
The native global scaling system in Ethanon Engine helps us determine how much the entire scene should be scaled to fit that 1280 x 720
screen (or whatever the user chooses as best resolution) and also automatically scales every scene loaded, and entities dynamically added, as well as every motion procedure including physics simulation.
All we need to do is choose a best screen height and the engine will automatically set a new scale factor. Setting the best screen resolution is easy:
void main() { SetFixedHeight(720); LoadScene("scenes/my_scene.esc"); print("The new scale factor is: " + GetScale()); }
The sample above sets the global scale factor to screenHeight / 720
. By doing that, the engine will automatically scale every entity added after the call using that scale factor. For example, if our 360
pixels tall entity is in a screen size which is 480
pixels tall, its in-scene height will now be 240
(half of 480).
It is recommended to set global scaling factor inside the main
function and before loading the first scene. Once the fixed global scale factor is set, it doesn't need to be set again, it persists as long as the application is running and will be applied to every scene and every entity.
All AddEntity
functions will automatically scale entities according to the global scale factor before adding them to scene.
Operations such as AddToCameraPos
, ETHEntity::AddToPosition
, SetGravity
, ETHPhysicsController::SetLinearVelocity
, among other relative positioning methods, will automatically consider the global scale factor, so the programmer shouldn't worry about that while programming the gameplay.
Warning! Operations involving absolute position coordinates, such as ETHEntity::SetPosition
or SetCameraPos
won't scale position values passed as parameter, that is to say that the global scaling system will only automatically scale relative positioning operations, and scenes do get larger or smaller depending on the scale factor.
To-do: cover automatic rescaling from v0.9.6 and above...
With the global scaling system, developers may choose a best screen resolution and compose scenes as if the game would always run on that specific screen, and the global scaling system will help making sure the game will run seamlessly on different screen sizes and aspects.
Optionally, we may use screen width to compute global scale factor with SetFixedWidth
function instead, which may work better on games that run on portrait mode. Check the API Reference pages for more Global scaling utility functions.
The global scaling system won't scale sprites and text drawing operations, because sometimes we do not want our UI being scaled the same way the game scene is. If you want to scale sprites with the global scale system, you can do something like this:
void drawScaledSprite(string name, vector2 pos) { const vector2 size(GetFrameSize(name) * GetScale()); DrawShapedSprite(name, pos, size, 0xFFFFFFFF); }