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