Alien Invasion Game

A first-rate version of an arcade classic, plus a revealing article on Mode 7 animation.

Volume 1

Number 12

February 1984

Who said you can't write a good Invaders program in Mode7? TOM BLACKBURN has done it!

AT last, an authentic game of Invaders to run on both the Model A and B micros. In good arcade style, there are five colourful and ever advancing rows of Aliens, 10 per row, mercilessly bombing you.

You get 1,000 points for each full wave you destroy, but you've only got three lives, and each new wave starts lower and comes faster.

The mothership appears randomly, taunting you with her song, but if you can hit her, she's worth up to 300 points.

With a choice of either joysticks or keyboard, the game should provide hours of enjoyment, and a chance to admire the wonders of BBC Basic and Teletext Mode 7.

The program is written almost entirely in "straight" Basic, with the exception of the bomb routines, which for the sake of speed, use the BBC "?" peeks and pokes.

Before discussing the details of the program, let's consider Mode 7. The program runs in less than 10,000 bytes and that includes the graphics.

Although the shapes are limited and chunky, they are very likeable, much in the same vein as the Ceefax and Oracle screens on TV.

In simple terms, to the Basic interpreter the shapes are no more than concatenated (joined together) characters, printed in the same way as the normal Ascii set — ABC, etc.

The difference is achieved by use of the control codes - see Figure I.

Decimal

Hex

producing

145

&91

red

146

&92

green

147

&93

yellow

148

&94

blue

149

&95

magenta

150

&96

cyan
151

&97

white
Figure I

The code must be printed before the required shape - but on the same line -using the CHR$( ) instruction, or alternatively, using the VDU instruction. For example:

PRINTCHR$(&91)
VDU145

will both provide for red graphics on the rest of the line. Each line of print requires its own control code - try Program I:

10MODE7:FOR A=2 TO 24 STEP 2
20PRINT TAB(0,A)CHR*(&91)
30NEXT
40FOR A=1 TO 24
50PRINTTAB(A,A)"x{xt"
60NEXT
Program I

As you can see, the first loop places the control code in alternate lines, resulting in a mothership (borrowed from the game) on one line and gobbledygook on the next.

What about gobbledygook? Can we use it selectively? The answer is yes, and is explained in Table I.

Table I

In the User Guide (page 155) the "six cell" graphics characters are explained as Ascii values. I use the table, which provides both a quick look-up method and an easier line to enter.

The User Guide would have you calculate and enter:

PRINT CHR$(&91); CHR$(248); CHR$(251); CHR$(247); CHR$(244)

or:

VDU 145,248,251,247,244

to print a mothership, but by the table method:

PRINTCHR$(&91)"x{wt"

is all that is required.

The table is used by printing a graphic control code (&91-&97) followed by the character which represents the required cell, in quotes.

Alternatively, if you have OS 1.2, you can use the CTRL plus FUNCTION keys procedure.

By depressing CTRL+F1, for example, red graphics characters can be entered directly, enabling you to develop your Mode 7 graphics in real time.

Note that all six cells filled requires its own PRINT or VDU statement - PRINTCHR$(255) or VDU255 - copied into a function key as defined below.

For fun, set function key FO as below, and by using the CTRL key to move the cursor position:

CTRL+H = 1 space left
CTRL+I = 1 space right
CTRL+J = 1 line down (40 spaces)
CTRL+K = 1 line up (40 spaces)

and the keyboard with the caps lock off, you can create simple pictures and line drawings.

The F0 setting gives red graphics on all lines except line 0.

Use CTRL+H, CTRL+F1 for line 0. You can change colours by using CTRL plus FUNCTION keys as you wish, but you must not overwrite character 0 of each line, nor any of your colour change characters.

I doubt if Mode 7 will turn you into a computer Picasso, but it's all in the best possible taste!

Function key F0
*KEY0 CLS:F.A=0 TO 23: VDU145,10,8:N.: F.A=0 TO 23: VDU11:N.¦M

Incidentally, to fill all six cells, you can enter direct VDU 255.

This will simply print a block. You then set the block into a normal function key - *KEY 1 - then copy the block and press Return.

Now function key 1 will display the block whenever pressed.

You must remember that the alphabet is lower case to print graphics. The upper case alphabet is printed as normal in the selected colour.

Finally, in preparation for the real McCoy, try Program II. It is a demonstration of how to animate your characters. The program displays the mothership, as she quietly drifts to rest at the bottom of your screen.

