Trying to draw a flat tile terrain.

Page 1 of 1

6 Replies - 3366 Views - Last Post: 23 May 2012 - 12:27 PM

#1 ArchColossus

Reputation: 1
• Posts: 49
• Joined: 22-February 12

Trying to draw a flat tile terrain.

Posted 10 May 2012 - 06:58 AM

I'm trying to draw a tiled floor using a bitmap image, but I'm running into spots where I don't know what to do. I tried looking off Riemer's tutorial on it, but I'm still confused. Could anyone either point me to a tutorial on the subject, or explain the process to me? For starters, I just want a 16x16 grid floor. I want to be able to choose tile color based on the bitmap's white value. This is my bitmap reader I'm using. (Given to me by someone here a while back actually.)
```private void LoadTileData(Texture2D tileMap)
{
terrainWidth = tileMap.Width;
terrainHeight = tileMap.Height;

Color[] tileMapColors = new Color[terrainWidth * terrainHeight];
tileMap.GetData(tileMapColors);

tileData = new float[terrainWidth, terrainHeight];
for (int x = 0; x < terrainWidth; x++)
for (int y = 0; y < terrainHeight; y++)
tileData[x, y] = tileMapColors[x + y * terrainWidth].R / 5.0f;
}
```

If this seems very newbie-like, it's because I am.

Is This A Good Question/Topic? 0

Replies To: Trying to draw a flat tile terrain.

#2 ArchColossus

Reputation: 1
• Posts: 49
• Joined: 22-February 12

Re: Trying to draw a flat tile terrain.

Posted 11 May 2012 - 06:49 AM

I'm really stuck on this, I can't get anything other than one tile to draw, and it was vertical instead of horizontal. Riemers tutorial isn't helping, and I can't find ANYTHING that teaches this. And I don't know how to make anything generate off of the bitmap readings. Any help would be appreciated.

#3 DanielLeone

Reputation: 22
• Posts: 177
• Joined: 04-February 12

Re: Trying to draw a flat tile terrain.

Posted 11 May 2012 - 07:35 AM

I am a bit confused as to what your trying to do, but are you trying to loop through each of the 'parts' in the texture, and test the white value.

I think you need to explain your actual situation a bit more so we can help you out. I've used similar methods for collision detection, so all that is familiar to me, but what are you actually trying to achieve with this line of code :

```tileData[x, y] = tileMapColors[x + y * terrainWidth].R / 5.0f;

```

To me it looks like your assigning each pixel in tileData to the same value in tileMapColours. Except that tileMapColours is a 1D array, as appose to tileData, 2D. But then I don't know why you have .R / 5.0f;

Explain that and I may be able to help you out some more.

Sorry if I sound like even more of a noob, but I don't really understand your question .

Hope I helped,
Daniel,

#4 ArchColossus

Reputation: 1
• Posts: 49
• Joined: 22-February 12

Re: Trying to draw a flat tile terrain.

Posted 11 May 2012 - 07:41 AM

I'm trying to draw a grid-like "tile floor" that is generated off of a bitmap. I'm trying to start with just a 16x16 floor, where say a "floor" tile is red, and a "wall" tile is blue. All of the tiles will be at Y = 0. But I'm trying to draw it in 3D.

#5 DanielLeone

Reputation: 22
• Posts: 177
• Joined: 04-February 12

Re: Trying to draw a flat tile terrain.

Posted 11 May 2012 - 07:59 AM

Okay I won't be able to help you with the positioning then, because I haven't used 3D before.

So what if you used:
```            tileData = new float[terrainWidth, terrainHeight];
for (int x = 0; x < terrainWidth; x++)
for (int y = 0; y < terrainHeight; y++)
Color a = tileData[x, y] = tileMapColors[x + y * terrainWidth];

switch(a.R)
{
case 0:
{
//Floor
}
case 255:
{
//Wall
}
defult:
{
//Blank
}
}
}

```

Would something to that effect be of any use?

Or I may be on the complete wrong track
Trying to help anyway,
Daniel,

This post has been edited by DanielLeone: 11 May 2012 - 08:00 AM

#6 ArchColossus

Reputation: 1
• Posts: 49
• Joined: 22-February 12

Re: Trying to draw a flat tile terrain.

Posted 11 May 2012 - 08:10 AM

I'm not actually positive on it, as I've never been formally taught in the language yet, everything I know is from tutorials and dissecting projects, so I've never seen some of this before, but it LOOKS like it's heading in the right direction... I'll be working on this for awhile, so I'll try it out, but thank you for the help. I've been unable to find many sources that teach XNA. Especially in 3D. So anything helps.

#7 BBeck

• Here to help.

Reputation: 792
• Posts: 1,886
• Joined: 24-April 12

Re: Trying to draw a flat tile terrain.

Posted 23 May 2012 - 12:27 PM

ArchColossus, on 10 May 2012 - 06:58 AM, said:

I'm trying to draw a tiled floor using a bitmap image, but I'm running into spots where I don't know what to do. I tried looking off Riemer's tutorial on it, but I'm still confused. Could anyone either point me to a tutorial on the subject, or explain the process to me? For starters, I just want a 16x16 grid floor. I want to be able to choose tile color based on the bitmap's white value. This is my bitmap reader I'm using. (Given to me by someone here a while back actually.)
```private void LoadTileData(Texture2D tileMap)
{
terrainWidth = tileMap.Width;
terrainHeight = tileMap.Height;

Color[] tileMapColors = new Color[terrainWidth * terrainHeight];
tileMap.GetData(tileMapColors);

tileData = new float[terrainWidth, terrainHeight];
for (int x = 0; x < terrainWidth; x++)
for (int y = 0; y < terrainHeight; y++)
tileData[x, y] = tileMapColors[x + y * terrainWidth].R / 5.0f;
}
```

