Advertisement

Province Map

Started by January 07, 2018 04:59 PM
5 comments, last by radek spam 6 years, 10 months ago

Hi,

I would like to create a province map, something like in attached example of Age Of Conquest. I would like to use Libgdx.

After some research i learnt that it can be done by using two images, one with graphics and second invisible with distinct colors to handle clicks.

I have some doubts about this method:

  • how to deal with memory, i have created sample map with size of 960x540 and it weighs 600kb, i would need 10 times bigger map. I could cut it in some smaller pieces and render them but im afraid that it can cause lags when scrolling the map
  • how to deal with highlighting the provinces. I managed to implement simple highlight limited to one province creating filter in OpenGl fragment shader. But what if i want to highlight multiple provinces (eg. highlight all provinces of some country). I guess It can be done by shader too but it may be much complicated
  • i would like to also implement Fog of War over the undiscovered provinces. How one could do that?

I would really appreciate your guidance. Perhaps to create the above map i need some other method?

age.png

As a general rule, don't assume you're having a problem before you have shown that to be the case.

Current memory is counted in GB, 600KB is pretty much nothing, even if you assume it will become 10*10*600K = 60M = 0.06G (which I doubt will actually happen, but ymmv).

 

Secondly, if you look more precise, you will notice there is a lot of repetition at the map, many of the graphics in each country are the same. Instead of replicating those pixels a zillion times, it's much smarter to store that graphic one time, and then render it to the screen multiple times (ie exactly at the positions where you want it). I think you can do that with most of the graphics on top, which will then eliminate the need to have the second image.

Even for the map itself, the colours of each land are quite simple, you can have a small rectangle of it, and draw that rectangle several times until it covers all land. By clipping away the parts of the rectangle that fall outside the country, it looks like the land contains the colour nicely. Speaking of land, you'll want a mask for each country for clipping the rectangles. You can also use that mask for highlighting and possibly fog of war.

Thus rather than having one big map image, build that map from many smaller images that you use multiple times.

Advertisement

Thanks Alberth for help.
Apologies but i'm not quite get the idea of rectangles. How i could achieve arbitrary shape of provinces using rectangles? Could you please elaborate more this solution?

 

 

The core idea is to have 2 layers, one layer is a grid of small rectangles (conceptually covering the entire map, but you likely don't want to fill the entire grid with a single colour of rectangles), and one layer handles the precise shape of a province.

Starting with the first layer, if you cut out a small rectangle from a solidly coloured area, you can see you would get a solidly covered area covering the entire map if you fill the entire grid of rectangles, right?

You can do the same with the countries with diagonal lines. The height has to be exactly right, so the lines properly connect if you put two rectangles under each other. Again, filling the entire grid would then give you an entire map filled with diagonal lines.

This is how you make an (rectangular-ish) area of some colour of arbitrary size, using just a single small rectangle.

 

As for the second layer, instead of the entire map, just fill enough of the grid such that the country with the colour is completely covered. For simplicity, make it a normalt rectangle covering a subset of the grid, just enough to cover the country completely. Each country is then a rectangular image of N x M grid cells, starting at the bottom left with some grid coordinate.

 

To get the real province shape, you need a mask, that only shows the pixels in the above rectangle that are part of the country. It leaves the pixels outside the country unharmed, so they can be used for other countries.

A mask is a transparent/opaque picture that is opaque for pixels in the country and fully transparent for pixels outside the country. (In its simplest form, opaque/transparent pixel can be a single bit, so this picture is really small in size). You add the mask to the rectangles colour, so it becomes opaque colour in the country, and invisible/transparent outside the country.

To a person, it looks like you only coloured the country, and nothing outside it (since the person cannot see the transparent pixels).

 

The simpler but less flexible approach is to combine the rectangles and the mask into a single image. That is, for each country you have a picture of that country, which is fully transparent outside the country. This is less flexible if you need to give a country different colours, eg for highlighting or for hiding. In the sinmpler approach you must make a new image for each country for each colour, in the two layer system, you only need to add a few more small rectangles.

2 hours ago, radek spam said:

How i could achieve arbitrary shape of provinces using rectangles?

I don't believe @Alberth could have explain that better, the problem is that it isn't a very simple thing to do; So I added images to show some details. Sorry I am at work and don't have the time to make it at a great quality.

So I will show you what Alberth said:

First you need what is known as tiling textures, these are the rectangles:

TileTextures.jpg.f90ebec1424fbdf1a6fab996b6e5873e.jpg

The important part is that you can make a larger image from them because they tile.

Next you need a mask, this is the form of your country:

MaskExample.jpg.b2b8173c9424f3fc6e6a22f171e7130f.jpg

It's common for masks to be gray scale or black and white, this saves a lot of data.

The way a mask works is that you will tell your fragment shader to render the grass texture where the white is, because white = (1,1,1) and any number times 1 = it self. Example 0.5 * 1 = 0.5. You can just multiply the color of the texture with the white.

Black = (0,0,0) and Any number times black = 0. Your end result should look like this:

MaskGrassExample.jpg.0baac803edbbb9d18dcbea0ce6d88d14.jpg

Next you tell your fragment shader just to skip all pixels that is Black (0,0,0) and it should render only the grass part.

After rendering the grass part you do the same using your rock texture. Then you render first the rock texture a bit lower and to the left of the image, then you render the grass where you want it.

Click image for full size.

IslandsExplain.jpg.8ef2841e281a7c5623c9b89c25aafda3.jpg

For the edge you just use an edge detect or you can also store it in the mask. Using tiling textures and a mask you can create all the content you need.

 

Thank you @Alberth and  @Scouting Ninja  I will try what you have suggested

 

This topic is closed to new replies.

Advertisement