phaser icon indicating copy to clipboard operation
phaser copied to clipboard

Device dimensions currently affect the final position of parallax tileset layer (setScrollFactor)

Open Dercetech opened this issue 3 years ago • 5 comments

Version

  • Phaser Version: 3.55.2 (tested with 3.24 too, before the Static & Dynamic layers were merged)

  • Operating system: W10, MacOs Montery

  • Browser: Reproduced on Brave, Chrome, Safari.

Description

When creating parallax layers from a tilemap, the setScrollFactor value is used in conjuction with the main.camera's scrollX value in order to determine the parallax layer's offset. The result is that a same tilemap will have its parallax layers move slower on a wide screen than on a narrow screen. It's thus impossible to safely create cross-device parallax experiences based on a tilemap.

See illustrations in forum forum post

Example Test Code

See https://github.com/Dercetech/phaser-355-broken-parallax, the README.md has the instructions.

With 320px wide, move the "frog" right until it faces the FG5 block (50th foreground tile). Here, you notice both midground 3 (MG3) and background 2 (BG3) are perfectly aligned: image

Now, modifying the game config in src/main.ts, use 512px width: image The midground and background are no longer aligned in spite of the camera being centered on the same midpoint (square: FG5). Midground and background are lagging behind: larger screens have lower scrollX due to being "closer" to the world origin for the given midpoint. This is to be expected since the scrollX value of the camera is used to compute the parallax background offsets.

Additional Information

The main.camera's midpoint should be used to synchronize all the layers that have a scroll factor. Only the non-parallax one should use the existing behavior. A basic but effective approach is to instruct Phaser to align all layers via their center.

The best scenario would be to define a per parallax layer focal point. Out of scope as we're discussing a bug, not a feature request.

Dercetech avatar Jun 03 '22 20:06 Dercetech

This issue has been mentioned on Phaser. There might be relevant details there:

https://phaser.discourse.group/t/screen-size-affects-scrollfactor-bug-or-expected-behavior/11802/1

photonstorm avatar Jun 03 '22 20:06 photonstorm

Hi @photonstorm, indeed it's my original post. Since it appears to be a problem I decided to report it here.

Dercetech avatar Jun 03 '22 20:06 Dercetech

Hi @photonstorm, indeed it's my original post. Since it appears to be a problem I decided to report it here.

Those messages are auto-posted by Discourse, I don't create them manually.

photonstorm avatar Jun 06 '22 21:06 photonstorm

I just found out that Tiled supports a global map property Parallax Origin (Xand Y). I guess this issue could be solved by adding an optional parameter parallaxOrigin without breaking the current behaviour.

Edit: Obviouly one could also workaround this by adding an x and y offset to objects depending on the games resolution.

tobx avatar Jun 13 '23 07:06 tobx

@Dercetech I played around with your example. The issue is that the camera does not start scrolling before the player reaches the center of the screen. This is by design.

If you want to support different viewport sizes, then this can easily be fixed with the offsetX and offsetY arguments of the startFollow function:

Instead of:

this.cameras.main.startFollow(this._player);

use:

this.cameras.main.startFollow(this._player, undefined, undefined, undefined, (320 - this.cameras.main.width) / 2, 0);

Then 320px is your "main" width while the others adopt to it.

tobx avatar Jun 13 '23 19:06 tobx