Sunday, July 20, 2014

HaxeFlixel scale modes: complete guide pt. 2: auto-zoom

Part 1: Zoom set to 1

When I started testing the various scale modes available in HaxeFlixel several days ago, I quickly found out that pretty much none of them work as I'd expect. Fortunately, it didn't take long for me to figure out, that it's caused by the automatic zoom calculation that's included in the template, and not by scale modes themself. I mean this:
Both screenshots show the same device and the same code.
So what happened here?

This is the culprit:

if (zoom == -1)
{
var ratioX:Float = stageWidth / gameWidth;
var ratioY:Float = stageHeight / gameHeight;
zoom = Math.min(ratioX, ratioY);
gameWidth = Math.ceil(stageWidth / zoom);
gameHeight = Math.ceil(stageHeight / zoom);
}

So when you set the zoom to -1, the template will recalculate not only the zoom factor, but also your gameWidth and gameHeight. Which leads to a disaster, as those values are used to determine the size of your assets in relation to the game area. So, for example, if you design for 320x480 and prepare a background that nicely fills that 320 px width, you will find out that after launching your game in a different than intended aspect ratio (for example, in landscape rather than portrait orientation), your gameWidth might suddenly become, for example, 100 px, and now the engine "thinks" that it's supposed to fit the 320 pixels wide background not on one, but on over 3 screens.

It might be a good thing for some games, but I'd guess it's bad for most. But perhaps my biggest complaint is that it leads to horribly unpredictable and inconsistent behavior - a game launched in portrait mode and then switched to landscape will look differently than a game launched in landscape and then switched to portrait. More examples below.

Test setup

This is my design resolution.
How does it look on other screens?
Like before, my "test screen" is designed with 320x480 pixels in mind and will be tested in the following starting resolutions (like if the game was launched with this resolution):
  • 640x960 pixels - iPhone 4,
  • 640x1136 pixels - iPhone 5,
  • 960x640 pixels - iPhone 4 in landscape orientation,
  • 768x1024 pixels - non-retina iPad & other tablets
In addition, I'll showcase the following in order to justify saying that zoom = -1 is a trap:
  • Portrait > Lanscape - started in 640x960 px, then rotated to 960x640 px,
  • Landscape > Portrait - started in 960x640 px, then rotated to 640x960 px.
I started from a default HaxeFlixel project template. In my Main.hx, I changed my gameWidth and gameHeight
to 320 and 480, respectively. This is my design resolution. To test different actual resolutions, I modified my Project.xml's <window> tag and/or resized windows on the fly.

My only game state consists of a red background covered by a static 320x480 image (blue). In my design resolution, the background is not visible at all, but in certain scaling modes, it will show up, marking the difference between inaccessible, off-game area (= black bars) and areas that are within the game bounds, just not covered by my image (= red background).

Note 1: As of the time of writing this post and version 3.3.4 of HaxeFlixel, you need the development branch to even think about Scale Modes in the fledgling HTML5 target. A few days ago they simply wouldn't work at all, in the next version, they should be integrated with the master branch and the world will be a better place. What a glorious time to be alive!

Note 2: As mentioned, I found several inconsistencies between Scale Mode behavior on different target platforms. I'll explain them in detail in the following parts of this guide.

Note 3: Don't look at resolutions (they are resized for easier viewing), even though I mention them every now and then. It's the aspect ratios that matter.

Zoom = -1

In this test, I left the default setting of zoom = -1 (in Main.hx).

Click on a thumbnail to change the Scale Mode:

Click in the table below to change resolutions. Make sure to compare "Landscape" with "Portrait -> Landscape" and "Portrait" with "Landscape -> Portrait"!
640x960
(Port)
960x640
(Land)
640x1136 768x1024 Port ->
Land
Land ->
Port

Next


My plan for the next part(s) is to review each Scale Mode individually, focusing on glitches (especially in the HTML5 department), caveats and use cases. Knowing my luck, by the time this guide is finished, it will be outdated, but it's a good thing! It means that HaxeFlixel is improving (and it is, constantly).

I'll post a link as soon as I finish part 3. In the meantime, make sure you read part 1, which shows all the scale modes in action (and working properly!).

2 comments:

  1. Hi, thanks for your tutorial. Waiting for your part 3 of this! :-)

    ReplyDelete
  2. Did Part 3 get outdated before it was published? ;)

    I wonder what your opinion is on https://github.com/player-03/advanced-layout

    ReplyDelete