If this seems very newbie-like, it's because I am.

I appologize for missing your post on this. It looks like it's been about a week and a half since you asked this question. I probably would be the perfect person to help you on this, because 3D is what I'm spending all my time working on these days. You probably got the problem worked out by now, but I'll help if I can.

I don't see anything wrong in the code you provided here. I've seen this code in examples such as Riemer's tutorials. So, I'm fairly familiar with it. I also built a couple of programs a few weeks ago that used code almost identical to this to build a 3D terrain.

I'm working on a tutorial that teaches this, that will be - in some ways - similar to Riemer's tutorials. The similarity is one of the reasons that I've put that tutorial to the side for the moment and have been working on an even more basic 3D tutorial, which I now have pretty much written and hope to publish pretty soon. I'll try to remember to update this thread if I do.

Anyway, it looks like this is the "core" code for building a 3D terrain (it could be used for a couple of other things that I can thing of though, and when you mentioned different colors it threw me off). The code is basically reading the data from a heightmap file into an array. The array is then later used to build the terrain.

So, "tileMap" is a bitmap picture, which has been loaded into this variable in another part of the code. The problem is that you can't use that data as a "picture". The bitmap is a full color picture. When you "look at it" the picture will "look" grayscale. But it's actually full color. So, you have 3 or 4 values for every position on the grid.

Look at this code here:
```tileData[x, y] = tileMapColors[x + y * terrainWidth].R / 5.0f;

```

See the "].R". I think that means "red". The three colors in each position are Red, Green, Blue, and possibly Alpha (which is why I said 3 or 4). This line of code ignores all colors except red, and it's just going to use the brightness of red to set the value in tileData[x,y] (your array).

I'm not sure why it divides the number by 5. Usually, you do that when you want to limit the number of answers you get. There are 256 values of Red numbered 0 through 255. Dividing by 5 reduces it to 51 different values. 51 is still quite a few; so, I'm not sure why it does that.

Usually, what you would be doing is putting values into the tileData array from the numerical values in the bitmap picture file. The values all have an x,y position which represent vertices, or the corner points, of a grid that is to be used as a terrain.

So before you get to this code here. You define a bunch of points (vertices) across and a bunch of points (vertices) down, and then you draw lines (indices) between those points to form squares. XNA doesn't know what a square is, so you actually have to draw two triangles to make each square. Each of your squares is a grid tile. But at this point it's completly flat. All the vertices are perfectly evenly spaced the same distance apart from one another to form a perfectly flat plane of squares that make up a grid.

The code you've shown here is the type of code you would use to "unflatten" the terrain. To make the terrain have hills and valleys you need not only x and y but z as well.

The way the code example here was written is confusing, because sometimes when it says y it means y and sometimes when it says y it means z. This confusion comes from the fact that you are building a 3D terrain from a 2D picture. The tileData array should probably be written as tileData[x,z] to make it less confusing. And the surrounding loops would use z instead of y as well. I think that would make the code more clear. The y value is actually the number stored in each position of tileData[x,z]. In other words, tileData[x,z] = y.

You "could" just assign a height value for each x,z position, but for a big grid that becomes nearly impossible. That's why a bitmap is used to store all the heights.

Anyway, as I think about your post, I'm not sure where you are trying to make a terrain or if you actually are doing a grid of "tiles". The fact you are dividing the red value by 5, to reduce it to 51 values, makes me think the numbers in the tileData array represent 51 different types of tiles that it knows how to draw.

Well, if you still want some help on this. I'd like to see the entire code of what you're working on. Which of Riemer's tutorials is it? Then I might be able to help you if you are having specific problems or problems understanding something.

```private void LoadTileData(Texture2D tileMap)
{
terrainWidth = tileMap.Width;  //You're going to loop x for each x position across the grid.
terrainHeight = tileMap.Height; //You're going to loop y for each y position across the grid.

//Here we build an array of 3 or 4 byte colors where the x and y
// perfectly match our bitmap size and grid size.
//Then we use XNA to transfer the data in the file into our
//array of colors.
Color[] tileMapColors = new Color[terrainWidth * terrainHeight];
tileMap.GetData(tileMapColors);

//Next, we make tileData an array of float values that matches the size
//of our grid as well as the bitmap height and width.
//The float values stored here could be used for terrain height, or
//we might use them to represent something else, such as the color or
//texture being used for that spot on the grid.
tileData = new float[terrainWidth, terrainHeight];
for (int x = 0; x < terrainWidth; x++)  //look at every row
for (int y = 0; y < terrainHeight; y++) //look at every column
//Here we look in the array of colors that we built and pull out only the red values.
//Since we're only looking at the brightness of one color, we are "essentially" reading
//gray (or brightness) values. If the color actually IS gray on that spot red, green, and
//blue all have the exact same values for gray. So, reading one color is the same as
//We usually divide by 5 to reduce the 256 possibly color values down to 51 or 52 values.
//The x + y * terrainWidth is the x position plus y * terrainWidth. You can't just use
//y by itself. These are rows and columns. To advance 1 row you can't just move 1 column
//forward. Instead, you have to move the entire width of columns forward to get to the
//next row. So you use y * terrainWidth to do that.
tileData[x, y] = tileMapColors[x + y * terrainWidth].R / 5.0f;
}
```

Anyway, let me know if I can help further.

This post has been edited by BBeck: 23 May 2012 - 12:36 PM