Minimap not so mini

Started by
5 comments, last by Cannon 22 years, 9 months ago
The heading of this post pretty much says it all. I''ve created my minimap using 1x4 pixel images to represent each tile. I believe this is how it is done in TANSTAAFL''s book too. Anyhow, with a 200x200 map, I end up getting a minimap that fills my screen. I''m trying to figure out a way to shrink the minimap so that i can show it in its entirety while still reserving a tigers share of the screen for gameplay. One solution I can think of is to just keep a copy of the minimap in the background, and then just blit it to the screen and let the blit function do the compression for me. But I''m afraid this may lead to some distortion of the data displayed by the minimap. Any suggestions? Thanks
Advertisement
Yes I tried allowing ddraw to resize and the results were poor. In the end I took a screenshot including the poor map, cut the map out, gave it a by hand touch up in paint and kept it as a separate bitmap. This is fine if you have static maps. If you have random map generation going you''ll need to devise some sort of algo to smooth things up I suppose.

El Duderino
I use one pixel per tile which actually looks quite nice. When the user wants to see the minimap the map array is scanned and rendered to a small offscreen surface. When a floor, wall or object tile is hit, a pixel is rendered to the surface. Until the user closes the minimap the same offscreen surface is used so the minimap doesn''t have to be redrawn every frame.

You may want to just use a scrollable minimap if you want more detail. It''s more complicated but it would look cool. The other option is to allow free scrolling of the main screen and skip the whole minimap.

Ben
http://therabbithole.redback.inficad.com

A scrolling mini-map seems to me to defeat the purpose, which is to (man thats a lot ot tos) give the user feedback on what''s happening on the entire screen. If you have a static map size, it would probably not be too hard figuring out a size (in your case smaller than 4x4) for each cell to take up. If that doesn''t work, you can group a bunch of cells into a single pixel.
This last method would also work for non-static maps. Just scale the number of tiles skipped between pixels according to the mapsize. If you are using alphablending, you could also combine the colors of multiple cells in a single pixel. I don''t know what sort of effect this will give you with thin walls etc, but give it a try.
When the map is created or loaded, I calculate some information about its size and stored it in a structure:
typedef struct MINIMAP_INFO
{
int min_x;
int max_x;
int min_y;
int max_y;

double step;

double x_conversion;
double y_conversion;
} *MINIMAP_INFO_PTR;

Then I calculate:

MINIMAP_INFO mm_info;

if(map.width > map.height)
{
mm_info.min_x = 0;
mm_info.max_x = 160;

mm_info.min_y = 80 - 80 * map.height / map.width;
mm_info.max_y = 160 - mm_info.min_y;

mm_info.step = (double)map.width / 160;
}
else
{
mm_info.min_x = 80 - 80 * map.width / map.height;
mm_info.max_x = 160 - mm_info.min_x;

mm_info.min_y = 0;
mm_info.max_y = 160;

mm_info.step = (double)map.height / 160;
}

Basically, the rectangle (min_x, min_y)-(max_x, max_y) defines the area to draw (for non-square maps), and in this case, the minimap is to be drawn in a 160x160 area. step says how many tiles to skip between pixels on the minimap. Then, for the rendering function (which assumes that the back buffer is locked):

for(int y = mm_info.min_y; y < mm_info.max_y; y++)
{
for(int x = mm_info.min_x; x < mm_info.max_x; x++)
{
int x_pos = (int)((x - mm_info.min_x) * mm_info.step);
int y_pos = (int)((y - mm_info.min_y) * mm_info.step);

UCHAR color = terrain_colors[map.data[x + y * map.width].terrain];
// (minimap_x, minimap_y) is the upper-left corner of the place to draw the minimap
back_buffer[(x + minimap_x) + (y + minimap_y) * back_lpitch] = color;
}
}

Node *ulist_start, *ulist_end;

ulist_start = level.units.getFirst();
ulist_end = level.units.getLast();

// process units for minimap
for( ; ulist_start != ulist_end; ulist_start = ulist_start->next)
{
int x = (int)(ulist_start->data.x / mm_info.step + mm_info.min_x + minimap_x);
int y = (int)(ulist_start->data.y / mm_info.step + mm_info.min_y + minimap_y);

UCHAR color = player_colors[ulist_start->data.player];

back_buffer[x + y * back_lpitch] = color;
}

And that works for me. The only problem I''ve noticed is that depending on their position, tiles can sometimes be 1x1, 1x2, 2x1, or 2x2 on the minimap and it looks slightly distorted. terrain_colors[256] is the color to plot each terrain type, and player_colors[8] is the color of each players'' units.
so, you have a 200x200 map, diamond shaped i assume, which gives you a 800x400 minimap.

here''s a thought:

why not approximate your 200x200 map with a 100x100 map or a 50x50 map? in this situation, one of the minimap tiles would represent several (either 4 or 16) tiles in the actual map. a mini-maps purpose is not to be exact anyway, just to give a general idea of where action is happening.

Get off my lawn!

quote:
why not approximate your 200x200 map with a 100x100 map or a 50x50 map? in this situation, one of the minimap tiles would represent several (either 4 or 16) tiles in the actual map. a mini-maps purpose is not to be exact anyway, just to give a general idea of where action is happening.


That''s what I''m thinking too.
This would also work on dynamic maps.

You could:

1) Create the map (static or dynamic) and grab the size
2) Create your static minimap.
3) Depending on the number of tiles, draw a pixel for x tiles.

For example:

Say the map is 100 tiles wide and the minimap is 100 pixels wide...you could plot one pixel for each tile.
IF the map was 200 tiles wide, then plot a pixel for every two tiles...see what I mean?

-Coleco

~ c o l ec o ~



Rock the cradle of love!
You stupid WANKER!
S i g n a l D E V .com

--HASBRO SUCKS--
Rock the cradle of love! You stupid WANKER!

This topic is closed to new replies.

Advertisement