Her movement is controlled by the FOR-NEXT loop, but is made clear and realistic by printing the space characters before moving the ship and by using the REPEAT-UNTIL, to slow it down.

If you really want to see the BBC Basic moving, delete line 50.

10 MODE7:VDU 23;8202;0;0;0;
20 FOR A=2 TO 18
30 B=B+RND(2)
40 PRINT TAB(B,A)CHR$(&91)'x{wt"
50 TIME=0:REPEAT UNTIL TIME=100
60 IF A=17 END ELSE PRINT TAB(B,A)""
70 NEXT
Program II

Although it looks lengthy, the Basic is fairly well structured with a few REMs and space lines.

For clarity, wherever possible the lines have been kept short and you should find that you will soon have the program keyed in and working.

Or, for those who prefer to let the machine do the work, you could send for the Micro User cassette and obtain a completely keyed and debugged version (see Page 137).

For the sake of speed, the program uses the % variables A to Z (yes, all of them), which in some instances saves up to 50 per cent of the time it takes an ordinary variable. A list of their uses is supplied.

The program is entered from RUN, and uses lines 10 to 180 to set up the working environment:

Lines 10-40 define the ENVELOPES.
Line 50 uses the ON ERROR routine to return the keyboard to normal and print the error number and line (ERR ERL). refer line.
Line 60 *TV 255 drops the display 1 line — improves the display on most TVs.
Line 70 sets mode and switches off the cursor.
Line 80-90 set up all the arrays and displays the titles.
Line 100 sets up the "Hall of Fame".
Lines 110-150 sets the values of the variables - note that the % variables must be set to zero even from run, as their values are not set by MOS (Machine Operating System). Return to line 80 from "Another Game" prompt ensures that the values are correctly maintained. Lines
160-170 set the top lines of print (lives left, scores). Line 180 set time and branch to the main loop.
The Main Loop - line 2000

To be absolutely correct, the main loop does not begin until line 2090, the intermediate lines being used from start and from each cleared screen to set up the battle scenario.

I let the machine do the donkey work in lines 1530 to 1930, using FOR NEXT loops to create the rows of aliens and bases.

As you can see, the string variables A$ to E$ are preset with the necessary gobbledygook in preparation for the magic control codes.

All processing is by PROCEDURE, apart from the main REPEAT UNTIL loop itself, which performs the routines and marches the invading hordes across your screen.

Before beginning the loop, the invaders are printed by lines 2000 to 2050 which display the aliens without the timing delays within the loop.

Note that for efficiency and thus to increase speed the more aliens you shoot, only non-space filled rows of aliens are printed and this is achieved by A% to E% counting your kills.

The REPEAT UNTIL variables, T% to W%, are set up during PROC-DIRECT, and must take account of the columns shot out. This is achieved by use of the variables GL%, SGL%, MM% and NN%. The result is the rather complex looking formula at line 2330.

Now a description of the procedures:

PROCDIRECT. Sets up the REPEAT UNTIL variables T% to W%. The TT% array helps to ensure that only living aliens are displayed.

The values of T%, V% and W% are modified during the main loop to take account of fully destroyed columns.

Incidentally, the *3 in the formula is the two-character alien plus its space character. Also the values of 20 and 21 are used to restrict space line prints to a minimum.

PROCLINE1 to PROCLINE 5. Actual print of the aliens. They are held in the string arrays A$ to E$ and are concatenated into AP$ to EP$ by the FOR NEXT loops which use MM% and NN% for the left and right hand columns.

This ensures that the well used technique of shooting out the end columns is catered for.

Note again that for the sake of efficiency the concatenation is only carried out if any aliens in that row have been shot - AA% to EE% are the indicators.

PROCMOVE. Normal laser movement, achieved by either ADVAL if K% is set from PROCTITLE or the negative INKEY. The negative INKEY is the most efficient and responsive method of key detection and is highly suited to games programming.

Note that F% is checked for bullets in motion (F%>0) before shoot detection, allowing for the COPY key or shoot button to remain depressed without slowing down the game.

Also the laser has a space character each side, providing smooth movement in one PRINTTAB instruction.

PROCSHOOT. First in a series of nested procedures, PROCSHOOT sets your laser bolt into action. Once fired, the laser is disabled by F% until you hit something or go out of range (line 0 on the screen). F% is the column position of the laser and thus the bullet.

PROCHIT. Moves the bullet up one line. Performs PROCBOMB in fairness to the aliens.

