Classic Computer Magazine Archive COMPUTE! ISSUE 11 / APRIL 1981 / PAGE 97

Invaders From Outer Space

An Atari Program Using One Joystick

David H. Markley
Reynoldsburg, Ohio

This program is a simplified version of an earlier program I wrote called "Alien Landers" and is designed to run in 8K of memory. The object of the game described here, is to protect your galactic base from an invasion of allien saucers of unknown origin. Your weapon against the alien saucer is a sophisticated photon cannon which jou control by a joystick connected to controller port #1. The saucer on the other hand, is equipped with a mysterious paralyzing death ray which when energized, will immobilize and possibly vaporize your photon cannon. The game is played by defending your base against the saucers and achieving the highest score possible before your 3 photon cannons are destroyed. The program keeps track of the highest score obtained during any individual game and displays the final game score and the high game score at the end of each battle. After starting the game using the RUN command, additional battles are initiated by holding the start button down until the new game begins.

This program utilizes many of the fine features of the ATARI personal computer, such as the exciting sound effects and the advanced player/missile graphics. The player/missile graphics are used to enable the program to provide good animation without the overhead of saving and restoring the background as the player or missile image moves through the playfield. Another ATARI feature used here is the player/missile collision registers. These registers are associated with the ATARI'S graphics and indicate when a player or missile overlaps with another player, missile, or playfield image.

The program from line 30 thru line 600 provides background setup and player/missile initialization. Initialization begins by allocating space for the player/missile image buffers. The buffers are placed in a free area of memory just below the graphics memory with the base address located 2048 bytes (8 pages) from the top of memory. This leaves the top 1K of memory for the graphics 2 display list and mapping data.

The functional player/missile (P/M) graphics area begins with the missile image buffer. Since the program uses the double resolution mode of P/M graphics, the missile image buffer begins 384 bytes from the base address and is followed by four player image buffers. Each buffer occupies 128 bytes of memory. Invaders from Outer Space uses only two of the four available players which are in the form of a saucer (player 1) and a photon cannon (player 2). The images of the saucer and cannon are formed by placing a bit pattern of the shapes into their corresponding player image buffers.

Lines 600 and 700 initialize the game's counters and registers. The high game score counter initialized by line 600 is used to keep track of the highest score obtained for all games played during any program run. This counter is only initialized one time. Registers and counters which are initialized every time a new game is played are all located at line 700.

With the playfield and players enabled and the games counters and registers initialized, the program is ready to begin antimating the graphics by entering the game's antimation sequencer loop (lines 1000 thru 2000). This section of the program is used to control the movement of the saucer, cannon, and photon. It also determines when to fire the saucer's death ray and checks for P/M collisions.

The sequencer loop begins by determining the saucer's horizontal position in relation to the play field. Normally the saucer will travel across the field in a left to right direction in steps of 5 horizontal increments. If the saucer is within the range of fire of the cannon however, and is currently under attack (M > 0) the saucer will take evasive action by moving randomly within a short distance of either side of its current position. With the position of the saucer determined, the sequencer's next task is to produce the saucer's sound effect. This effect is created by stepping through a series of six frequencies in which the frequency is changed one step for each loop cycle. Once the saucer has been placed in its new position, a test is made to see if it is in attack range of the cannon. If the test (line 1060) indicates that the saucer is within 15 increments of the cannon, the program will go to the death ray handler (line 3100).

The next sequencer task to be handled is the control of the cannon and its associated photon missile (lines 1100 thru 1220). The program begins by checking to see if the photon is ready to be fired. If it is ready to fire or has reached the top of the playfield (M < J + 8), its sound is turned off and the joystick trigger is examined. If the trigger is not pressed, the program will continue through the sequencer loop and will examine the trigger each time it passes through the loop. When the trigger is finally pressed, the M pointer will be set to an address of the missile image buffer which corresponds to a vertical position directly above the cannon's muzzle.

The horizontal position of the photon is handled by calculating the horizontal position of the cannon's center and placing it into the cannon's horizontal positioning missile register. Line 1110 controls the movement of a photon which is enroute to its target. To move an object vertically using the P/M graphics, the image is first removed from its current position within the image buffer and then rewritten into its new location. The P/M graphics function in such a way that as the base address of the image data is moved to a lower numbered address in the buffer, the image will appear to move upward on the screen. After each photon movement, the player/missile collision register is checked to see if the saucer has been hit. When a hit is detected the program exits the sequencer loop and goes to the routine at line 3000 to handle the collision. If the saucer is not hit the sequencer loop enters the code which handles cannon movement. When the joystick is moved to the left or right the cannon is shifted 5 increments to the left or right of its current position each pass through the loop. With the completion of this code, the sequence loop is now ready for the next pass.

