void star games

* play * code * learn *


Flash Tutorials

puce Flash Memory Game Tutorial 3 Back Start Over Next

A New Class. Create a new Actionscript file and call it Table.as. Inside declare a package and then a class called Table. Copy the import files from the class Tile into this new one.

First, let us declare a variable in this class to store the table of tiles. This will have to be an array and we can make it one right away:
var table:Array;
Declaring the type of a variable of parameter in Flash doesn't affect the program but Flash can help you finding appropriate functions for it if you do.

Now we can define a function that initializes the tiles with random values such that there are two and only two tiles for each option. The easiest way is to fill the table in order and then shuffle it. Let's start with the function shuffle:
public function shuffle(rows:int, cols:int) {
  var i, r, temp;
  for (i=0; i<rows*cols-1; i++) {
    r = i+Math.floor(Math.random()*(rows*cols-i));
    if (i != r) {
      temp=table[int(i/cols)][i%cols];
      table[int(i/cols)][i%cols] = table[int(r/cols)][r%cols];
      table[int(r/cols)][r%cols] = temp;
    }
  }
}

Basically this function chooses for each cell in the table a random position further down in the table and swaps it with it. I find it easier to linearize the table by having i going from 0 to rows*cols-1 and then compute the row and column by dividing by the number of columns and then applying the modulo (%) operation.

Now that we have a shuffle function, we can write the function that fills up the table. Here it is:
public function fill_table(rows:int, cols:int, options:int) {
  var k = rows*cols/2;
  var n = options;
  var i=0, opt = 0;
  while (k > 0) {
    var r = Math.floor(Math.random() * (1+n));
    if (r <= k) {
      table[int(i/cols)][i%cols] = opt;
      table[int((i+1)/cols)][(i+1)%cols] = opt;
      i+=2;
      k--;
    }
    opt++;
    n--;
  }
  shuffle(rows, cols);
}

What happens here is that we go through all the possible options and we select rows*cols/2 of them to be used in the table with a known sample selection algorithm. For each selected option we need to place two tiles with that option in the table. Again, I found it easier for this algorithm to work with a linearized table and compute the row and column once I know what value needs to be stored in the cell.

Finally, if you want to test out this part (and you should), here's a function that can be useful:
public function trace_table(rows, cols) {
  for (var i=0; i<rows; i++) {
    for (var j=0; j<cols; j++) {
      trace(i, j, table[i][j]);
    }
  }
}

The "trace" is printing out the parameters it receives to the Output tab in flash. It does not affect the execution of the swf, but it's useful for debugging.

With all of this, it's time to write a constructor for the class. It seems necessary to pass the number of rows and columns to the constructor, but also to store these in some class variables for later use. Let's add two variables in the class called sizeR and sizeC (or use more creative names if you want). This constructor must initialize the array of arrays that will store the table, then call the function fill_table. We can assume right now that the constructor will need to initialize the tile objects and keep links to them, in which case it will need a reference to the stage that it can pass to the tiles.
public function Table(rows:int, cols:int, the_stage) {
  table = new Array(rows);
  for (var i=0; i<rows; i++) {
    table[i] = new Array(cols);
  }
  fill_table(rows, cols, 15);
  sizeR=rows;
  sizeC=cols;
  parent = the_stage;
}

Before going to the next step, it might be a good idea to test this all out in the .fla file.

Let's proceed to creating the tiles and displaying them. We'll need another array created the exact same way as the table. Let's call it "tiles" and add it to the class. First, let's assume that we'll leave some space in the stage above the rows of tiles for buttons and titles. It would be useful to store it in a class variable. Declare it as "headspace" and initialize it in the constructor to whatever might be appropriate for you. You can make a guess now and adjust this value later by testing it.

Then start a new function called create_tiles with no parameters and allocate the arrays for the tiles with a similar method to the one used for the table. Instead of the parameter "rows" you'll have to use sizeR this time, and instead of "cols", sizeC. Then inside the for loop, after initializing the array for the row i, let's add a loop that creates all the tiles for that row and places them in the appropriate position ("this" identifies the table object itself):
for (var j=0; j<sizeC; j++) {
  tiles[i][j] = new Tile(parent, table[i][j]);
  tiles[i][j].set_position(i, j, this);
  tiles[i][j].place(100*j, headspace+100*i);
  tiles[i][j].show_back();
}

Note that you have to replace the "100" by whatever size your tiles are. Add a call to this function in the constructor at the end.

The last step for now is to go back to the .fla file and test this. Add a line at the top importing the Table file. Then comment out the creation of the single tile by adding two forward slashes "//" at the beginning of every line to be commented out. The declare an object of type Table and with the parameters for the row and column having the values of whatever you want your final table to be, and this.stage passed in the third place for the parameter the_stage.

If everything went well and there are no errors, now you should see the whole setup of tiles, and when you click on all of them, they should show the image. You can verify that you have indeed the right tiles in a random order. When you run the program again, a different configuration should appear. You can tweak the position of the tiles at this point to make sure that they are well centered.

Back Start Over Next