Applesoft BASIC is a versatile language. It is possible to design simple games using low-resolution graphics. You won’t be winning any awards for graphics but it is an interesting way to spend an afternoon. Listed below is a Pong program I designed. It uses the up arrow and down arrow to control the paddle (vertical orange line). It is a Pong-type game very similar to swash.
The ball is a yellow dot one pixel tall. When the game starts, the ball is put in play and moves from the green wall towards your paddle. The player uses the up and down arrows to move the paddle to intercept the ball before it hits the purple wall. If the ball hits the purple wall, the game ends and prints out the following lines:
YOU LOSE
GO AGAIN? (Y OR N)
?

The program will continue to display this until the player presses Y or N. If the player presses N, the Apple II is put into TEXT mode, the screen is cleared with HOME, and the program is quit. If the player enters Y, the game is reset and play resumes.
Paddle Control:
The program uses T = PEEK(-16368) in line 130 to assign T the value of the key being pressed by the player. To learn more about how PEEK works, read “My Homemade Apple II Paint Program” available on this site. In line 140, if T is equal to 139, the number of the up arrow, the program jumps to line 300 and proceeds to move the paddle up. In line 150, if T is equal to 138, the number of the down arrow, the program jumps to line 400 and proceeds to move the paddle down. In line 330 and line 440, T = PEEK(-16368) resets the keyboard strobe to zero so that the next character can be read in. It also sets T’s value to zero. Note the delimiters on line 140 and 150 (Y < > 1, Z < > 29). This keeps the program from driving the paddle through the top or bottom wall, eventually leading to a syntax error. PLOT statements cannot plot values off the screen.
- 140 IF T = 139 AND Y < > 1 THEN 300
- 150 IF T = 138 AND Z < > 29 THEN 400
Play Area:
The play area is a square drawn using HLIN and VLIN in subroutine 3000. HLIN draws a horizontal line and VLIN draws a vertical line. COLOR= selects the line color. The two numbers following HLIN or VLIN tell the computer where to start and end the line on the X or Y-axis. The number after AT tells the computer which line on the X or Y-axis the line will be drawn on.
- 3100 GR: COLOR= 3: VLIN 0,30 AT 7
- 3200 COLOR= 12: VLIN 0,30 AT 32
- 3300 COLOR= 12: HLIN 7, 32 AT 0
- 3400 COLOR= 12: HLIN 7,32 AT 30
You cannot PLOT points outside the play area. This would cause the ball to shoot out of the wall area and possibly off the screen causing a syntax error (Illegal Quantity Error). Delimiters are used that will not let the program PLOT a point in a restricted error.
Ball Movement:
Simulating movement is the most interesting aspect of this game. The program draws the ball (or paddle) at its current position. Then it draws the ball again but this time in black. After the ball is blacked out, the program draws the ball in its new position, which is advanced along the ball’s line of movement. This simulates the illusion of movement. It also makes the program somewhat clunky. I have tried to build a game with multiple moving objects using this same method. Unfortunately, the effect of drawing and blacking out objects is way too slow for a complex game. High-resolution graphics and shape tables were designed to handle complex graphics but that is way beyond the scope of my pong program.
There are a few things to know before you can simulate the movement:
- Which direction is the ball currently moving?
- Has the ball hit anything to change that direction?
- Which direction will the ball bounce when it hits something?
Ball direction is captured in variable DR. Variable S holds the program line or subroutine currently controlling the ball’s movement. S = 0 defines the game start condition. If S = 0, line 240 sends the program to line 2500, starting the ball in motion from right to left or DR = 1. DR = 1 equates to a right to left motion in the program logic. DR = 0 equates to a left to right motion in the program logic. Keep in mind that the ball can move in a diagonal from left to right or right to left as well. DR denotes the direction the ball is currently moving. DR cannot be changed until there is a collision from a wall or from the paddle.
XB and YB are the variables used to hold the ball’s PLOT points. Lines 200 through 230 check to see if the ball is attempting to PLOT on a wall. If so, the program gives control to the RANDOM NUMBER GENERATOR in subroutine 2000. To learn more about random number generation, read “Apple II Screen Saver” available on this site. A random number is generated and this number is used to determine the ball’s bounce in subroutine 2300. Depending on the bounce direction selected (straight back, diagonal up, or diagonal down), the appropriate program line is selected. The bounce variable is K:
K = 1 equates to diagonal up
K = 2 equates to diagonal down
K = 3 equates to straight back
(see lines 2520-2580 and lines 4020-4080)
The ball’s bounce back movement is handled in the main program in lines 2500 – 2580 (direction being DR = 1 or right to left) and lines 4000 – 4080 (direction being DR = 0 or left to right). Lines 4000 – 4080 define a movement away from the paddle, after a collision is detected. Lines 2500 – 2580 define a movement towards the paddle.
Collision Detection:
The program must continually PLOT the ball movement until a collision is detected. Variable S, which defined the start condition (zero), also holds the current subroutine or program line controlling the ball’s movement. A series of IF statements in lines 240-290 keep the program from getting confused. These lines keep sending the program to the appropriate PLOT statements until a wall or the player paddle stops the ball. When this occurs, the value of S is changed to reflect the current direction and bounce of the ball.
Collisions are detected by lines 160 – 230. Lines 160 – 190 define conditions for paddle collisions. Lines 200 – 230 define wall collisions. These lines also keep the program from driving the ball through a wall or off the screen. Line 210 defines the losing condition:
210 IF XB = 8 THEN 2600
If XB, the ball’s X-axis PLOT point equals 8, the left side wall’s HLIN plus 1, the game is over. In this way, the ball has only to touch the purple wall in order to trigger the losing condition. The game is over when the ball touches the purple wall behind the player’s paddle.
Sound Generation:
The program does not have sound except when the player loses the game. Generating hit sounds would slow the game up somewhat. The following lines cause sound to be generated:
- 2610 W = PEEK(-16336)
- 2620 IF Z = 20 THEN 2650
- 2630 Z = Z + 1
- 2640 GOTO 2610
PEEK(-16336) generates a click on the internal speaker. This is done 20 times because a single click is almost imperceptible.
Conclusion:
The program could be improved in many ways. You could add a scoring function that prints to the text area under the playing field. You could also put in a difficulty selector that could make the paddle larger. Right now, the paddle is two pixels tall. You could make it three or four pixels tall to make the game easier. There are a few bugs inherent in the code. Sometimes the game wigs out. Fortunately, it doesn’t bug out very often.
The Program:
10 REM APPLESOFT PONG BY JOHN WARD
20 HOME
100 GOSUB 3000
110 X = 11: Y = 12: Z = 13: XB = 31: YB = 12: S = 0
120 COLOR= 9: PLOT X,Y: PLOT X, Z: COLOR= 13: PLOT XB,YB
130 T= PEEK (-16384)
140 IF T = 139 AND Y < > 1 THEN 300
150 IF T = 138 AND Z < > 29 THEN 400
160 IF X + 1 = XB AND Y = YB THEN 4000
170 IF X + 1 = XB AND Z = YB THEN 4000
180 IF X = XB AND Y + 1 = YB THEN 4000
190 IF X = XB AND Z + 1 = YB THEN 4000
200 IF XB = 31 THEN 2500
210 IF XB = 8 THEN 2600
220 IF YB = 29 THEN 2700
230 IF YB = 1 THEN 2800
240 IF S = 0 THEN 2900
250 IF S = 2500 THEN 2515
260 IF S = 2600 THEN 2615
270 IF S = 2700 THEN 2715
280 IF S = 2800 THEN 2815
290 IF S = 4000 THEN 4015
299 GOTO 130
300 COLOR= 0: PLOT X,Y: PLOT X,Z
310 Y = Y – 1: Z = Z -1
320 COLOR= 9: PLOT X,Y: PLOT X,Z
330 T = PEEK(-16368)
340 GOTO 130
400 COLOR= 0: PLOT X,Y: PLOT X,Z
410 Y = Y + 1: Z = Z + 1
420 IF Z = 35 THEN 130
430 COLOR= 9: PLOT X,Y: PLOT X,Z
440 T = PEEK(-16368)
450 GOTO 130
2000 REM RANDOM NUMBER GENERATOR
2100 K = INT (10*RND(1))
2200 RETURN
2300 REM RANDOM SELECTOR
2320 IF K < = 3 THEN 2370 2350 IF K > 3 AND K < 6 THEN 2380 2360 IF K > = 6 THEN 2390
2370 K = 1: GOTO 2400
2380 K = 2: GOTO 2400
2390 IF K = 3
2400 RETURN
2500 GOSUB 2000
2510 GOSUB 2300
2515 S = 2500
2516 DR = 1
2520 IF K = 1 THEN 2550
2530 IF K = 2 THEN 2560
2540 IF K = 3 THEN 2570
2550 COLOR= 0: PLOT XB, YB: XB = XB – 1: YB = YB – 1: GOTO 2580
2560 COLOR= 0: PLOT XB, YB: XB = XB – 1: YB = YB + 1: GOTO 2580
2570 COLOR= 0: PLOT XB, YB: XB = XB – 1
2580 COLOR= 13: PLOT XB, YB: GOTO 130
2600 REM LOSE GAME
2605 Z = 0
2610 W = PEEK(-16336)
2620 IF Z = 20 THEN 2650
2630 Z = Z + 1
2640 GOTO 2610
2650 PRINT “YOU LOSE”
2660 PRINT “GO AGAIN? (Y OR N)
2665 INPUT N$
2670 IF N$ = “Y” THEN 2691
2680 IF N$ = “N” THEN 2695
2690 IF N$ < > “Y” AND N$ < > “N” THEN 2660
2691 HOME: COLOR= 0: PLOT XB,YB
2692 GOTO 100
2695 TEXT: HOME
2699 END
2700 REM UPSWING
2715 S = 2700
2720 IF DR = 1 THEN 2750
2730 IF DR = 0 THEN 2760
2750 COLOR= 0: PLOT XB, YB: XB = XB – 1: YB = YB -1: GOTO 2780
2760 COLOR= 0: PLOT XB, YB: XB = XB + 1: YB = YB -1: GOTO 2780
2780 COLOR= 13: PLOT XB, YB: GOTO 130
2800 REM DOWNSWING
2815 S = 2800
2820 IF DR = 1 THEN 2850
2830 IF DR = 0 THEN 2860
2850 COLOR= 0: PLOT XB, YB: XB = XB – 1: YB = YB +1: GOTO 2880
2860 COLOR= 0: PLOT XB, YB: XB = XB + 1: YB = YB +1: GOTO 2880
2880 COLOR= 13: PLOT XB, YB: GOTO 130
2900 REM START THE BALL
2910 DR = 1
2920 GOTO 2500
3000 REM PLAY AREA
3100 GR: COLOR= 3: VLIN 0,30 AT 7
3200 COLOR= 12: VLIN 0,30 AT 32
3300 COLOR= 12: HLIN 7, 32 AT 0
3400 COLOR= 12: HLIN 7,32 AT 30
3999 RETURN
4000 GOSUB 2000
4010 GOSUB 2300
4015 S = 4000
4016 DR = 0
4020 IF K = 1 THEN 4050
4030 IF K = 2 THEN 4060
4040 IF K = 3 THEN 4070
4050 COLOR= 0: PLOT XB, YB: XB = XB + 1: YB = YB + 1: GOTO 4080
4060 COLOR= 0: PLOT XB, YB: XB = XB + 1: YB = YB – 1: GOTO 4080
4070 COLOR= 0: PLOT XB, YB: XB = XB + 1
4080 COLOR= 13: PLOT XB,YB: GOTO 130