BASIC Code

APPLEII Air Attack.BAS

Click the screen to give it focus.

Press any key to drop bombs, trying to time them such that it hits the ship below.

This game was refactored from a code listing in the 1984 book Games Apples Play. Written in Applesoft BASIC, it's presented in Joshua Bell's javascript emulator.

It isn't a perfect emulator - some important high-res graphic commands are missing, but it's fine for games like this.

The Listing

``` 10 SL = 15 : REM ** SHOTS LEFT ** 100 TEXT: HOME : NORMAL 110 VTAB 3: HTAB 11: PRINT "*** AIR ATTACK ***" 120 ?" *** As seen in Games Apples Play *** " 130 ?" *** Refactored by Michael Coorlim ***" ```

Applesoft requires the use of line numbers, so we're keeping them this time.

140 VTAB 7
150 ? "Press any key to drop a bomb, aiming" 
160 ? "for the ships."
170 ?
180 ? "Lower Deck: 10 points"
190 ? "Upper Deck: 20 points"
170 ? "Smokestack: 30 points"
200 ?
210 ?"You have ";SL;" bombs in your bay."
220 ?:? "Good luck."
230 VTAB 23 
240 INPUT "*** PRESS RETURN ***"; AN$

I've rewritten the instructions to be more concise.

250 GOSUB 300 : REM SETUP
260 GOSUB 400 : REM PLAY
270 GOSUB 700 : REM END
280 END

Fortunately the program was well structured so I didn't have to change much about its general shape. I did move the instructions to follow the title screen as they'd only be seen once per play, and not looped.

300 REM *** SETUP
310 SL = 15
320 GR
330 COLOR = 2 : REM ** DRAW THE WATER
340 HLIN 0,39 at 39
350 HLIN 0,39 at 38
360 AX = 0: SX = 33: SS = 1
370 RETURN

GR sets our graphics mode to lowres. HLIN draws horizontal lines (origin, end at vertical position). Our graphics in this game are going to be made of lines of various lengths.

400 REM *** PLAY LOOP
410 HOME
420 VTAB 22: CALL - 958 : ? "SHOTS LEFT: "SL"       SCORE: "TS

CALL is a keyword that calls a native Applesoft routine. -958 clears the text from the cursor to the bottom of the window.

430 GOSUB 470: REM PLANE
440 GOSUB 510: IF SL = 0 THEN RETURN
450 GOSUB 640: REM SHIP
460 GOTO 430
470 COLOR = 0: HLIN AX,AX +6 AT 2: HLIN AX +1, AX+6 AT 1: PLOT AX + 6,0
480 REM CHECK SCREEN WRAP
490 AX = AX-1: IF AX =< 0 THEN AX = 33
500 COLOR = 4: HLIN AX,AX + 6 AT 2: HLIN AX+1, AX+6 AT 1: PLOT AX+6,0: RETURN

Drawing our player. COLOR sets the current color. PLOT draws a single point. In lowres those points are much bigger than a pixel.

510 IF FF THEN 540
520 IF PEEK(-16384) =< 128 THEN RETURN

PEEK and POKE directly access machine memory (virtual machine memory in an emulator's case) and that's why it's hard to convert programs that use them; each microcomputer's peeks and pokes did different things. Peek gets info, poke changes that memory allocation to do a thing.

PEEK(-16384) checks to see if we're getting keyboard input. If the bits at that register are more than 128, we are.

530 FF = 1: POKE -16368,0: FX = AX+3: FY =2
540 COLOR = 0: PLOT FX, FY
550 FY = FY+1
560 IF SCRN(FX,FY) = 0 THEN COLOR = 13: PLOT FX,FY: RETURN
570 IF SCRN(FX,FY) = 2 THEN 610

SCRN gets the color of the pixel at a certain point on the screen. Line 560 checks to see if the screen is black where our bomb's coordinates are; if it is, we draw the bomb pixel. If it's blue, we jump to a subroutine to draw a splash.

580 TS = TS + (38 - FY) * 10
590 SC = 0: COLOR = 0: HLIN SX,SX +6 AT 37: HLIN SX+3,SX+5 AT 36: PLOT SX +4,35
600 SX = 33: SS = 1: SC = 0

If it's not black OR blue, we hit the enemy ship, so draw that explosion and deal with logic and scoring.

610 COLOR = 2: HLIN FX -1, FX+1 AT 37: PLOT FX - 2,36: PLOT FX-3,35: PLOT FX,35: PLOT FX+3,35
620 FF =0: SL = SL-1: POKE -16368,0
630 VTAB 22: CALL -958: ? "SHOTS LEFT: "SL"       SCORE: "TS: RETURN
640 SC = SC +1: IF SC =< SS THEN RETURN
650 SC = 0: COLOR = 0: HLIN SX,SX+6 AT 37: HLIN SX +3, SX+5 AT 36: PLOT SX+4,35
660 SX = SX+1: IF SX => 33 THEN SX = 0: SS = INT(RND(1)*3)+1: SC=SS
670 COLOR = 1: HLIN SX,SX+6 AT 37: HLIN SX+3,SX+5 AT 36: PLOT SX+4,35: RETURN
700 REM ** END
710 HOME: PRINT "GAME OVER": ?"Your score of "TS" is ";
720 IF TS =< 25 THEN ? "Terrible!": RETURN
730 IF TS =< 50 THEN ? "Bad!": RETURN
740 IF TS =< 75 THEN ? "Poor!": RETURN
750 IF TS =< 100 THEN ? "Mediocre!": RETURN
760 IF TS =< 150 THEN ? "Good!": RETURN
770 IF TS =< 250 THEN ? "Great!": RETURN
780 ? "Amazing!": RETURN

At the end of the game we get a rating based on our score.