Table of Contents

It's been a long time since I wrote my last article on the ASP.Net subject. This time I decided to write something about it, and more specifically, about ASP.Net MVC.

The MVC approach is, by far, my favorite way of doing things in ASP.Net. The simple fact that you don't have the code behind, nor view state, deserves much of my consideration.
That goes without saying that you don't care about post backs.

Also, the application uses the awesome jQuery library to make our lives easier. As the readers will see, I tried to use jQuery wherever I could. This library
is really a blessing for those of us developers who need to work on web applications.

To use the MVC Bricks game provided with this article, if you already have Visual Studio 2010, that's fine. If you don't, you can download the following 100% free development tool directly from Microsoft:

When the game starts, there is a simple jQuery animation, which makes the "MVC BRICKS" title raise up to the middle of the screen. This is accomplished by
animating the top css property of the title div:

The game is all controlled by the keyboard. When the game is in Intro mode, you can use the space bar to start a new game. When the
game is playing, you use the space bar again if you want to pause the game. And then use the space bar again to resume the game.
When the game is over, you push the space bar once again to open the game Intro screen.

Use the left arrow key and right arrow key to move the falling piece to the left or to the right. Press the up arrow key
to rotate the piece 90 degrees. Finally, press the down arrow key to speed up the fall of the piece.

You must be very familiar with this kind of game, but I have to explain the game rules anyway.

Here we have an empty 10 x 16 board, containing 160 empty positions. As soon as the game starts,
the game engine will randomly generate one new piece at a time, which will fall from the top of the
board, falling at the speed of 1 square per second. When the falling piece find an obstacle (that is,
part of another piece that is fixed at the bottom of the board) then it can't fall anymore, so that
falling piece gets stuck. Then the game engine will produce new random pieces, and they are piled up
until the pile reaches the top of the board, and at this moment the game ends. The user will have to
control each falling piece, by moving it to the left, to the right, or rotating it, placing the new
piece in the lowest possible empty place in the board where the new piece fits in, in a way to avoid
the piled pieces to reach the top of the board. Also, when the user fills any the board rows, these
rows are cleared, thus giving some extra space and prolonging the game.

The "I" shape

The "L" shape

The "J" shape

The "O" shape

The "T" shape

The "S" shape

The "Z" shape

The game engine can randomly generate any of the above shapes. As we can see, each shape is associated with a letter which resembles it.

For each cleared line, the user scores a total of 10 multiplied by the game level. That is, each row cleared in the first level will give 10 points. The second level
will give 20 points per cleared row, and so on.

Each level is completed when the user has cleared 10 rows. That is, to reach the 5th level, the user must have cleared 40 rows.

When the game is over, the game score is compared with the previous high score, and replaces it if there is a new record.

The Next piece gives the user the opportunity to place the current piece in a way that makes it easier to accomodate the next falling piece.

The beauty of MVC, as I see it, is its adherence to the principle of separation of concerns.
Unlike "classic" (non-MVC) ASP.net, you don't put business logic on your views. Instead, you use the views only for presentation logic (such as parsing and rendering of raw
data or input validation), and for presentation itself. On the other side, you reserve the Controllers (or another layer, such as Service layer) for your business rules.

If you look at the javascript in the application, you won't find the business logic. Instead, you'll find out that it is really thin and light. Fortunately,
since I already had the Bricks game logic from previous projects, I was able to maintain my managed code almost intact on the server side,
and make the view communicate with it through a new ViewModel I designed specifically for this MVC project.

The model is defined by the BoardViewModel and BrickViewModel classes, and contains all information needed
by the View to render the game board, the score board and to know whether the game is over or not. As we can see below, most of the properties
of BoardViewModel class are native types, except for the Bricks and Next properties, which are
2-dimensional arrays of the BrickViewModel and hold the data for the bricks and empty spaces that forms the current snapshot
of the game board and the bricks corresponding to the Next piece that will fall from the top of the game board.

The low-level BrickViewModel class has informations about each individual brick: row, column and the color name. These values
will be used by the View to find the corresponding divs and update their background color accordingly.

The view really contains no business logic (in our case, no game logic). Here we can see its basic goals:

Set up a timer, which calls the Controller every 200 milliseconds to get a ViewModel containing an updated game board snapshot (serialized as JSON).

Parse the returned JSON to render the board, score, high score, level and next piece.

Set up another timer that calls the Controller every 1000 milliseconds to request a new movement for the falling pieces.

Listen to the keyboard events, and calls the Controller to start a new game, to pause of resume the game, to move or rotate the falling piece, or to restart the game.

This is pretty much what the View does. Notice that, in a traditional (non-MVC) ASP.net application, we would have the code behind class, which would
probably hold some business logic. Thanks to MVC, the principle of separation of concerns is maintained, and we can move the business logic away from our View.

We handle user's gesture by attaching a function to the keydown event of the page document using jQuery syntax:

This happens because the bricks are divs generated dinamically, when the application starts. Instead of hard-coding this divs into
the html, the dinamic generation makes it a lot easier to control how the bricks are generated, how they are rendered and so on.

Here is the code that generates all the bricks, incluiding the bricks in the "Next" section on the score board. Notice how elegant is the jQuery
syntax for appending html to existing html elements:

One of the most important parts on the BricksView side is the game board rendering. Notice that we don't use
images for the bricks; instead, we use the CSS3 Webkit Gradient generator, which works only on CSS3 enabled browsers:

As we can see below, the Controller is even dumber than the View. Its goal is merely to expose actions
that are consumed/called by the view, call the hard-working method on the GameManager side, and return (or not) a JSON-serialized ViewModel.

As you might expect, the game must have a means to control the states, so that you don't have falling pieces before the game has started,
or after the game is over. Also, the score shouldn't be displayed while in the Intro mode.

At first I was using boolean variables on the javascript side to handle the game state (i.e. "isPlaying", "isPaused", "isGameOver", and so on),
but this didn't seem elegant nor efficient. So, at the middle of the development I noticed the application had to use a better state management,
such as a finite state machine (FSM). So I searched and finally found out a simple, easy-to-use
finite state machine for JavaScript, written by Anthony Blackshaw.

The implementation for Blackshaw's FSM is quite simple. First, you declare a state machine object (in our case, gameState). Then you add transitions
to the state machine instance. Each transition defines:

The play action hides the subtitle, and animates the top of the title o the position 0 (top of the screen). Besides,
both the scorePanel and the boar are made visible thanks to an fade-in effect animation on
their opacity css property..

The pause itself in the game play happens because the state is switched to "paused" and as
we can see below, the controller's action is not called unless the game state machine is on the "playing" state:

The GameManager is a class that holds all methods needed by the BricksController
so that the BricksView requests can be communicated to the game engine, and the responses can be sent back
to the BricksView.

Thanks a lot for reading my MVC Bricks article. I hope it may be useful for you in some way, either by the MVC concepts covered here, or the jQuery syntax which makes
the javascript section thin and elegant, or even because the fun of the game itself. Feel free to comment below. Please share your ideas, complaints, advices so the
next articles will get better and better.

Share

About the Author

Marcelo Ricardo de Oliveira is a senior freelance 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.