Click here to Skip to main content
Click here to Skip to main content
Go to top

Bricks for Pocket PC

, 24 Apr 2008
Rate this:
Please Sign up or sign in to vote.
A .NET Compact Framework version of the Bricks game.

Bricks

Introduction

I present two simple versions of the well-known brick game for Pocket PC. In this article, I'll present some techniques used to develop the game, also providing the source code. I hope the reader enjoys it, because for me it was a real treat.

The first version is the classic one, with the colored blocks falling from the top. With the second version, the pieces are composed of balloons instead of bricks, and the user has to correctly place them in lines on the top of the screen as the balloons go up.

I should say that I was motivated mainly by the fabulous work of Jonas Follesø in his article Pocket 1945 - A C# .NET CF Shooter. That article was uploaded to The Code Project in 2004, and is still impressive (and will continue to be impressive for many years). So, after reading the "Pocket 1945" article, I decided to write a game myself, and I ended up borrowing some of the concepts Jonas used in his game.

Background

The first brick game was programmed in 1985 by Alexey Pajitnov while he was working for the Dorodnicyn Computing Centre of the Academy of Science of the USSR in Moscow (thanks, Wikipedia). The game was virtually ported to every known platform, and was even played with human beings instead of the traditional colored bricks (see video).

The Game

Basically, Bricks! is a never-ending puzzle of 4-segment pieces. There are 7 types of pieces (that I call "I", "J", "L", "O", "S", "T", and "Z" in the game), and only one piece falls at a time from the top of the game board. The type of the tetromino is produced randomly. Every time the player fills a row in the board, that row is removed and the bricks above collapse, making room for more pieces to go.

Every time a row is completed, the player scores 10 points, multiplied by the number of the game level. A new level is reached every time the player completes 10 lines.

Application Design

The solution comprises of two projects: Bricks4Pocket and Bricks4Pocket.Core. The first basically contains the UI components, while the second contains the hard-work functionalities. I believe that just a few classes from the project are worth mentioning here.

I decided to use a simplified MVP (Model-View-Presenter) pattern in the game. In doing so, I could enforce the separation of concerns by assuring that the UI component would only respond passively to the events thrown by the Presenter component.

The Code

The game has two main entities: the shape (BaseShape-inherited classes) and the board (the BricksBoard class). Both inherit from the BaseBricksArray abstract class that implements a bi-dimensional array of bricks (Brick class).

protected IBrick[,] shapeArray = null;

The heart of the game is the BricksBoard class. It contains a 10 x 16 array of bricks, and also the game logic functionalities such as moving and rotating a piece according to the arrow buttons, testing whether a piece can still be moved, deciding if there are completed rows that must be removed, and deciding when the game is over.

As soon as the game starts, the GetRandomShape is invoked, and a shape of a random type and a random color is created:

