Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
96 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

  Contents

 Introduction
 Stepping to the
 plate...

 Mr. Structure
 The New Shape
 Maker

 Update takes a few
 practice swings

 Let's Get Moving!
 Time to Clear the
 Bases?

 The Final Batters
 The Loop and His
 Team

 Until Next Time...

 Printable version

 


  The Series

 Part 1
 Part 2
 Part 3
 Part 4
 Part 5
 Part 6

 

Stepping to the plate...

Animation is a very complicated player. He can play in many different ways, and has numerous styles. On our team, he has adopted the style commonly referred to as "Pre-Set." What this means is that everything that he does was determined before the game has even been started. This occurred in the initialization section, of course.

In our game we have single blocks that are selected at random. That random block is used with a random shape. The shapes that exist are the same ones as in the original Tetris. Now the animation sequences that are needed by the shapes are relatively simple ... you merely rotate the shapes. Therefore, I had three choices when deciding how to animate them.

  1. I could make bitmaps of every shape pre-built and rotate them at runtime as needed.
  2. I could do the same as above except pre-rotate them, then save many bitmaps and cycle through them at run-time as they are needed.
  3. I could build every shape from a block and use some sort of table to tell me how the shape was to be built for that frame.

Because of speed, and size, I decided to go with the third method. It is a little bit more complex ... but I think the speed gain, and size drop, is worth it. (NOTE: As a programmer, if you have the ability to make a piece of code more robust, more user-friendly, smaller, or faster then do so).

So, now that we know what we want, how do we accomplish it? Well, the first thing I did was sit down with a piece of paper, and determine the patterns that a shape could have. Then, I took those patterns, encapsulated them into mini-grids, and made them represent either ON, or OFF, states depending on if a block was in that position. Here is an example for a square.


0 0 0 0
0 1 1 0
0 1 1 0
0 0 0 0

Notice the grid is 4x4, the reason is because the largest a shape can be is four squares wide, or tall. The ones are the places were the blocks are and the zeros are empty locations.

With that gigantic list built, I needed a way to organize them into look-up tables. The decision was to pad the left of each line with four zeros and thus get an 8x4 grid. I could then use an array of four bytes for each frame where a single bit represented a block. This caused a 2-byte waste for every block ... yet it made the code about 100000 times easier to understand.

The table access is really simple. We just offset into the table according to the shape we want. Then, we offset into that address by the frame that we want. Every shape has four frames, no matter what, and are all aligned to four bytes. So, we can easily adjust our "frame pointer" with a few simple arithmetic operations.

That is how animation works in our game. You simply tell him when to adjust to a new frame and he does. Need a new shape? No problem, just point him where it is and he will know what to do.

Here is our table:

Popup : Source Listing 1




Next : Mr. Structure