Tetris Guts (a tutorial on Flash game programming (AS3))

I’m pretty new to flash/actionscript – and this tutorial is more of a “learning log” than well developed material. Just keep that in mind!

***

SOURCE DOWNLOAD

This portion of the tutorial is a general overview. The exact details can be found in the (heavily commented) program files.

 This is a slightly simplified version of the game actually posted on this website, in that I removed music, the splash screen and PHP interfacing to 1.) keep file size down, 2.) not divulge the specifics of my leaderboard implementation, but mainly 3) to keep things relatively simple.

This tutorial covers:

- Fast graphics via copyPixels (from a sprite sheet). Not that fast graphics are necessary for this game, but it’s a convenient way to do it with sprite sheets (since no rotation or other tranforms of the graphics are required).
- Handling game logic (scoring, level, game over, pause, etc)
- Basic keyboard input
- Object Orientation in ActionScript 3.

Overview

The general program flow is this:

  • Set up drawing drawing surfaces (Bitmap and BitmapData objects attached to MovieClip objects).
  • Initiate game logic.
  • Initiate game loop when user starts game:
    • Apply user input to game objects
    • Update game objects (“step the world”)
    • Check for states in which actions need to occur (i.e. collision, row delete).
    • Draw screen
  • Set game to “over” state when a “losing” condition has been detected.
  • Wait for user to restart game -> Clear game over flag and re-initiate game logic


Objects

Tetris Screen ShotThere are 3 classes defined in the code.

  • The main application (Tetris.as) – created when the swf loads. All game logic, control and display is handled here.
  • The Body’s (Body.as). There are always 2 Body’s in existence. When a Body is created, it creates 4 Block objects in a certain pattern, making one of the seven standard Tetris pieces.
    • The current body is under the control of the keyboard
    • The next body is waiting in line to become the current body. It is necessary to have this body defined ahead of time so it can be shown in the preview pane.
  • The Block’s (Block.as). The Body’s are constructed of blocks, and when a Body “dies” (reaches the “ground”), it is converted to stand-alone Block’s – no longer part of a Body.


Collision Handling

When the current Body’s position updates, via the game or user input (pressing the up/down arrow), the game checks for 3 types of collisions.

  • Horizontal Collisions – if a Block within a Body is found to be overlapping another Block, then the code rewinds the Body to it’s previous position, moving it back into a valid state. The user never sees the overlap, because the collision is detected and rewound BEFORE anything gets drawn to the screen. No further action is taken.
  • Rotational Collisions – are handled seperately because it’s more complex to rewind, and you don’t want to waste time looking for a rotate collision unless the user had actually rotated. So while a horizontal collision check takes place on every frame, the rotation collision check takes place ONLY IF the user has pressed the up arrow.
  • Vertical Collisions – this is where the fun really starts. If there has been a vertical collision, then
    • The Body needs to be rewound
    • We need to check the position of the Body – if it hasn’t moved, then previous Body deaths must have stacked all the way to the top, and the game is over. Game ends here.
    • If the game hasn’t ended: Since this was vertical, the block has reached the ground, and must “die.” The Body’s 4 Blocks are copied into an array of Blocks in the main application (they are no longer within a Body).
    • The pointer to the current Body is re-pointed to the next Body.
    • The next Body is assigned to a new Body.
    • Now we have to check to see if the Body death resulted in a filled row, which would need to be removed/score incremented, etc.
      • When a Body dies and the Blocks are copied to the main application, for each Block that is copied, a variable holding the sum of the blocks in the row is incremented.
      • If that sum reaches 10, then the row has been completely filled.
      • If the row is completely filled then:
        • Delete that row of blocks (via an array splice)
        • Push a new row to the top of row array.
        • Shift every block above that row down.
        • Increment the score.

Drawing