private IShape GetRandomShape()
{
    IShape newShape = null;
    Random randomClass = new Random();
    int randomCode = randomClass.Next((int)ShapeCodes.Stick, 
                                      (int)ShapeCodes.Z + 1);
    .
    .
    .

Before every move attempt, the BricksBoard class will invoke the TestPieceOnPosition method, to assure that the shape will not go off board and will not collide with other bricks in the board.

public bool TestPieceOnPosition(IShape shape, int x, int y)
{
    for (int row = 0; row < shape.Height; row++)
    {
        for (int column = 0; column < shape.Width; column++)
        {
            //is the position out of range?
            if (column + x < 0)
                return false;

            if (row + y < 0)
                return false;

            if (column + x >= width)
                return false;

            if (row + y >= height)
                return false;

            //will the shape collide in the board?
            if (
                shapeArray[column + x, row + y] != null &&
                shape.ShapeArray[column, row] != null)
            {
                return false;
            }
        }
    }
    return true;
}

If the piece can be placed according to the move attempt, then the method PutPieceOnPosition is invoked in order to transfer the bricks from the shape to the board.

The MoveLeft and MoveRight methods of the BaseShape class just move the bricks of the shape to the left or to the right, if possible:

public bool MoveLeft()
{
    bool test = false;
    if (!anchored)
    {
        if (containerBoard == null)
            throw new NullContainerBoardException();

        containerBoard.RemovePieceFromCurrentPosition(this);

        test = containerBoard.TestPieceOnPosition(this, this.X - 1, this.Y);
        if (test)
        {
            containerBoard.RemovePieceFromCurrentPosition(this);
            containerBoard.PutPieceOnPosition(this, this.X - 1, this.Y);
        }
    }
    return test;
}

The Rotate90 and Rotate270 methods implement the clockwise and counterclockwise rotations for a shape, respectively. This is done by transposing the bricks from the columns to the rows of the shape, before trying to put the shape on the board:

public bool Rotate270()
{
    bool test = false;
    if (!anchored)
    {
        if (containerBoard == null)
            throw new NullContainerBoardException();
        
        containerBoard.RemovePieceFromCurrentPosition(this);
        
        IBrick[,] newShapeArray = new IBrick[height, width];
        IBrick[,] oldShapeArray = new IBrick[width, height];
        for (int row = 0; row < height; row++)
        {
            for (int column = 0; column < width; column++)
            {
                newShapeArray[row, width - column - 1] = shapeArray[column, row];
                oldShapeArray[column, row] = shapeArray[column, row];
            }
        }
        .
        .
        .
    }

For the key-handling capabilities, I merely copied the Input class from Jonas Follesø's article. Besides, I created a InputBuffer class that encapsulates the Input class. The InputBuffer class has the ability to process buffered keystrokes, and also allows that views can subscribe to the utility class. I do this by implementing the Observer Pattern in the InputBuffer class and in the subscriber view:

public void AddObserver(IInputObserver observer)
{
    observers.Add(observer);
}

History

  • 2008-04-24: Initial posting.
  • 2008-05-01: Code and article renaming; Input problem solved; New game Ballons! added.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Marcelo Ricardo de Oliveira
Software Developer
Brazil Brazil
Marcelo Ricardo de Oliveira is a senior software developer who lives with his lovely wife Luciana and his little buddy and stepson Kauê in Guarulhos, Brazil, is co-founder of the Brazilian TV Guide TV Map and currently works for ILang Educação.
 
He is often working with serious, enterprise projects, although in spare time he's trying to write fun Code Project articles involving WPF, Silverlight, XNA, HTML5 canvas, Windows Phone app development, game development and music.
 
Published Windows Phone apps:
 
 
Awards:
 
CodeProject MVP 2012
CodeProject MVP 2011
 
Best Web Dev article of March 2013
Best Web Dev article of August 2012
Best Web Dev article of May 2012
Best Mobile article of January 2012
Best Mobile article of December 2011
Best Mobile article of October 2011
Best Web Dev article of September 2011
Best Web Dev article of August 2011
HTML5 / CSS3 Competition - Second Prize
Best ASP.NET article of June 2011
Best ASP.NET article of May 2011
Best ASP.NET article of April 2011
Best C# article of November 2010
Best overall article of November 2010
Best C# article of October 2010
Best C# article of September 2010
Best overall article of September 2010
Best overall article of February 2010
Best C# article of November 2009

Comments and Discussions

 
GeneralVGA Pinmemberjoubertvasc25-Jan-09 6:48 
GeneralRe: VGA PinmemberMarcelo Ricardo de Oliveira25-Jan-09 12:58 
GeneralThank You and, please, let me know if you have similar links. PinmemberKadetz14-Dec-08 6:38 
GeneralRe: Thank You and, please, let me know if you have similar links. PinmemberMarcelo Ricardo de Oliveira15-Dec-08 4:15 
GeneralInput problems PinmemberATM_Guy29-Apr-08 9:46 
GeneralRe: Input problems PinmemberMarcelo Ricardo de Oliveira30-Apr-08 12:39 
GeneralGreat article PinmemberPeter Kohout25-Apr-08 2:59 
GeneralRe: Great article PinmemberMarcelo Ricardo de Oliveira25-Apr-08 7:26 
GeneralA few issues you will have to fix PinmemberThomas Stockwell25-Apr-08 2:38 
GeneralRe: A few issues you will have to fix PinmemberMarcelo Ricardo de Oliveira25-Apr-08 7:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140922.1 | Last Updated 25 Apr 2008
Article Copyright 2008 by Marcelo Ricardo de Oliveira
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid