In this Delphi game tutorial we are going to show you how to program the popular falling bricks game. There are many variants of this type of game, here we will explain the basic algorithm and provide full Delphi 7 source code for download
In this game, there are a number of bricks on a wall, and each of these bricks has a color out of "n" colors.
When the player clicks on a brick, the whole block of bricks of the same color disappears and the upper bricks fall down and fill the positions of the removed ones.
Whenever a column becomes completely blank, all of the columns to the right of it are shifted one column left.
The purpose of the player is to remove a block with maximum number of bricks at a time.
Again, we will use a drawgrid with fixed number of rows and columns. The cell sizes will also be fixed. Customization issues are straightforward and they are left to the reader.
First of all, please follow the steps below:
We make the DefaultDrawing property false, because if we don’t, the changes we make to the cells are overriden. So, don’t forget to change this value.
Finally, arrange the size of the drawgrid and the form in order to get rid of unnecessary blank space on the drawgrid and on the form and thus obtain a proper appearence.
If you don’t think to provide the user a customizable game with rearrangable number of rows, number of columns and cell sizes, prevent the user from resizing or maximizing the form in order to prevent an unaesthetic appearance. You can do this by assigning the appropriate values to the BorderIcons and BorderStyle properties of the form by using the Object Inspector, or you can assign these values explicitly in your code.
At the beginning of each new game, we have to assign a color among a number of colors to each cell on the grid.
Actually, we can select a color randomly from the whole color spectrum an assign it to a cell. But since it is possible that any two or more bricks can be assigned two distinct colors but undistinguishable by the human eye (for example two very close tones of red), it is better to select the colors discretely from a predetermined color array.
For this purpose, we need a constant array declaration similar to the following:
const MAX_COLORS = 3; const PossibleColors : array [0..MAX_COLORS-1] of TColor = (clRed, clBlue, clGreen);
Here, we defined MAX_COLORS (the maximum number of colors) to be 3. If you want to add new colors to the PossibleColors array, you should also change the MAX_COLORS value accordingly.
We also need a 2-dimensional array to keep the corresponding colors of the bricks. But what will be the dimensions of this array? It is better to introduce new constants such as MAX_COLUMNS and MAX_ROWS and use these in the array declaration. It is good to do like this for future changes in the code. So, please add the following constant declarations:const
const MAX_COLUMNS = 20; MAX_ROWS = 20;
Now, we can declare our array that will keep the brick colors:
var ColorOfBrick : array [0..MAX_COLUMN, 0..MAX_ROW] of TColor;
Please note that the first index denotes the column, and the second one denotes the row.
I think there is no need to mention that all of the declarations made above are global.
Now, we need a procedure that will assign the colors of the bricks randomly. The following procedure will do that:
procedure AssignBrickColors; var i, j : integer; begin for i := 0 to frmMain.DrawGrid.ColCount-1 do for j := 0 to frmMain.DrawGrid.RowCount-1 do ColorOfBrick[i][j] := PossibleColors[Random(MAX_COLORS)] end;
As you can understand from the code, it assigns one of the colors from the possible colors randomly at each time to a cell.
Note that we used the built-in Random() function in this procedure. If you don’t want the random seed to be the default one, you should also call the built-in Randomize() procedure once before the first to the Random() function, in order to assign a seed. Otherwise, you will get the same sequence of random numbers at each game, which is not desired.
We can call it in the creation of the main form:
procedure TfrmMain.FormCreate(Sender: TObject); begin Randomize end;
We have told that we need to assign the colors of the bricks at the start of each new game.
Let’s first add a main menu on our form and add an item named itemNewGame with the caption “New Game”. This will enable the player to start a new game whenever he/she likes to do so.
In the OnClick event of itemNewGame, we should call our AssignBrickColors procedure:
procedure TfrmMain.itemNewGameClick(Sender: TObject); begin AssignBrickColors end;
If you want a new game to be started automatically when the application is started, you can call itemNewGame.Click on the creation of the main form:
procedure TfrmMain.FormCreate(Sender: TObject); begin Randomize; itemNewGame.Click end;
We will use the OnDrawCell event of the draw grid. This event is fired whenever a cell needs to be redrawn. But we will also call this event explicitly in our code whenever necessary.
procedure TfrmMain.DrawGridDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); begin DrawGrid.Canvas.Brush.Color := ColorOfBrick[ACol][ARow]; DrawGrid.Canvas.FillRect(Rect) end;
Here, we want it to fill the rectangle determined by the Rect parameter with the corresponding color of the brick that is characterized by the column ACol and the row ARow.
Now, run your application. You’ll see an appearance similar to the below one:
Now, click on the “New Game” item on the main menu. Thus the bricks will be assigned new random values. But what is that? The appearance remains the same?
That is because, the cells do not need to be redrawn at the moment. After clicking on “New Game”, if you move the form towards the outside of the screen and pull it back, you will notice that the cells which have just gone to the outside of thescreen have now their new colors, because they needed to be redrawn.
If you enjoy addictive games you should probably check out Game Addicts, a blog on all the latest gaming news.