Drawing is achieved with copyPixel.

  • When the swf loads, a bitmap object is created from the library MovieClip “BlockMap”, which looks like this:BlockMap
  • Each Body type has an ID, 0 to 6 (for the 7 Tetris shapes). Each Block knows what type of Body it belongs to. When it comes time to draw a block to the screen, the code takes the blocks type, multiplies it by the blocks width, and gets a number of the value 0, 30, 60, 90, 120, 150, or 180. Since each block in the BlockMap is drawn at block width, that list of numbers corresponds to the x-value of that blocks sprite (lost yet?). For example, if we want to draw a block of type 3, the function called is: gameScreen.copyPixels(blockMap, new Rectangle(3 * 30, 0, 30, 30), new Point(x,  y));This is simplified so you don’t get lost in the details at this point. Basically it’s saying: Copy the portion of the bitmap blockMap within the 30 x 30 square whose upper left corner is at 90. Place it on the game screen @ (x, y). That would draw an orange block to the point x, y.


Final Notes

This implmentation could be vastly improved. For one thing, the entire game pane is cleared on every frame. That is horribly wasteful, as the only thing  changing is the one block that’s moving – so really, only it’s bounding box needs to be cleared. I’m sure there are lots of other little things, but due to 1.) my limited knowledge of flash/actionscript, 2.) my desire to keep this tutorial relatively simple, but still produce a perfectly functional application, and 3) my laziness, those details are left as an excercise for the reader. ; )

One detail that is sure to cause confusion is how to get the coordinates at which a block must be drawn. In Body.as, each Tetris shape is defined by an array of x values, and an array of y values. For a Line shape, the coordinates would be:

x = {0, 0, 0, 0}
y = {2, 1, 0, -1}

So each block has it’s own coordinate within the body. And then you have the Body’s position on the screen. So to get the position of an individual block on the screen, you have to add the Block’s local position to the Body’s world position:

BlocksTruePosition = BodysPositionOnScreen + BlocksPositionInBody

Again, the code is heavily commented, so if you understand the theory, the rest is just syntax.

SOURCE DOWNLOAD

  • Print this article!
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • StumbleUpon
  • Yahoo! Bookmarks

Tags: , , ,

12 Responses to “Tetris Guts (a tutorial on Flash game programming (AS3))”

  1. Jun Jiao says:

    Hi!

    I downloaded your source code of Tetris.

    When compiling the code, I got this error message in Tetris.as : “cnvMain not defined”.

    There are also serveral other variables such as BlackMap, txtBtnrestart undefined too.

    The ide I’m using is Flex Builder 3.

    How can I compile your code?

    Thanks!

  2. Anthony says:

    Hi,

    I’m sorry – I don’t know anything about Flex. So all I can tell you is that cnvMain is an instance of the flash library symbol “canvas”. The other undefined variables are also instances of library symbols. Maybe look up “importing flash library symbols” or something in Flex’s help. Good luck!

    Anthony

  3. John says:

    Thank you very much. I’m writing a block based game that is marginally similar to Tetris, and I needed a jumping-off point. Your open source has provided just that.

  4. [...] public links >> spritesheets Tetris Guts (a tutorial on Flash game programming (AS3)) First saved by Yaneey | 1 days ago 2D Animation Content Pipeline First saved by musikl | 22 [...]

  5. Brian says:

    Nice …..

    but

    Source Download link is not working anymore.

    Anyone have a download location?

    Thanks

  6. mindfocker says:

    cool! working on a tetris clone right now, for learning purposes.
    download link is down btw.. hope you get it fixed. :)

  7. Anthony says:

    Sorry about that – download link is working now.

  8. Sj says:

    Cool, Thunks, Brain

  9. Tammzak says:

    Hey,

    Thanks for the source code and tutorial for this great game.

    Is it possible to get the source code and/or tutorial on your leaderboard implementation. I would really want that too but I just don’t know how to start it.

  10. Denny says:

    thanks man im not using it for anything just building up my knowledge for code i’ll post if i ever make anything using similar code

  11. John says:

    Hey,

    Thanks for the code. We used the source from this tutorial as the basis for a two player flash game that integrates tetris and a vertical shooter.

    Here’s a download link if you’re interested:
    http://www.filedropper.com/tetrisworlddefense

  12. yyzz990 says:

    Thanks for you code,it is a good tutorial for me

Leave a Reply

Spam Protection by WP-SpamFree