BrainBlitz.org

April 25, 2010

AS3 Pathfinding and Game Source

Filed under: Programming — Tags: , , , , — Anthony @ 9:11 am

Here is the somewhat-polished version of my pathfinding/game application, all heavily commented in tutorial format for your analyzing pleasure. New to the demo is graphics displaying the internal workings of the pathfinding and collision detection, less brain-dead AI and the ability to add stuff to the map. 

Here is the application: 
Create a few “guys,” click to select, click elsewhere to move. Or add a tower near the guys.
Ctrl+Click to add multiple units; Escape to cancel character selection or drop the current “tool.”
 

Here is the code. 

A few observations: 

  • I  have dubbed my primitive A* pathfinder “AStarOrthogonal” to make it clear: this pathfinder does not work diagonally.
  • I’m still working out some glitches in the “dynamic” collision handling (between mobile units, mainly on head-on collisions). Sometimes the movement isn’t quite right, and sometimes characters end up coinciding. This isn’t a problem with the pathfinder, it’s with the “game” code–specifically the Character “state machine.”
  • The first red cell leading character movement is the square currently tracked by the pathfinder. The leading-leading square is not used at the moment, but I’m experimenting with better collision avoidance by utilizing that future location.
  • If you’re going for something along the lines of the typical, ubiquitous “Tower Defense” game, I’ve already written half the code for you. : )

A couple of technical notes: 

  • This is a learning process for me; keep that in mind. I am but a lowly game programming “hobbyist.” So, if you’re learning from this, don’t assume that everything I’ve done was done the “best” way.
  • If you’re using Flash, CS4 is required by the POLYGONAL data structures library. If you don’t use another IDE (i.e. Flex) and you don’t have CS4, I have at this point only used Singly Linked Lists and Doubly Linked Lists from the library, so it should be easy to find another library that does the trick.

Resources: 

  • The code download includes the POLYGONAL data structure library from http://code.google.com/p/polygonal/wiki/DataStructures. I’ve included the library for convenience, but you might want to check the project home to be sure and have the latest version.
  • As in all my demos, the non-original graphics are from, or are derived from, the work of Azure Flame.
  • Print this article!
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • StumbleUpon
  • Yahoo! Bookmarks

June 22, 2008

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

Filed under: Programming — Tags: , , , — Anthony @ 9:03 pm

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

Powered by WordPress