The routine starting at line 3000 is used to control hits on the saucer. It begins by removing the photon from the playfield by clearing the first 29 bytes of the missile image buffer. This area represents the area on the playfield in which the photon can collide with the saucer. When the buffer has been cleared, the missile position pointer M is reset to zero as an indication that it is ready to be fired again. To help produce the effect of more than one saucer, the saucer's color is randomly changed each time it is hit. Finally the score is updated and the background flag (BK) is set to indicate an above ground explosion. The program then goes to the explosion handler routine (line 4000).

The routine starting at location 3100 is used to generate the saucer's death ray. It begins by positioning the ray at the center of the saucer. This is done by calculating the center of the saucer and placing this position into the ray's horizontal position missile register. The sound and visual effects are handled by lines 3120 thru 3140. The ray is first drawn by setting bits 0 and 1 for every third byte in the missile image buffer. It is then erased by again accessing every third byte and clearing bits 0 and 1 to zero. As the ray is removed, the frequency of its associated sound generator is decreased. Upon completing the death ray, the program examines the P/M collision register corresponding to the ray missile and the cannon player. If the collision took place, an explosion effect is produced by moving the cannon to a position off the playfield and setting the explosion back ground flag for the bottom text window before calling the explosion handler at line 4000.

The explosion handler is used to produce the explosion effect for both the saucer and the cannon. To begin, the explosion handler resets the P/M collision registers. The collision registers are designed to be latching and must be reset each time a collision has been registered. After terminating the sound of the photon which may have caused the explosion, the program begins to produce the visual and audio effects of the explosion. This is done by stepping the variable X from 14 to 0 and using its value to control the intensity of the color and sound. The background which is determined by BK was selected by the calling program before the explosion handler was entered. When the explosion is complete, the playfield colors are returned to their normal hue.

When the explosion effect is complete, the program is ready to display the cannon number or score. Since the program displays all messages at the top of the screen using graphics 2, the saucer must be removed from the screen by setting its P/M color registers to zero. The saucer's original color is stored in X and will be again restored at the completion of the message display cycle. After a short delay while the message is being displayed, a test is made to determine if the last cannon has been hit. If not, the message is removed and the background is restored and the game continues. When the game is finally completed, the score is compared to the high game score. If the score resulting from the last game is higher, the high game score is updated. The program indicates the end of the game by alternately displaying the last game and high game scores. After each display of the high game score the start switch is examined to see if a new game is requested.

10 REM INVADERS FROM OUTER SPACE
15 REM COPYRIGHT (c) 1980
20 REM BY DAVID H. MARKLEY

Print title

25 GRAPHICS 2
30 PRINT #6;" INVADERS"
35 PRINT #6;" FROM"
40 PRINT #6;" OUTER SPACE"

Start player/missile data list 2K from top of memory. Place in P/M base register and calculate beginning address of the player data lists.

50 I=PEEK (106)-8 : POKE 54279,I
60 J=I*256+384
Clear P/M buffer area
70 FOR X=J TO J+384
80 POKE X,0
90 NEXT X

Generate play field

100 GRAPHICS 2
110 SETCOLOR 2,11,6
120 COLOR 3
130 POKE 84,0:POKE 85,4:? #6; ".","."
140 POKE 84,5:POKE 85,2:? #6; "* ."
150 POKE 84,3:POKE 85,8:? #6;".","."
160 POKE 84,7:POKE 85,14:? #6;"."

Enable player/missile DMA for double line resolution,

200 POKE 559,46

Place saucer image data into first player's image buffer area and set its color to green (200). Set the saucer's initial horizontal position to 70.

300 POKE J + 148, 24
310 POKE J + 149, 126
320 POKE J + 150, 171
330 POKE J + 151, 126
340 POKE J + 152, 24
350 POKE 704, 200
360 POKE 53248, 70

Place photon cannon image data into second player's mapping buffer area and set color to orange. Set cannon's initial horizontal position to 160.

400 POKE J + 347, 24
410 POKE J + 348, 60
420 POKE J + 349, 24
430 POKE J + 350, 24
440 POKE J + 351, 60
450 POKE J + 352, 126
460 POKE J + 353, 255
470 POKE J + 354, 102
480 POKE 705, 56
490 CNPOS = 160

Set saucer player to double width and enable P/M graphics.

