Drawing a Minimap

Heads-up - This is a C# game using XNA for a college project, hence the subforum

tl’dr at bottom

So I am having a little trouble at the moment with my minimap, not so much it working but it causing frame rate issues. The issues with the frame rate is already apparent as we are rendering everything at once.

We have a tile system for our map and the size starts at 160x90 tiles, with 2 layers so that is 28,800 tiles being rendered. Like I have said, it’s not optimized yet and culling and chunk system will be added with the next update.

Now if I go onto the medium map, which is 320x180 (115,200 tiles) the frame rate drops. If I render the mini-map it REALLY drops.

The way the mini-map is created is simply give it a new camera and spritebatch, the camera is basically just a tiny little version of the world camera with the render holding all the same data.

This means the mini-map is rendering 115,200 tiles and the world is as well.

The whole “just use a small camera and render your map in it” approach seemed logical but I could see it going tits up when big maps are loaded.

Now I can see that if we culled and drew only the tiles visible inside the camera bounds, we would be rendering (with default zoom) 40x23 tiles which is only 920 tiles, which is fine. However that mini-map is still drawing a whopping 57,600 tiles.

What other way could I do this?

A few requirements for the mini-map:

  • Must show the whole map
  • Must show stationary entities (buildings, walls)

These 2 requirements literally throw the entire “just use a shader and color each pixel to that of the terrain type (grass green, blue water etc)”.

What other methods can I do? Should I just forget those requirements and re-discuss the approach with the group?

tl;dr My mini-map lags my game as it is drawing everything over again, what do?

Why don’t you just create another view?

Presumably, currently every tile Object contains an image to be drawn. You then draw that image twice- once at full size, and once at tiny size.

Why not have each tile Object contain another tiny image (or color) that you then draw to the minimap?

Alternatively: base the tiny image off of the full image, but cache the result instead of redrawing it every single frame.

Do you mean another camera with a different projection? That is what I am already doing unless you mean something different.

I know the tiny image way would really increase performance but that means we start diluting the classes with extra data that imo, should not be necessary.

The color option is what I thought would be the next step but then I thought, it would look a bit weird having 1 pixel represent a building that takes up an entire cell and then a unit sitting next to it that also takes up an entire cell, then if we have a group of say 100 units all around each other it would populate the map to the point it looks a little eh, weird.

Do you mean essentially take the pixel information of the finished batch call and store it somehow? I have no idea how to do that lol.

Do you really have to draw everything on the minimap all the time? Will the terrain be changed often? Draw the terrain on an image, used that as background, on that add the rest of the stuff. Only draw a new image of the terrain when the terrain has changed.

No, that’s not what I mean. I’m talking about creating your mini-map without using your full-sized images directly.

I would argue that this data is necessary, but you don’t really need to add anything new. Just cache the resized images used for the mini-map instead of recalculating them every frame.

It doesn’t really have to be that fancy. Just store the small images to be used by the mini-map. Whether you do them by hand ahead of time or try to calculate them when you load the full-sized image is up to you.

This is a old wiki for libGDX, but maybe can help you with some ideas:
https://code.google.com/p/libgdx-users/wiki/Minimap

Basically is a new camera with a new batch with small size. You draw only the objects you want (such as player, some maze walls) but not the same sprite, you draw pixel points/shapes or any texture to simulate the real size.

Why not temporarily store the data you have from your map rendering spritebatch and just shrink it instead of making a new camera. Or come up with some convoluted algorithm that determines which tiles will even be visible as pixels of course that means iterating through either 118000 tiles or performing width*height in pixels of the minimap converting each pixel into a world coordinate based upon the current position of the player and then specifically selecting the data from those tiles and binding it to a new sprite batcher which you then render on top of the current view . BREATHES