2
\$\begingroup\$

I'm making a top-down strategy game so I thought a minimap is a must. I'm using Scene2D to display my GUI and since the minimap is technically a part of the GUI, I used the stage camera to position the minimap. Below is how I'm rendering the minimap.

    shape.setProjectionMatrix (stage.getCamera ().combined);
    shape.begin (ShapeType.Filled);
    shape.setColor (Color.CYAN);
    shape.rect ((Constants.RENDER_WIDTH - 500) + ship.getX () / 30, ship.getY () / 30, 5, 5);
    shape.end ();

    shape.setProjectionMatrix (stage.getCamera ().combined);
    shape.begin (ShapeType.Line);
    shape.setColor (Color.YELLOW);
    shape.rect (Constants.RENDER_WIDTH - 500, 0, 500, 500);
    shape.setColor (Color.WHITE);
    shape.rect ((Constants.RENDER_WIDTH - 500) + (camera.position.x) / 30, (camera.position.y - camera.viewportHeight / 2) / 30, Constants.RENDER_WIDTH / 30, Constants.RENDER_HEIGHT / 30);
    shape.end ();

The first ShapeRenderer (shape) call renders the ship marker, which is currently a small square. The second renders the bounds of the minimap which is 500x500. RENDER_WIDTH and RENDER_HEIGHT are the width and height that I'm plugging into camera as viewport dimensions (1920x1080). The map is 15000x15000, so I'm dividing the ship location by 30 so that it is always in the range of 0-500. However, when I move the camera around I actually end up being able to see the ship before the minimap says I should, which is illustrated below. I'm fairly certain it's due to the zoom level of the camera, but I haven't figured out how to incorporate that other than multiplying the width and height of the display of where the camera is (the white box), by the current zoom level, which didn't work.

The white box is the visual representation of the camera at it's default zoom level (zoomed out), and the yellow box is the bounds of the map divided by 30, so 500x500. The cyan square is the ship, but as you can see I shouldn't be able to see it.

\$\endgroup\$
1
\$\begingroup\$

I've managed to get it working by fiddling around and it would seem that this works as I wanted.

   `shape.setColor (Color.WHITE);
    shape.rect ((Constants.RENDER_WIDTH - 500) + (camera.position.x - (camera.viewportWidth * camera.zoom) / 2) / 30, (camera.position.y - (camera.viewportHeight * camera.zoom) / 2) / 30, (Constants.RENDER_WIDTH * camera.zoom) / 30, (Constants.RENDER_HEIGHT * camera.zoom) / 30)`
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ That's is pretty much what I did but again you are posting a unreadable long line of code. You added another division to x and y to get the camera in place. Kinda hard for me to debug without the code ;). I again strongly advice you to break code down like I did and you will fix this in minutes or less by keeping things clear and easy to alter/tweak. \$\endgroup\$ – Madmenyo Jul 20 '15 at 19:53
  • \$\begingroup\$ I can understand that. The code that I posted will eventually be cleaned up when I actually implement the GUI aspect of the minimap, instead of being the testing nonsense I have now. :) \$\endgroup\$ – AerospaceP Jul 21 '15 at 6:22
0
\$\begingroup\$

Well if you are incorporating zoom with your camera you have to multiple the rectangle by that. It also depends from where the camera actually zooms, I believe this is the center of the camera but it might be bottom left too.

Something like this should leave you with the correct rectangle size.

shape.rect ((Constants.RENDER_WIDTH - 500) + (camera.position.x) / 30,
   (camera.position.y - camera.viewportHeight / 2) / 30,
   Constants.RENDER_WIDTH / (30 * zoom), Constants.RENDER_HEIGHT / (30 * zoom));

You might need to reposition the rectangle by half the size to get centered properly. I advice you to deconstruct that long overload with formula's into something simpler.

Rectangle miniMap = new Rectangle(); //Here you create the minimap rectangle so you have access to it's numbers.
Rectangle miniCam = new Rectangle(); //

//First we set it's width so we have access to it when we want to position the camera.

miniCam.setWidth((minimap.getWidth() / 30) * zoom); //First get the normal miniCam size only then we should multiply it by zoom.
miniCam.setHeight((minimap.getHeight() / 30) * zoom);

minicam.setX(miniMap.x + (camera.position.x / 30) - (miniCam.getWidth() / 2);
// (miniCam.getWidth() / 2) to center it
minicam.setY(miniMap.y + (camera.position.y / 30) - (miniCam.getHeight() / 2);

Now draw your rectangle with it. Using this method makes it easier for you but especially other to read your code and see what is going on. It helps breaking down the problem to smaller bits.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ That actually made the white rectangle smaller when I am zoomed out (it should get bigger as I'm viewing more of the map). If you read above I tried multiplying by zoom and that didn't work as it made the minimap camera too big so the ship marker wasn't positioned correctly because of that. \$\endgroup\$ – AerospaceP Jul 20 '15 at 3:08
  • \$\begingroup\$ Yes I see my mistake. miniCam.setWidth ((miniMap.getWidth() / 30) * zoom) should be good. I was dividing by (30 * zoom) so when the cam gets farther away and get a higher zoom it shrank the rectangle. The zoom division just need to come last. I fix my answer. \$\endgroup\$ – Madmenyo Jul 20 '15 at 9:06
  • \$\begingroup\$ @AerospaceP as you can see in the comment behind the line we could have avoid this mistake by breaking down the code even more. \$\endgroup\$ – Madmenyo Jul 20 '15 at 9:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.