1
votes

I'm making a random City generator in C# using XNA, based on a tile engine with tiles of 16x16. I've generated roads in a grid pattern and put them in a List<T> with the position in pixels and also by tile coordinates. So I have set the tile the road is using as "Occupied = true" and tried to fill in any remaining unused tiles with buildings.

However the difficulty is that I want the building texture to be bigger than the just one tile. My tiles are organised in another List<T> and have an occupied property so I can check weather it is filled or not. So I need to check the property of 4 tiles in a 32x32 rectangle to see weather they are occupied and if not place a building there.

I have achieved this, however it is terribly slow and inefficient as it loops through every tile and checks the entire list 4 times per loop. So I'm looking for a better way to do this. I'm also aware that my entire system might be kinda stupid, but I'm new and am trying to achieve this using my limited knowledge.

foreach (Tile Tile in Tiles) {
  Tile Tile1 = Tiles.Find(delegate(Tile T1) { return T1.TileCoords() ==
    new Vector2(X, Y) && T1.Occupied == false; });
  Tile Tile2 = Tiles.Find(delegate(Tile T1) { return T1.TileCoords() ==
    new Vector2(X + 1, Y) && T1.Occupied == false; });
  Tile Tile3 = Tiles.Find(delegate(Tile T1) { return T1.TileCoords() ==
    new Vector2(X, Y + 1) && T1.Occupied == false; });
  Tile Tile4 = Tiles.Find(delegate(Tile T1) { return T1.TileCoords() ==
    new Vector2(X + 1, Y + 1) && T1.Occupied == false; });
  if (Tile1 != null && Tile2 != null && Tile3 != null && Tile4 != null) {
    MyBuildings.Add(new Buildings(new Rectangle(Tile1.Rectangle.X,
    Tile1.Rectangle.Y, Engine.TileWidth * 2, Engine.TileHeight *  2)));
  Tile1.Occupied = true;
  Tile1.OccupiedWith = "Building";
  Tile2.Occupied = true;
  Tile2.OccupiedWith = "Building";
  Tile3.Occupied = true;
  Tile3.OccupiedWith = "Building";
  Tile4.Occupied = true;
  Tile4.OccupiedWith = "Building";
}
if (X > WorldSize.X / 16) {
  X = 0;
  Y++;
} else
  X++;
}
2
So the question is something like: How do I optimally find squares of 32x32 where I can put a building (that is composed of 4x16x16 tiles)?Timotei
Yes, thanks that's a simple way to phrase itFrank James

2 Answers

0
votes

Consider storing your tiles in a twodimensional array. This is a very common(if not the most common) practice with tile based games. Right now you are storing them in array which is very inefficient for traversing through, since you have to loop through the whole array to find a certain tile. With a twodimensional array you can search for tiles in this way:

Tile T1 = Tiles[T1.X, t1.Y];
Tile T2 = Tiles[T1.X + 1, t1.Y];
Tile T3 = Tiles[T1.X, t1.Y + 1];
Tile T4 = Tiles[T1.X + 1, t1.Y + 1]; 

Since your tiles have a standard size of 16 pixels, you can easily translate between the tiles' pixel locations(drawing) and their location in the array by dividing or multiplying them by 16

0
votes

I propose to change the way you are storing the tiles.

Each tile could have a List<Tile> of neighbors, in an 8x8 configuration: enter image description here

And when you are trying to find a free space, you just iterate linearly through the 8 neighbors.

This way only when creating the map you have to calculate the neighbors, and store them in the neighbors list.

With this representation you could also find easier to march through the grids using a certain pattern (for example creating rivers, roads, etc).