Game Tutorial: Part 1
  This is part one of a series of gaming tutorials. As a beginner I found a real lack
Home

 

Game Tutorial: Part 1 - Tiles

Before starting this tutorial I recommend reading the Tutorial Basics page. This talks about how I format things, the way source is presented etc. Find it here.

Introduction

This is my series of game tutorials, covering the basics of a little tank game. An example of the concepts covered in this set of tutorials can be found on the BattleTanks page.

Why Tiles?

Tiles are a great way to layout a game and are used as the basis for alot of maps in games. Tiles are useful because they can dictate whether a tile is accessible or not (such as a floor or a wall) as well as dictate different types of terrain that is supposed to be displayed (water, dirt, grass, rock etc). This can all be layed out easily in an array and this makes accessing the data later much easier. That allows of easy addition of more options like collision detection and obstacle avoision.

Getting Ready

First thing is the preperations. We need to decide how large our map will be, how large each individual tile will be and finally what the actual layout of the map will be.

Size of the map is entirely upto you. It should be a certain number of tiles tall and a certain number of tiles wide. The height/width should be integers. I'm going to go with 40 x 40 for my map size:

var map_height = 40;
var map_width = 40;

Next you need to decide what size you tiles will be. Again this is all upto you and depends on your needs. I chose 10 by 10 pixels (this makes for a 400x400 "actual" map size):

var tile_height = 10;
var tile_width = 10;

Generating the map

Now we need to decide how exactly to lay out our map. This can be done a couple of ways. Number one would be to do it randomly. This is easy and requires very little time but dosen't necesarily output a map that is desirable:

      function genMap(map_width, map_height, num) {
            var xlength, ylength, xpos, ypos, arr;
            var map_arr = new Array();
            //generate empty map
            for (var x = 0; x<map_width; x++) {
                  arr = new Array();
                  for (var y = 0; y<map_height; y++) {
                        arr.push(0);
                  }
                  map_arr.push(arr);
            }
            //generate blocks
            for (var i = 0; i<num; i++) {
                  xlength = Math.round(Math.random()*5);
                  ylength = Math.round(Math.random()*5);
                  xpos = Math.round(Math.random()*xdim);
                  ypos = Math.round(Math.random()*ydim);
                  for (var x = 0; x<xlength; x++) {
                        for (var y = 0; y<ylength; y++) {
                              map_arr[y+ypos][x+xpos] = 1;
                        }
                  }
            }
            return map_arr;
      }

The way this works is by generating a set of randomly position and randomly sized boxes and placing them into the map array. This is more effective than a simpler method of just placing random walls throughout the map. Let me explain the code.

The function is passed three variables. The first two are self explanatory. These are the width and height of your map. The third is how many random blocks you want to place. On a map my size I find that 20 produces a decent but not too cluttered map.  Next we declare some variables (good thing to do if you ever start coding in a stricter enviroment) and generate an empty map:

      var map_arr = new Array();
      //generate empty map
      for (var x = 0; x<map_width; x++) {
            arr = new Array();
            for (var y = 0; y<map_height; y++) {
                  arr.push(0);
            }
            map_arr.push(arr);
      }

This works by first declaring the empty map array. Then we loop through every possible x/y position on the map and place a 0. This is an empty square (or in my example a floor square).

Next we have a loop that generates our random blocks. This loops a numnumber of times (the variable passed to the function):

       for (var i = 0; i<num; i++) {
            xlength = Math.round(Math.random()*5);
            ylength = Math.round(Math.random()*5);
            xpos = Math.round(Math.random()*xdim);
            ypos = Math.round(Math.random()*ydim);
            for (var x = 0; x<xlength; x++) {
                 for (var y = 0; y<ylength; y++) {
                      map_arr[y+ypos][x+xpos] = 1;
                 }
            }
       }

This code picks a random X length, a random Y length and a random position for the block. Then it loops through all the tiles within the block and sets their position on the map to 1 (or in my case a wall square).

When the function is done that it returns the map it just generated allowing you to place it in a variable. So then you can call the function simply using:

       var new_map = genMap(my_width, my_height, number_of_blocks);

You can see that my map is pretty simple in the fact that it only uses two distinct tiles. For simple games this is fine. However later you might need to use more tile types (wall, grass, dirt, water etc) and this is simply by using different numbers in the array besides 0 and 1 and having them corrispond to a different tile type.

Drawing the Map

So now that we have a map represented in array form, we need to display it visually. In my case this is going to be done simply by looping through the array and drawing a box with the dimensions tile_width x tile_height everytime a 1 shows up:

       function drawMap(map, target, tile_width, tile_height) {
              for (var y = 0; y<map.length; y++) {
                     for (var x = 0; x<map[y].length; x++) {
                            if (map[y][x] == 1) {
                                   drawBox(target, 10, 10, _
                                   x*10, y*10, 0x000000);
                            }
                     }
              }
       }
       function drawBox(target, xdim, ydim, x, y, col) {
              target.lineStyle(undefined);
              target.beginFill(col);
              target.moveTo(x, y);
              target.lineTo(x+xdim, y);
              target.lineTo(x+xdim, y+ydim);
              target.lineTo(x, y+ydim);
              target.endFill();
       }

This code includes the drawMap function (this is the important one) and then the generic drawBox function (I wrote this one just because I draw alot of boxes and it makes it easier to have it seperate). So the important function here is the drawMap function, though it is pretty simple. It receirves four arguments. The map, the target movieclip, the tile_width and the tile_height. Majority of these are self explanatory. The target clip is the movie clip upon which the tiles are going to be drawn. It works by looping through the x and y columns of the map and checking if the position is a 0 (floor) or a 1 (wall). If it is a 1 it sends the coordinates and the tile_width and tile_height to the drawBox function and the function draws a box.

This all together should output something on the lines of this:

Source

Manual Map

So now we have generated a random map and drawn it out visually. It works, but it isn't really that great. You can see that it's random and it dosen't have the flair that you might desire, though in some cases this might be what you need. Another option (and most of the time the better option) would be to manually. This takes longer initally than a random map because every tile has to be hand decided, but it uses less code and you are in complete control of your map.

This method is quite simple. You layout your map in such a way that makes it easy to read and then hack away, placing tiles where need be. Here is an example of a manual map: gameTut1Ex2.txt

This will output something like this:

Source
 

So now we have a manually generated map. This is great because it's exactly the way we want. The only problem is the time it took to make the map. This isn't a huge problem on mine, but if you ever start dealing with huge maps it can definatley be pain-staking. There is an option that is best of both worlds.

Procedural Mapping or Procedural Generation

This is the process of dynamically generating a map based on a number of different factors and variables. Wikipedia.org has a very nice article. I might extend this section of my tutorial in the future but currently my knowledge is not quite upto par in this area.

So I have a map. Now what?

The next step is going to be placing a character and movement. I will cover this in the next chapter: Game Tutorial: Part 2 - Character and Basic Movement