Ultra-Kit: BLOCKOUT

 

 

 

[NOTE: Before you can use this kit, you must first copy
its source listing file into your project's "Library" folder.]

 

 


 

 

The BLOCKOUT Ultra-Kit lets you create your own "Ball & Paddle" types of games.

 

But before you begin, first make a print-out of these instructions (by clicking on the word 'File' in the menu bar, and selecting the 'Print...' option).  You will want to follow that printed-out version as we work through the programming exercises.

 

 

How to Use the BLOCKOUT Ultra-Kit

 

The kit consists of eleven new tasks. They are:

 

bugle

booboo

pop

border

tile

paddle

moveball

zaptile

english

square

zapsquare


For a brief description of what each task does, click here.

 

Before we start creating an actual game, let's first play with some of the kit's tasks so that we can get familiar with them:

 

The "bugle" task (which can be used to let the player know that he/she has won) plays a familiar tune.  Let's test it out by writing the following short program:

 

          Ultra-SiMPLE

          Call bugle @

          Append L: kit

 

The "booboo" task can be used to let the player know that he/she has lost.  Let's test it out by writing the following short  program:

 

          Ultra-SiMPLE

          Call booboo @

          Append L: kit

 

The "border" task draws a gray frame around the outside of the screen.  This established the playing field for the game.  Let's test it out by writing the following short program:

 

          Ultra-SiMPLE

          border @

          Append L: kit

 

(Note: You should not use the system library's "Frame" task to draw the border because it creates a frame that is slightly too small for our purposes.)

 


 

The BLOCKOUT Ultra-Kit uses two basic coordinate systems.  One is the standard 640x480 pixel coordinates system.  The other is a tile coordinate system in which the screen is divided into an array of tiles (1-15 horizontally, 1-22 vertically) as shown in the following illustration:

 

 

Each tile measures 40x20 pixels.  Location (1,1) is the tile in the upper-left corner of the screen, and location (15,22) is the tile in the lower-right corner of the screen.

 

The proper coordinate system to use (pixel or tile) should be obvious, depending on the task being invoked.

 

All angles in the kit are measured clockwise from "north" (or "up" on the screen), and are expressed in units of "quants" (65536 quants = 360 degrees).  Therefore "east" (or "right") would be at an angle of +16384 quants, and "west" (or "left") would be at an angle of -16384 quants.

 

The "tile" task draws a colored tile at a specified location on the screen.  (The location is specified in tile coordinates, of course, and the color of the tile can range from 9 through 14 inclusive.)  Let's test out the task by writing the following program which draws three different colored tiles inside a gray frame:

 

          Ultra-SiMPLE

          Call border @

          Call tile (5, 3, 12) @

          Call tile (12, 6, 14) @

          Call tile (9, 9,  9) @

          Append L: kit

 

Go ahead and change some of the calling parameter values in the program to see how they affect the locations and colors of the tiles.

 

In these examples (and in most of the listings that follow), we have chosen to run our programs in full-screen mode. However, if you would prefer to run them in a window, just add the customary "[]" characters following the "Ultra-SiMPLE" compiler directive. If so, you will also want to speed up the programs by specifying a delay of zero in all of the delay-producing statements (such as "waitquitkey").

 

If you choose to include the asterisk character (to implement the "myquit" feature in either full-screen mode or window mode), the programs will thank the player for playing when they quit.

 

 

Ok, Let's Start Making a Game!

 

Perhaps the best way to investigate the remaining tasks in the kit is to start creating an actual game, from the ground up.

 

The following program merely draws a frame, a paddle, and a bouncing ball. Pressing the "Esc" key exits the program.  (See how long you can trap the ball underneath the paddle. But, if you chose to run the program in a window, make sure that you keep your mouse inside the window. . . or else you won't be able to control the paddle!)

 

       Ultra-SiMPLE

 

       Int x, y, z

       hide mouse

       border @

       xball=320.0; yball=400.0; vector=2500

       Do

          read mouse (x, y, z)

          paddle (x, 420, 40) @

          move ball (xball, yball, vector) @

          wait quit key (27, 2)

       Loop

 

       Append L: kit

 

(If you are still uncertain about expressing angles in units of "quants", you might want to experiment with different values for "vector" to see how it affects the initial direction that the ball moves.)

 

The above program, as it stands, is not yet a game.  It's simply illustrates how some of the modules can be used together to create the beginnings of a game.  We will now, in a step-by-step fashion, actually convert the above program into a playable mini-game.

 

Let's start out by adding another "Do-Loop" (shown below in Green)* which draws a row of red tiles across the top of the playing field:

 

       Ultra-SiMPLE

 

       Int x, y, z

       hide mouse

       border @

       Do k=1,15

          tile (k, 5, 12) @

       Loop

       xball=320.0; yball=400.0; vector=2500

       Do

          read mouse (x, y, z)

          paddle (x, 420, 40) @

          move ball (xball, yball, vector) @

          wait quit key (27, 2)

       Loop

 

       Append L: kit

_________________________

 

*(As we progress from step to step, the new statements which have

just been added to the listing will always be shown in Green.)

 

It's starting to look better.  But there are still many obvious problems.  For one thing, whenever the ball hits one of the tiles, it just bounces off.  Let's fix that problem by erasing any tile that comes in contact with the ball:

 

       Ultra-SiMPLE

 

       Int x, y, z

       Int num, pdl, wall, other

       hide mouse

       border @

       Do k=1,15

          tile (k, 5, 12) @

       Loop

       xball=320.0; yball=400.0; vector=2500

       Do

          read mouse (x, y, z)

          paddle (x, 420, 40) @

          move ball (xball, yball, vector) @

          zap tile (num, pdl, wall, other) @

          wait quit key (27, 2)

       Loop

       Append L: kit

 

Now whenever the ball hits a tile, the tile is erased.  But, even when all the tiles are gone, the ball still keeps on bouncing...and bouncing....  Let's fix that problem by keeping track of how many tiles remain in the playing field.  Then, when all tiles are gone, we'll end the program:

 

       Ultra-SiMPLE

 

       Int x, y, z

       Int num, pdl, wall, other

       hide mouse

       border @

       Do k=1,15

          tile (k, 5, 12) @

       Loop

       tiles=15

       xball=320.0; yball=400.0; vector=2500

       Do

          read mouse (x, y, z)

          paddle (x, 420, 40) @

          move ball (xball, yball, vector) @

          zap tile (num, pdl, wall, other) @

          tiles=tiles-num; If !tiles Break

          wait quit key (27, 2)

       Loop

 

       Append L: kit

 

Ok, but there's still at least one really big (and obvious) problem:  It doesn't matter whether the ball hits the paddle or not.  Either way, the "game" continues on.  So let's add a check to determine when the ball hits the bottom wall of the frame and, if it does so, end the program:

 

       Ultra-SiMPLE

 

       Int x, y, z

       Int num, pdl, wall, other

       hide mouse

       border @

       Do k=1,15

          tile (k, 5, 12) @

       Loop

       tiles=15

       xball=320.0; yball=400.0; vector=2500

       Do

          read mouse (x, y, z)

          paddle (x, 420, 40) @

          move ball (xball, yball, vector) @

          zap tile (num, pdl, wall, other) @

          If wall=4 Or wall=6 Or wall=12 Break

          tiles=tiles-num; If !tiles Break

          wait quit key (27, 2)

       Loop

 

       Append L: kit

 

(Notice that we must not only check for the ball hitting the bottom wall (wall=4), but also for it hitting in the bottom corners as well.)

 

It sure is annoying when the "game" ends and we have manually restart it if we want to try again.  It would be nice if we could simply press a key on the keyboard to restart.  So let's embed our whole program in another "Do-Loop", and wait for any key (except the "EsC" key, of course) to be pressed:

 

    Ultra-SiMPLE

 

    Int x, y, z

    Int num, pdl, wall, other

    hide mouse

    Do

       cls; border @

       Do k=1,15

          tile (k, 5, 12) @

       Loop

       tiles=15

       xball=320.0; yball=400.0; vector=2500

       Do

          read mouse (x, y, z)

          paddle (x, 420, 40) @

          move ball (xball, yball, vector) @

          zap tile (num, pdl, wall, other) @

          If wall=4 Or wall=6 Or wall=12 Break

          tiles=tiles-num; If !tiles Break

          wait quit key (27, 2)

       Loop

       If (waitkey()=27) quit

    Loop

 

    Append L: kit

 

We've come a long way, but there's still a subtle problem remaining:  We have no control over the ball.  When it hits the paddle, the ball always bounces off at the same angle.  It would be nice if we could put some kind of "English" on the ball, depending on what point on the paddle it hits.  In addition, we'd also like to add a few other embellishments, such as:

 

               *  putting more rows of tiles in the game!

               *  having the paddle shrink slightly as the game progresses!

               *  exploding the ball when it hits the final tile!

               *  thanking the player for playing the game!

 

And here they all are:

 

    Ultra-SiMPLE *

 

    Int x, y, z

    Int num, pdl, wall, other

    hide mouse

    Do

       cls; border @

       Do k=1,15

          tile (k, 5, 12) @

          tile (k, 8, 14) @

          tile (k, 11, 9) @

       Loop

       tiles=45

       xball=320.0; yball=400.0; vector=2500

       Do

          size=tiles+15

          read mouse (x, y, z)

          paddle (x, 420, size) @

          move ball (xball, yball, vector) @

          zap tile (num, pdl, wall, other) @

          If (pdl) english (vector) @

          If wall=4 Or wall=6 Or wall=12 Break

          tiles=tiles-num; If !tiles Break

          wait quit key (27, 2)

       Loop

       If (tiles) booboo @

       Else explode (int(xball),int(yball)) @toys

       If (waitkey()=27) quit

    Loop

 

    Append L: kit

 

(By the way, if you'd like to see something pretty cool, temporarily replace the  "read mouse (x, y, z)statement with a:  "Set x=xball"  statement, and watch the game play all by itself!)

 

Of course there are still many other embellishments that you can make to the program (like incorporating two or more paddles on the screen, adding sound effects, etc.)  We will let you add these features on your own.  But if you would like to see one of the ways we chose to embellish the game, you are invited to click here.

 

 

The TRAPPED! Program

 

Two of the tasks ("square" and "zapsquare") in the kit are very similar to the "tile" and "zaptile" tasks, respectively.  (A 20x20 pixel "square" is essentially a "half-tile".)  The only reason they have been included in this kit is so that they can be invoked by the TRAPPED! demo program.

 

TRAPPED! is merely a "screen saver" in which a bouncing ball is trying to escape from a field of square tiles that are constantly being generated.  (The rate at which tiles are created increases as you move away from the center of the field.)

Program Listing

Will the ball ever escape?  And if it did, would it ever be able to get back inside again?  (Inquiring minds want to know!)

_________________________________________________

 

www.simplecodeworks.com