FourthTribe DevDiary1 – Using pixel maps

Taking a break of the standard reviews I had been posting, heres a bit on the current project I'm working on. 

Fourth Tribe is a top down RPG where the player controls a character that moves around on a map of tiles. Still in a very early stages, using early art, I wanted a way to design levels quickly. I played around with a few ideas, a binary store of level data, text files etc. Finally bottomed out on using a pixel map/json file combination. The json file holds data for each tile type(grass, rock, bush, etc) and the pixel map tells the game which tile to use where. For example, using this pixel map

MapEx

I can create this map of tiles.

TilesEx

 

Where the red creates rock tiles, blue is bushes, and green is grass. 
This turned out to be much easier then I was expecting.  A few basic steps with C# and XNA had me creating levels super easy.  The first step would be to create a Texture2D object from the png file. Initial testing had me using the built in XNA content pipeline. This defeats the purpose if the texture needs to be recompiled every time it changes. Fortunetly the Texture2D object has a FromStream() method that makes this process very easy.

 try           
{               
                using (StreamReader sr = new StreamReader(filename))
                {                   
                        texture = Texture2D.FromStream(graphicsDevice, sr.BaseStream);               
                }     
}           
catch (Exception e)
{
                log.Error(e.ToString());
}

 

Now that we have a Texture2D file, the second step is to create an array of all the colors. Again, this is an ease to pull off. Because the size of the texture is the number of pixels we can use the measurements to create an array sized to the number of pixels. 

Color[] texColors = new Color[texture.Height * texture.Width];
texture.GetData(texColors);

 

 Now we have an array of colors which we can gleen the RGBA values from. To create the actual tiles, I created a dictionary of all tile types. In this dictionary I used the colors as the key. Using the texture.Width in a for loop, I know when to restart each row. 

 

Because I have the framework already built in, it was no trouble at all to create a utility to allow me to export png files back out. I can use this mapper utility to easily change tiles visually, without having to edit the specific pixels by hand.  Knowing the tile location, we can replace its corispondant color in the array. Then there is just the matter of simply saving the color array back to a Texture2D, and writing it back to a stream writer.

texColors[location] = newColor;
texture.SetData(texColors);
try
{
            using (StreamWriter sw = new StreamWriter(filename))
             {
                      newSave.SaveAsPng(sw.BaseStream, texture.Width, texture.Height);
              }
}

 

Theres still a lot left to do with this. In the code I'm currently using I don't have anything with the alpha value. This will be used to add entities/events on top of the map, but this brings its own set of problems.