views:

185

answers:

4

This is a very general question that's not related to a specific language. I'm having this array of int's:

int[100][100] map;

This contains just tile numbers, and is rendered as 256x256 tiles. So it's basically just a tile map or whatever it should be called. Thing is I want to be able to write anything to the map, anywhere, and it should stay there. For example be able to paint on stuff on the ground such as grass, flowers, stones and other stuff making the terrain more varied without having to render each of these sprites a huge number of times every time it renders. But making each tile contain it's own texture to write to would be terribly memory consuming at that would be 256x256x100x100 = 655360000 pixels to store. Would'nt that be like gigabytes of data or something!?

Does anyone know of a good general sulotion to make what I'm trying to do without killing too much memory?

If someone wonders I'm using C++ with HGE (Haaf's Game Engine).

EDIT: I've choosen to limit the amount of stuff on screen so that it can render. But look here so maybe you'll understand what I try to achieve: Link to image because I'm not allowed to use image tags :(

A: 
ufukgun
Seems cool but won't that limit to 4 overlay textures or am I missing someting here? :o
Mariamario
+2  A: 

If it's just tile based then you only store one instance of each unique tile and each unique "overlay" (flower, rock, etc.). You reference it by id or memory location as you have been doing.

You'd simply store a location (tile number and location on tile) and a reference to an overlay to "paint" it without consuming a lot of memory.

Also, I'm sure you know this but you only render what's on screen. So memory usage is pretty much constant once everything is loaded up.

colithium
+1 This is about what I would have said. :)
kkaploon
You mean like only storing the actual texture if I have already painted to it, otherwise reference to a blank texture? That would be an option I guess :) And yes I know I render only what's on the screen, so I set my for loop that renders the main tiles top only loop througt the elements that will be rendered on screen. That feels faster then looping the whole array and checking them all one after one.
Mariamario
You would store one copy of each unique texture and one copy of each unique "ground debris". In your level file, you will store references to each tile, you wouldn't copy the tiles over and over again to fill the level. In memory, you will load up all tiles for that area/level once and then draw them to the screen when visible. I doubt you have 100*100 = 10,000 unique tiles, right? That's merely the size of your world or level?
colithium
The idea was to make the game world dynamic and it's not the tiles themself I want to store, but the stuff stat gets there as the game is run. That way there could in fact be 10,000 unique tiles. But I feel the discussion with runeborg has made me realize I should limit somewhere.
Mariamario
You shouldn't have a unique tile for every possible combination of things that are on them, keep them separate. Store the tile, and store each different kind of debris. Then only store a *reference* to the particular debris and a position/orientation. Draw them layered. Tile then each debris in order of occurrence. Cache as needed to improve performance.
colithium
+1  A: 

I'm not exactly sure what you are trying to do, but you should probably have the tiles in separate layers. So say that for each "tile" you have a list of textures ordered bottom-up that you blend together, that way you only store the tile indexes.

Runeborg
That's an option but it will possibly be too slow when it comes to rendering an extreme amount of data on each tile which probably will be needed :(
Mariamario
I think in some way you will need to limit yourself. Ask yourself at what point does it just get too cluttered. My suggestion was more for static map textures. For blood/bullets you'd probably want to use some kind of particle effects I guess. But at some point you will get 100k bullets in a single tile, and it won't do you any good. Limit yourself to a certain amound of bullets/blood.
Runeborg
Thanks for your answer. I realize that I should limit something. The choice is between limiting the game area so I actually can store textures for every tile or just limit the amount of stuff on the ground.
Mariamario
I think you're better off limiting yourself to the amount of stuff on the ground. Ask yourself what it brings to the game. Is it really necessary or is it just 'a cool idea'? Would 1000 bullets in a tile really be that much cooler than 20 bullets (depending on tile size)?
Runeborg
In fact I think it would be cooler. But as the game area is so huge the amount of data I wish to store would (1)Kill my memory by storing thousands of textures OR (2)Kill my CPY by rendering tens of thousands of sprites. So I think I'll just make the stuff falling on the ground really, really slowly fade away. So slow the player won't notice the fading.
Mariamario
A: 

Instead of storing just the tile number, store the overlay number and offset position also.

struct map_zone {
    int tile; // tile number
    int overlay; // overlay number (flower, rock, etc). In most cases will be zero
    int overlay_offset_x; // draw overlay at X pixels across from left
    int overlay_offset_y; // draw overlay at Y pixels down from top
}

map_zone[100][100] map;

And for rendering:

int x, y;
for(y = 0; y < 100; ++y) {
    for(x = 0; x < 100; ++x) {
        render_tile(map[y][x].tile)
        render_overlay(map[y][x].overlay, map[y][x].overlay_offset_x, map[y][x].overlay_offset_y);
    }
}

It's arguably faster to store the overlays and offsets in separate arrays from the tiles, but having each area on the map self-contained like this is easier to understand.

too much php
Yes that's a good idea for making the ground more varied, but for placing lots of objects as I need to do is sadly not supported :(
Mariamario