LibGDX mouse coordinates after resizing screen

What’s the best way to do this? I’ve read it’s done by converting world coordinates to screen coordinates. I’ve also read you can use camera.unproject(). (I’ll be honest and haven’t tried anything yet, I just wanted to have something to go off of when I get off work). I want to try the camera.unproject method. Does this method go into the resize() method in LibGDX? Or do I call unproject when the mouse actually clicks if the game is full screen?

Basically, the problem is my screen size is set for Android-like, and I have an inventory screen where you can click on different weapons to select which weapon you want to use. But if the screen is resized, this all breaks and you can’t click on anything to select inventory (not even where the original coordinates started…so basically if you resize the screen to full screen and click on where the inventory should be before resizing, that doesn’t work either) Is there something I’m missing? Thanks and have a good day :slight_smile:

This stuff is taken directly from my game project and it should work for you and also explain some concepts.

First you need to setup your Camera and Viewport, the Scaling mode is important, read the LibGDX-Wiki and test some Scaling modes yourself to see the difference:

private void setupCamera() {
	
	camera = new OrthographicCamera();
	
	// ww and hw are your world width and height in world units (meters for example!)
	// Read the LibGDX Wiki on viewports and try different types
	viewport = new ScalingViewport(Scaling.fit, Metrics.ww , Metrics.hw, camera);
	
	// [...]
	
}

Then you need to calculate your viewport size, do this in your games resize-method, it is called when needed by LibGDX, read the Wiki if you need to know more:

@Override
public void resize(int width, int height) {
	
	// width and height of the window in pixels
	Metrics.wv = width;
	Metrics.hv = height;
	
	// I want 1:1 texel to pixel mapping on screen for zoom=1.
	// You can choose how much of your world you show here, you could also choose a constant width OR height in meters instead.
	// world width and height in meters
	// window_width_in_pixels * zoom / pixel_per_meter
	Metrics.ww = Metrics.wv * camController.getZoom() / Metrics.ppm;
	// window_height_in_pixels * zoom / pixel_per_meter
	Metrics.hw = Metrics.hv * camController.getZoom() / Metrics.ppm;
	
	// World viewport uses world coordinates (meters) so we pass ww (WidthWorld) and hw (HeightWorld).
	viewport.setWorldSize(Metrics.ww , Metrics.hw);
	// Always input your screen width and height
	viewport.update(Metrics.wv, Metrics.hv, true);
	
	// My stage on the other hand uses pixel coordinates so i pass wv (WidthView) and hv (HeightView).
	stage.getViewport().setWorldSize(Metrics.wv, Metrics.hv);
	// Always input your screen width and height
	stage.getViewport().update(Metrics.wv, Metrics.hv, true);
}

Now the fun part, getting the position in world coordinates where the mouse pointer is:

// v get's overwritten and returned
public static Vector3 mousePositionInWorld(Vector3 v, Camera camera) {

	v.set(Gdx.input.getX(), Gdx.input.getY(), 0f);
	camera.unproject(v);

	return v;
}

Getting the screen-position in pixels from a point in your game world:

// v should contain the world position you want to convert
public static Vector3 worldToScreenPosition(Vector3 v, Camera camera) {

	camera.project(v);

	return v;
}

The most important step is to always update your viewport! This works irrespective of screen size, fullscreen or not.

1 Like

Ok thanks! I’ll try some of this out and see what’s up. Thanks man! I thought it would be easier than this lol. I.E. just resize the window and it works. Definitely not the case here.

[quote]just resize the window and it works. Definitely not the case here.
[/quote]
Errmm … it actually is that simple, you just resize and update your viewport in that resize method that gets called automagically and you’re set :smiley:

This is the super condensed version:

@Override
public void resize(int width, int height) {
    // Viewport => How much of your world you want to display in the window.
    // You basically use this to adjust after a resize and for zooming in/out. This has no effect on the camera position/rotation.
    viewport.setWorldSize(viewportWidthInWorldUnits , viewportHeightInWorldUnits);
    viewport.update(width, height, true);
}

That’s literally it. Don’t forget to set your sprite sizes in world units though, that’s another easy mistake.