PROCHITA. Checks for a hit. Uses FNHIT to look at the correct screen position - not TUBE compatible. Four checks are involved:

1 - Hit your own base. Screen location value of either 255, 50, 120, 116, or 97.

2 - Hit a bomb. Screen location value 124.

3 - Hit the mothership - line value of 1 and screen location value < > 0 or 32 (space). In this case Perform PROCMHIT.

4 - Last < > 0 or 32 - hit an alien. Needless to say, perform PROC-SCORE.

PROCMHIT. Hit the mothership. Plays a fanfare and gives a random score. Perhaps you might add a delay at this point to show more clearly the score value.

PROCSCORE. No guesses, looks after your score. Actually, it does a fair bit more. Logically, perhaps the most complex routine.

By using DIV and MOD it looks after the rows and columns of aliens - A$ to E$, A% to E% for the rows; B4% (1 to 10) for the columns.

It also checks a count of the aliens shot and gives you your "Cleared Screen" award. A little fanfare (perhaps the Close Encounters theme) would go nicely here. I'll leave it to you.

PROCMSHIP. Moves the mothership by time delay. The more purist of you might wish to make her appearance even more random. As it is, she appears sometime after 10 seconds since she last got shot or disappeared - but from which side?

PROCBOMBS. This routine and its subsequent performs will kill you, well it does drop the aliens bombs!

By setting L% to the start position of the highest row of aliens at the beginning (L% = HIMEM + (2+Z%) * 40) we have the base location for bomb dropping.

HIMEM is the first screen location in this mode.

Z% is the start height depending on screens cleared.

(2+Z%) * 40 gives the address of the first column of the highest line of aliens.

By using this method, we can direct and lower the bombs using the minimum of time-consuming arithmetic :

1. Random choice of one or two bombers.

2. Check A$ to E$ position to make sure an alien exists.

3. Add the correct screen location values; 80 characters for each line of aliens plus the following line of spaces.

4. Poke - or to be precise ?B2%(J%) = 97 — which means print a bomb below the chosen alien. Note that PROCLOWER uses the formula described in PROCBOMBS to check for a hit and blank out bomb and lower bomb one line.

PROCBOMBED removes a life and, if necessary, ends the game.

PROCTITLE is the first routine performed, prints the introduction and checks for joysticks. Note the interesting use of RIGHT$ to display the title.

PROCFAME of course, sets up your rank by FOR NEXT loops.

Overall, the flow of the program is governed by the way the main procedures are performed.

This potentially allows much scope for experiment — changing the frequency of the performs will change the responses and movement of the various characters.

For the adventurous, the laser bullets routines could be changed to use PEEKs and POKEs or even assembler routines - the assembler equivalent of ? is only a STA to a specified address.

I've described the program in detail in a hope that it may be helpful by providing an insight into games programming.

The Mode 7 graphics prove to be more than useful and the techniques used in Invaders could equally well be used in Galaxian, Centipede - even Gorf type games.

In the meantime, I wish you luck. Get keying, and enjoy yourself.

Variables Used

A% = Count of aliens shot - top line
B% = Count of aliens shot - second line
C% = Count of aliens shot - third line
D% = Count of aliens shot - fourth line
E% = Count of aliens shot - fifth line
F% = Position of base for bullets (column)
G% = Position of bullets (row)
H% = Height of aliens 1% = General loop count
J% = General loop - specifically used in random routines and small loops
K% = Joysticks
L% = Screen position in map terms
M% = General loop
N% = Position in base - movement routines
O% = FNHIT calculation - column
P% = FNHIT calculation - row
Q% = Mothership movement (direction +1-1)
R% = Used to define which alien characters are printed
S% = Mothership markers
T%, U%, V%, W% = Main loop counts - defines direction of aliens - TT% array helps.
X% = Result of FNHIT (=FNHIT) - checks for bullet hits
Y% = High score
Z% = Lower position of aliens after clearing screen
MM% = Start of alien string count - increases the prints per line as the columns are cleared (left hand side)
NN% = End of alien string count - used as
MM% from right hand side
LI% = Used as go to variables in SCORE - defines which alien was hit
AA% to EE% = Indicators for changes to alien lines
A$ to E$ = Alien lines
AP$ to EP$ = Concatenated alien lines
B4% (1 to 10)= Alien column counts
F3 = Result of row calculation - which alien was hit?
GL%, SGL%= Additional variables used to continue the leftward movement of the aliens if complete columns have been destroyed.