Screen touch coordinates change when window changes ratio (SOLVED)

Hi all,
Defold noob here developing simple 2D game for Android. It’s a simple catch-them-all game where you have to click on flies as they fly around the screen. I am having problem converting touch coordinates to the GOs coordinates.

I am using the generally recommended procedure where one component tracks all clickable GOs and then selects the GOs that were clicked based on the position, similarly as in this example https://github.com/britzl/publicexamples/tree/master/examples/click_game_object.

This works great when the game window has the ratio specified in the game.project, but if I resize the window (or run on a physical device with different screen ratio) the touch coordinates suddenly do not correspond to the GOs position.

I’ve setup a simple demo to test this problem. I have a sprite whose position I set to the touch coordinates (action.x and action.y). As you can see on the first image below, with the original window ratio it works just fine, the sprite is right behind the cursor.

However, if I change the screen ratio it suddenly breaks, as seen on the images below.


It seems as though the touch coordinates span the whole window but GO’s coordinates remain the same. I’m using use_fixed_fit_projection if that makes any difference.

Any ideas what’s happening here? Am I supposed to check the screen ratio and manually transform the screen coordinates to the GO coordinates?

Strangely, this problem doesn’t appear everywhere, e.g. gui.pick_node works as expected.

Thank you for any help!

Yeah, GUI does that for you but for anything else you’d indeed need to manually transform the screen coordiantes.

I recently posted my solution, but that’s because I like to do things the hard way. It’s probably much better to simply use either RenderCam or Orthographic Camera.

PS, fajn vidět dalšího Čecha!

2 Likes

action.x and action.y are in GUI coordinates. GUI coordinates take the width & height you set in your game.project and stretch them to fit the window, no matter what. If you set it to 800x600 in your game.project, the top right corner of the window will always be (800, 600), no matter what proportion or size the window gets changed to after the game starts.

gui.pick_node works with (and requires) coordinates like this. It’s how the GUI system works, so node positions don’t change completely every time you resize the window.

action.screen_x and action.screen_y are the actual pixel coordinates. These may or may not be easier to work with.

The exact formula for converting from GUI or screen coordinates to GO/“world” coordinates depends on what your camera is doing – what projection you use in your render script. I’m not sure off the top of my head what the formula is for the fixed_fit_projection. If you never move or rotate your camera, you may just need to multiply screen coordinates by the zoom value (you’d probably want to modify the render script a bit to store the zoom value in a module for use outside the render script).

…Yup, it’s not as simple as you would like it to be. :slight_smile: That’s why there are camera extensions to do it for you.

2 Likes

OK, I’ll check the cam extensions if they are easy to switch to, since I have the project nearly finished. If not I’ll play with the transformation. The example from Klear is probably exactly what I need.

Thanks guys!

Using RenderCam and rendercam.screen_to_world_2d solved my problem. Thanks!

1 Like