Saturday, October 5, 2013

TileMap in depth

I didn't really explain how my TileMap class works, so I'll go into more detail here. If you want to follow along, I'm using the TileMap class from: https://dl.dropboxusercontent.com/u/59779278/Dragon%20Tale%20Tutorial%20P02.rar

First, I'll go over the fields.

// position
private double x;
private double y;

This is self-explanatory. These two variables indicate the top left corner of the TileMap. As the player moves to the right, the TileMap moves to the left, ie: x decreases.

// bounds
private int xmin;
private int ymin;
private int xmax;
private int ymax; 

These are the minimum and maximum bounds of the map. The position (x, y) cannot go further than these limits. This prevents the "camera" from scrolling past the edges of the TileMap.

private double tween;

This is a factor between 0 and 1 that indicates the speed in which the TileMap's position changes. A tween of 1 means that the TileMap will move to a given position instantly, where as a tween of 0.1 means that the TileMap will move 10% towards a given position. This gives a smoother scrolling effect.

// map
rivate int map[][];
private int tileSize;
private int numRows;
private int numCols;
private int width;
private int height;

The map is simply a 2d array of integers, where each integer represents a tile from the tileset. The tileSize is the size of a single tile in pixels. numRows and numCols are the number of rows and columns of the map. width and height are the dimensions of the map in pixels.

// tileset
private BufferedImage tileset;
private int numTilesAcross;
private Tile[][] tiles;

The tileset is the entire tileset image. From that, I read each individual tile subimage, and store it in the tiles array. The numTilesAcross is used to calculate the "id number" of the tiles.






// drawing
private int rowOffset;
private int colOffset;
private int numRowsToDraw;
private int numColsToDraw;

These are for drawing. They indicate the row and column that drawing should start, and how many rows and columns to draw. This is so that only part of the TileMap on the screen gets drawn, rather than the entire TileMap. (With respect to drawing, these variables aren't important because the Graphics object has a device clip, which prevents any drawing from happening outside of the Graphics' device's visible region. But from a complexity point of view, it does reduce the time from O(n^2).)



 The constructor is simple. It sets the tileSize, the tween, and the number of rows and columns to draw.

The loadTiles(String s) method reads in the tileset and cuts out each individual tile to put into the tiles array. My TileMap class isn't very scalar, in that it has a specific way of handling tilesets. The tileset image must always have 2 rows of tiles. The top row are all the non-blocked tiles, and the bottom row are all the blocked tiles.

 The loadMap(String s) methods fills in all the field variables under // map. The map file contains the number of rows and columns of the map, and the map itself, a 2d array of integers. I get the numRows, numCols, width, height, and bounds of the map.

Then there are a few getters and setters. Simple.

Next is the setPosition(double x, double y) method. This method tries to move the TileMap's (x, y) position to the given destination (x, y). This is where tween kicks in to smoothly move the TileMap to the destination. Then I make sure the position doesn't go past the bounds using fixBounds() and then calculate the row and column offsets to know where to start drawing.

The last thing is the draw(Graphics2D g) method. This is a straight forward 2d array loop. I loop through the map array starting with the rowOffset and colOffset, up to the specified numRowsToDraw and numColsToDraw. Now remember the map array contains integers of tileset "id numbers." I have to calculate, say, the id number 24 into row 2 column 4 (see tileset image above.) Since I know the numTilesAcross of the tileset, I can easily translate the id number using:

 int idNumber = map[row][col];
int translatedRow = idNumber / numTilesAcross;
int translatedCol = idNumber % numTilesAcross;

Then I just draw the given tile at the correct position and that's it. 

Hopefully, this answers some questions about the TileMap. I'll make a separate post about the "camera" scrolling.

11 comments:

  1. You are doing very nice job

    Thank you for sharing :)

    ReplyDelete
  2. Hey man, I just wanted to say a big thanks for all the tutorials; you are doing an amazing job.. But what really amazes me is the pixel-art you create.. Could you suggest a good source (book,webpage or anything else) that has helped you draw these if you know any read any of course.. Cheers

    ReplyDelete
    Replies
    1. I didn't use any art tutorials. Just opened up Photoshop and made those. So I can't recommend any websites or books.

      Delete
  3. Hello mike, what are you working on? We miss your videos, hope ill see you work soon! thanks.

    Here is my work due to your lessons:
    http://www.youtube.com/watch?v=Cn2riOk8VXo

    ReplyDelete
    Replies
    1. I'm working on 2 games right now, although slowly.

      Yeah, I haven't really gotten progress on the Asteroids tutorial in a while. I mean the game is practically done. I really only wanted to do two more things: audio and save file (to keep high scores)

      <=========================>

      That's very cool. I see you got the textures down.

      Also, finally someone who knows some trig. I get lots of messages from people who want me to explain the math behind the game. Well you made good use of it with those orbiting shooters.

      It's always great to see the games my viewers make.

      Delete
  4. Hello, what program do you use to create the maps?

    ReplyDelete
    Replies
    1. My own. It's very crappy since I didn't expect anyone to use it other than me.

      https://dl.dropboxusercontent.com/u/59779278/TileMapEditor.rar

      Delete
  5. This comment has been removed by the author.

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete
  7. Hi guys, i created map with Tile Map Editor, but have a problem if i have 2 or more layers on tileMap editor

    ReplyDelete