500 POKE 53256, 1
510 POKE 53277, 3

Initialize game counters and registers.

600 HIGH = 0
700 M = 0 : SCORE = 0 : CN = 1

This ends program initialization. Begin process loop. Determine saucer's position.

1000 FOR POS = 15 TO 240 STEP 5
1010 SCPOS = POS

Vary saucer position if in range of cannon.

1020 IF ABS(POS - CNPOS) < 20 AND M <> 0 THEN SCPOS = POS + (25 - 50 * RND(0))
1030 POKE 53248, SCPOS

Produce saucer sound effect.

1040 FRQ = FRQ + 1 : IF FRQ > 6 THEN FRQ = 1
1050 SOUND 0, 60/FRQ, 10, 5

If missile is not launched check if in range to activate saucer death ray.

1060 IF M < J + 12 THEN IF ABS(CNPOS - SCPOS) < 15 THEN 3100

If missile is not launched or has reached the top of the screen, set missile flag and sound to zero. Check fire button, if pressed init missile position at cannon.

1100 IF M < J + 8 THEN M = 0 : SOUND 1, 0, 0, 0 : IF STRIG(0) = 0 THEN
        M = J + 93 : POKE 53253, CNPOS + 3

If missile is launched then move it to next vertical position.

1110 IF M > 8 THEN POKE M, 0 : POKE M - 1, 0 = M = M - 8 : POKE M, 12 :
        POKE M - 1, 12 : SOUND 1, ABS(M + 5 0 - J) * 0.5, 8, 15

Check missile collision register. If hit then goto 3000 for effect.

1120 IF PEEK(53257) = 1 THEN 3000

Determine cannon horizontal position.

1200 IF STICK(0) = 11 THEN IF CNPOS > 50 THEN CNPOS = CNPOS - 5
1210 IF STICK(0) = 7 THEN IF CNPOS < 198 THEN CNPOS = CNPOS + 51220 POKE 53249, CNPOS

End process loop.

2000 NEXT POS : GOTO 1000

Saucer hit and explosion handler erase missile, change saucer color, and update earth score.

3000 FOR X = 0 TO 28 : POKE X + J, 0 : NEXT X : M = 0
3010 POKE 704, INT(15 * RND(0)) * 16 + 8
3020 SCORE = SCORE + 25

Set explosion in sky.

3030 BK = 4
3040 GOTO 4000

Saucer death ray handler. Position death ray position under saucer.

3100 POKE 53252, SCPOS + 7

Fire ray and produce sound.

3120 SOUND 1, 4, 12, 15 : SOUND 0, 0, 0, 0
3130 FOR X = 25 TO 97 STEP 3 : POKE J + X, 3 : NEXT X
3140 FOR X = 25 TO 97 STEP 3 : POKE J + X, 0 : SOUND 1, X-23, 12, 15 : NEXT X
3150 SOUND 1, 0, 0, 0

Check cannon's missile collision register, if a hit then update cannon counter and produce explosion.

3200 IF PEEK(53256)< > 2 THEN 2000
3210 CN = CN + 1 : POKE 53249, 0
3220 BK = 2

Explosion handler program. clear collision registers and disable missile sound.

4000 POKE 53278, 255
4010 SOUND 1, 0, 0, 0

Produce explosion sound and light.

4020 FOR X = 15 TO 0 STEP -1
4030 SETCOLOR BK, 3, X
4040 SOUND 0, 50, 0, X
4050 FOR D = 0 TO 15 : NEXT D
4060 NEXT X

Restore colors for sky and earth.

4100 SETCOLOR 2, 10, 6
4110 SETCOLOR 4, 0, 0

Display score.

4200 POKE 84, 0 : POKE 85, 2
4210 POKE 53248, 0
4220 IF BK = 2 AND CNK4 THEN ? #6; "CANNON"; CN : GOTO 4240
4230 ? #6; "SCORE " : POKE 85, 8 = ? #6; SCORE
4240 FOR D = 0 TO 200 : NEXT D

Check if end of game.

4300 IF CNK4 THEN 4400
4310 IF SCORE>HIGH THEN HIGH = SCORE
4320 POKE 84, 0 : POKE 85, 2
4330 ? #6; "HIGH        "; : POKE 85, 7 : ? #6; HIGH
4340 POKE 53279, 8 : FOR D = 0 TO 80
4350 IF PEEK(53279) = 6 THEN 700
4360 NEXT D : GOTO 4200

Restore background.

4400 POKE 84, 0 : POKE 85, 2 :? #6; "  .", ". "
4410 GOTO 1000