I ran into some problems with handling the block sprites. I was basically just using the same built-in .x and .y properties built into flash sprites and adding some number to currentBlock.y in the event loop for gravity, and either adding or subtracting from currentBlock.x when a direction arrow was pressed. The problem with this was that it made collision detection a pain, and it also raised questions like what to do with a block partway between two square locations. In a game like Tetris or Blockout, the squares of the playing pieces have to fit into the squares on the board.

The way I decided to fix it was this-- give the block class getters and setters for x,y coordinates in terms of the grid of the playing area, not in terms of pixels on the screen. I made all animation in discrete 1 square increments and this also made collision detection much easier. Here's the top of my block class:

[as]
public class Block extends Sprite {
static const size:int = Board.gridSize; //size of the board's "squares"
static var list:Array = []; // for keeping track of all the blocks

var edge_color:int;
var inner_color:int;
var shape:Array;
var type:String;
var _gy:int; // the y position in grid squares rather than pixels
var _gx:int; // the x position in grid squares rather than pixels
var _gwidth:int;
var _gheight:int;
[/as]

And the getters and setters for the grid variables:
[as]
function get gy():int {
return ((this.y-Board.top)/ size);
}
function set gy(gy:int):void {
this.y = gy * size + Board.top;
}
function get gx():int {
return ((this.x)/ size);
}
function set gx(gx:int):void {
this.x = gx * size;
}
[/as]

With the convenience of these getters and setters, along with a few others for width and height of pieces in terms of grid squares, it made animation very easy. I didn't need to refer to x,y screen coordinates again in the block class and could just increment or decrement currentBlock.gx or currentBlock.gy by one to move a block one square. Collision detection was similarly simplified. Instead of needing to use hitTestObject() as I did in the other two games I've made, all that was necessary was 2 dimensional array of the playing grid, filled with zeros for empty locations and ones for locations with a block. Then, before moving a piece, I just check to see which grid locations the piece would occupy and not allow the move if they're occupied. For example, If I had a long thin piece occupying squares (5,4), (5,5), (5,6), and (5,7) then all I'd have to do is check (6,4), (6,5), (6,6) and (6,7). If all of them are unoccupied then I can increment currentBlock.gy and move the piece. Moving left, I'd check (4,4), (4,5), (4,6) and (4,7).

In retrospect it seems obvious that a grid representation would be the way to go for a game with pieces and a playing field broken up into discrete squares (or cubes for blockout), but it wasn't the first idea I had.

Leave a Reply

Your email address will not be published. Required fields are marked *