BALLOON.WS4 ----------- - "Writing Animated Computer Games" Tony Estep BYTE, Vol.4, No.11, November 1979, p.152 (Retyped by Emmanuel ROCHE.) It has been quite some time since the arrival of memory-mapped I/O boards upon the amateur computer scene, but the voluminous home computer literature rarely contains any listings of animated video games. Since it seems to me that there breathes not a hobbyist with soul so dead that he would not play one of these devilish little time wasters if he had one, I concluded that, perhaps, the lack of video games was due to some lack of information about how to get one up and going. This was certainly the case with me; I just started with a blank piece of paper and began scratching. But, as the reader will see, there really is no mystery to it, and the results are well worth the effort. A video game works just the same as an animated cartoon; there are a series of frames, each of which shows one or more of the objects in the picture in a slightly different position. Since the viewer's visual system has a certain persistence, the effect is one of continuous motion. In the case of a television picture, each frame is a single rewriting of the raster. This is very fast, and the flicker is seldom noticeable. A computer can pop information in and out of screen memory much faster than the monitor can rewrite its screen, so the programmer might think that computer games could represent extremely smooth movement. However, the movement has to be represented in finite increments, which will be determined by the minimum distance between the characters or points that can be written on the screen. In the case of a typical video display board which can put 1024 characters on the screen (ROCHE> That is to say: a 16x64 screen...), the user must move in increments of 1/16th the height of the screen when moving vertically, and 1/64th the width of the screen when moving horizontally. This means that the movement will necessarily be a little jerky, but smooth enough for games. The whole essence of writing an animated game is to put a picture on the screen, leave it there for a short length of time, then write blanks over the parts wanted to be moved, and rewrite them in the next space of the motion sequence. After another delay, the process is repeated. It does not take much thinking to realize that the main body of the game will be a loop with these essential elements, plus whatever keyboard checking, score updating, message displaying, and the like are wanted as the game progresses. / Begin | Put desired characters in memory | Move them to screen at location L Display game (1, n) < Time delay | Add desired offset to L (up, down, right, left) | Write blanks into present location of characters \ End Figure 1. A Warnier-Orr diagram describing the steps involved in simulating motion. This lends itself to a fairly modular program structure (see Figure 1). The program that I am going to use to illustrate this process is quite simple; it does not require an elaborate discussion of program logic. Let us start with a description of the program from the point of view of a player. Let us write a program in which the player flies a motorized delta-wing over his friend's backyard computer-controlled peashooter. The peashooter fires a pea and a water jet as you cruise past. When you are hit, the peashooter receives 100 points. You try to position yourself directly over your friend's backyard and drop a water balloon on the peashooter. If you hit him with the balloon, you receive 100 points. To make it interesting, we will have the gunner appear and disappear at random times and places. Before we start burning up coding sheets, or typing madly into the assembler, consider what functions must be added to those in Figure 1 to round out the whole game. To get everything ready to play, an initialization routine is needed to clear the screen, set the scores to 0, and so on. After waiting for the player to set the speed, put the delta-wing on the screen, give him a chance to get his fingers on the buttons, and survey the situation, and then we will enter the main loop. / Begin | Clear screen / Begin | Ask for speed | Set flags / Begin < Initialize < Get up ship | | Clear screen | Initialize scores | | Output picture \ End | \ End | Water balloon game (1, n) < Main run loop (1, n) (See Figure 3) | | / Begin \ End | Freeze screen | Display final score \ End Figure 2. The modular components of the balloon game. The main loop, Figure 2, will contain the functions described before; it will put the peashooter and ship on screen, leave them there for a short time, then write blanks over them and rewrite them in a new location, if required. In addition, there will be keyboard checks, to see if the player has fired his acceleration rockets to change the movement of the delta-wing, and update the score. Check for hits by a water balloon or peashooter, and see if a water balloon is being dropped. Move the peas and water jet which are being fired, and put on impact marks if any hits have been scored. / Begin / TakOf | Put blanks into location from which motorized | | delta-wing is moved onto screen. | \ End | | / Begin | Ship | Move motorized delta-wing location in memory | | to screen. | \ End | | Add offsets LR, UD | | / Begin | PutOn | Put motorized delta-wing characters into | | memory where blanks are now. | \ End | | / Begin | Ship | Move delta-wing to screen | \ End | | / Begin Main run loop (1,n) < KyChk | Update UD and LR from keyboard | \ End | | / Begin | TopB | Did we hit top or bottom of screen? | \ End | | / Begin | BlnChk | Is water balloon called for or already on | | its way? | | Update water balloon character location | \ End | | / Begin | Delay | Leave screen as it is for a moment | \ End | | / Begin | PeaChk | Update peashooter and pea | \ End | | / Begin \ ScorIt | Calculate scores | Put them on screen \ End Figure 3. A summary of the functions performed in the main loop, along with a definition of the individual tasks executed by each subroutine. Figure 3 summarizes the functions performed in the main loop, and names the subroutines which perform those functions. There are a number of possible changes that could be made in this program to tailor the program to the user's personal taste. The programmer should be able to figure out where to put the wrench by reference to the diagrams and the comments in the listing. Most of the housekeeping functions of this program are no different from those found in any assembly language program, so it will be assumed that the user can find the way through those, but a few more comments about the animation techniques might be worthwhile. For an illustration, follow the progress of a pea fired from the peashooter. Starting at line 1195 (PEA1), the program checks to see if a peashooter is on the screen, since you want peas to come only from a real peashooter. If one is there, jump to SHOT1, where you check to see if a water jet is already on the screen (water jets last for 2 cycles, as you will see when you play). If there is no water jet there, then a random number test decides whether to shoot a pea or water jet. If it is a pea, control falls through to TEMP. This locates the starting point for the pea line, and then sets the flag that tells the program that a pea is being fired. The program keeps track of that, since it will be on for several program cycles, until it makes a hit or goes off the screen. Next, we determine the random direction of fire and, at last, the program is ready to start the pea in motion. An increment is computed, and stored at lines 1425 through 1450. Note, at SUB1, that the user should reload the HL register pair with the same values that are already in it. This is a practice that I always follow when I will be coming to an entry point from a number of different places. The idea is to eliminate parameter passing, or rather to pass the parameters through a named storage location, which makes it much easier to debug. Be that as it may, you can readily see how, in the ensuing instructions, the heart of the matter is reached. Write hexadecimal 20 into the area occupied by the pea and its trail (hexadecimal 07 and 0A, respectively in the Processor Technology video display module (VDM) character set), then add the increment. Check to see if it is off the screen and, if not, put the characters into the new locations, and return. Checking for a hit is done when the ship is displayed. I hope that playing around with this program will prove to be as much fun for you as it was for me. In order to adapt it to your system, you may need to change the control keys, the clear routine, and the display location but, if you have a SOL-20, it will work as is. If you tackle the development of an animated game, you will find that the simple principles embodied in this program will work in much more elaborate games. One final note: when you first play this, you will be positive that it is impossible to win. The "random" peashooter seems to have an incredible 6th sense about where to aim his pea. However, it can be done... In fact, my 7-year old can beat it on Speed 1, so hang in there! Good luck, and have fun. Listing 1. oooo - "Dropping Balloons Reliably" Olli Urrila BYTE, Vol.5, No.6, June 1980, pp.183-184 (Retyped by Emmanuel ROCHE.) I thoroughly enjoyed the balloon game in the article "Writing Animated Computer Game" by Tony Estep (BYTE, November 1979, p.152). I do not have a SOL computer, so I had to make a few patches to the program. I also added a drop counter, which may interest other readers. The game as published drops balloons unreliably. To make the balloons drop consistently, change the code at hexadecimal location 01F6 to 01F6 CA 26 02 JZ Baln The "FINAL SCORE" message is not centered. Change the code at location 04DE to 04DE 21 98 CD LXI H,VdmBas+410 to center the message. Many video terminals can clear the screen after receiving a Form Feed character (hexadecimal 0C). If this works on your terminal, you can change the code at locations 0103 and at 0126 to 01xx CD F0 06 CALL ClSnFf and add the code as follows: 06F0 0E 0C ClSnFf MVI C,0CH 06F2 CD 09 F0 CALL Video 06F5 C9 RET The game, as published, allows an unlimited number of balloons to be dropped. While this is interesting, in a way, it can lead the player to engage in real block-bombardment, dropping balloons without aiming at anything below. I have added a limit to the number of balloons available, and a counter to tell how many balloons are left, to discourage waste of valuable resources. I have found that 35 balloons is a fair number. The code to provide this feature is shown in Listing 2. Listing 2. oooo (see BALLOON.ASM file) oooo EOF