Handling different screen resolutions with global scale

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.

Global scaling system

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.

Choosing the best screen size

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.

Moving entities in a scaled 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.

Handling screen resizes

To-do: cover automatic rescaling from v0.9.6 and above...

Final considerations

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.

Scaling sprites and texts

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);
}