Tile-Based Maps

Hello everyone. It is some time since my last post so i’ve learned some things. Currently i am in a big mist.
Usually, when i want to create a tile map i do so:

  1. I create a int[][] with every tile’s index
  2. Using every tile’s index, i put a tile object in an ArrayList so:

   ArrayList<Tile> tiles = new ArrayList<Tile>();

   for(...every tile in int[][]...) {
      switch(int[x][y]) {
      case GrassTile.id: tiles.add(new GrassTile(x, y));
      case ...
      ...
      ...
      }
   }

Is my aproach right? If not, how should i do this…

Thank you!

EDIT: And also, can anyone sugest me how should i design the tile classes so that when i want to add a new type of tile, i should not change too much in the other classes?

You shouldn’t have to change anything in other classes to accommodate a new type of tile. Just have each specific tile class extend a general Tile class.

I am already doing this. The problem is that i foud somewhere that i should make only a central Tile class and some static classes for every type of tile. The problem is that i don’t really know how to manage with this design, since i didn’t ever used it or ever saw any example…


class Tile{

    int x, y;
    Color tileColor;

    public Tile(int x, int y){

        this.x = x;
        this.y = y;
    }
}


class GrassTile extends Tile{

    public Tile(int x, int y){

        super(x, y);
        tileColor = Color.GREEN;
    }
}

Something along those lines.

Create a base Tile class that defines a bunch of properties, such as isPassable(), isAccessibleFrom(neighborTile), getTileImage(), getElevation(), etc. and a bunch of events, such as walkOver(character), npcWalkOver(npc), interact(character), draw(graphics), etc. The exact functionality you will want is specific to your game. I’m also assuming you’re talking about a top down tile map and not a platform game. It’s the same either way, but the examples would need to be slightly different.

Other options for reading tiles from an outside source could include reading data from a DataInputStream and converting data to Tile objects or reading an image and converting each pixel to a certain type of Tile.

So is it ok that i am doing a new Object for every Tile in the game? This is my main question.

Yes, of course ;D

How many tiles do you have? If you have a lot e.g. 500x500 then I would recommend the following approach:


byte[] terrain;  // of size width * height

which holds a single byte for each tile. You can index the array using a formula similar to y*width + x. The advantage of the above is that it’s simple, takes up minimal amount of memory, and is extremely fast to serialize using java.nio.

The byte stored is an index into a TileType array. TileType might appear as:


class TileType {
  name
  glyph
  color
  isPassable
  graphic
  etc...
}

TileType[] tileTypes;  // up to 256

tileTypes[0] = new TileType("grass", ".", Color.green, true, ...);
tileTypes[1] = new TileType("hill", "^", Color.brown, false, ...);
...

I originally went with the instantiate an object for every single terrain tile but serialization was too slow for my liking. The above worked well. I personally feel that an inheritance tree is unnecessary because TileTypes usually hold only basic properties.

Thanks! But I usually use this system:


stone(300, 400);


public static void stone(int x, int y) {
        glLoadIdentity();
        stone.bind();
        glTranslatef(x, y, 0);
        glBegin(GL_QUADS);
            glTexCoord2f(0, 0);
            glVertex2f(0, 0);
            glTexCoord2f(0, background.getHeight());
            glVertex2f(0, 50);
            glTexCoord2f(background.getWidth(), background.getHeight());
            glVertex2f(50, 50);
            glTexCoord2f(background.getWidth(), 0);
            glVertex2f(50, 0);
        glEnd();
    }

It works much better for me.