This program simulates a 2×2-pixel ball bouncing inside a rectangular enclosure, drawn with PLOT and DRAW commands to create “glass walls.” It uses simple Newtonian-style physics: a constant downward acceleration (A=1) accumulates into a vertical velocity (V), which reverses on floor contact, while a horizontal drift (DX) reverses on side-wall contact. The SOUND command is called at each collision with distinct multi-register parameter strings to produce different bounce sound effects for the floor, left wall, and right wall. After each complete bounce cycle where both V and V1 equal zero, DX is incremented and the ball is relaunched, progressively widening its horizontal travel.
Program Structure
The program is organized into a main loop and three collision subroutines, with a restart block at line 8000:
- Lines 1–4: REM headers crediting the original Apple source (Myers’ Microcomputer Graphics) and the converter.
- Lines 5–10: Initialization of position (
X=50,Y=4), vertical velocity (V=0), acceleration (A=1), horizontal drift (DX=0), and previous-velocity tracker (V1=1). - Lines 20–30: Screen clear,
OVER 1mode set, and the border rectangle drawn with chainedDRAWcommands. - Lines 40–110: Main animation loop — draw ball, check collisions, update physics, erase ball (XOR via OVER 1), update position, check rest condition, loop.
- Lines 5000–7010: Collision subroutines for floor, right wall, and left wall respectively, each firing a
SOUNDcommand. - Lines 8000–8010: Rest-state handler; increments
DXand restarts. - Line 9998:
CLEAR : SAVE "glasswalls" LINE 1— save line not part of normal execution flow.
Graphics Technique — XOR Plotting
The program uses OVER 1 (line 20) to engage XOR pixel mode for the entire session. The ball is represented as a 2×2 block drawn with four PLOT statements at lines 40 and 90. Because OVER 1 XORs pixels, plotting the same four pixels a second time at line 90 erases the ball before the position is updated at line 100, achieving flicker-free animation without a CLS each frame. The border rectangle is drawn once at line 30 and survives subsequent ball XOR operations because it is never redrawn.
Physics Model
| Variable | Role | Initial Value |
|---|---|---|
X | Horizontal pixel position | 50 |
Y | Vertical pixel position (from bottom) | 4 |
V | Vertical velocity (positive = upward) | 0 |
A | Gravitational acceleration constant | 1 |
DX | Horizontal velocity (pixels/frame) | 0 |
V1 | Previous frame’s vertical velocity | 1 |
Gravity is applied each frame at line 80 as LET V=V+A. Because A=1 is positive and the coordinate system maps increasing Y upward (Y is subtracted from 175 for screen plotting), the ball accelerates downward. On floor contact (line 50), the velocity is negated: LET V=-V, simulating a perfectly elastic bounce. In practice there is no energy loss, so the ball bounces to the same height indefinitely — the rest-detection at line 104 catches the degenerate case where V=0 and V1=0 simultaneously (the ball rests at the floor).
Collision Detection
Wall and floor detection is threshold-based rather than pixel-based:
- Floor (line
50):IF Y>174— triggers when the ball would exceed the screen height. - Right wall (line
60):IF X>254-DX— uses the current DX in the threshold, which slightly anticipates the wall when moving fast. - Left wall (line
70):IF X<(1-DX)— similar anticipation logic.
Both horizontal checks simply negate DX, producing a perfect elastic reflection. No energy is dissipated, so the ball will bounce indefinitely unless it comes to rest vertically (V=0).
SOUND Usage
Each collision subroutine calls the SOUND command with a series of AY-3-8912 register/value pairs. Three distinct timbres are programmed:
- Floor bounce (line
5000): registers 0,2,4,6,7,9,11,13 — multi-channel setup with envelope. - Right wall (line
6000): registers 0,1,7,8,11,12,13 — different timbre with aPAUSE 1afterward to let the sound settle. - Left wall (line
7000): registers 0,2,4,7,8,9,10,11,13 — yet another distinct register set.
The use of register 13 (envelope shape) in all three suggests envelope-based decay rather than sustained tones, appropriate for percussive bounce effects.
Rest Detection and Relaunch
Lines 104–105 implement a two-frame velocity check: V1 holds the previous frame’s velocity. When both V=0 and V1=0, the ball has truly stopped (two consecutive zero-velocity frames), and execution jumps to 8000. There, DX is incremented by ABS DX+1 — this always makes DX positive, so the ball always relaunches moving to the right, regardless of which wall it last bounced from. The program then returns to line 10 to reinitialize and restart. Over successive launches DX grows as 1, 2, 3… giving progressively wider horizontal arcs.
Content
Source Code
1 REM PROGRAM 1.2 (BOUNCING BALL) (with glass walls)
2 REM SIMULATES A BALLBOUNCING OFF FLOOR AND WALLS
3 REM from the book Microcomputer Graphics by Myers converted and embellished from the apple program to T/S 2068
4 REM by James N Jones 2242 Locust Amarillo, Texas 79109
5 BORDER 1: PAPER 1: INK 7
9 LET DX=0: LET V1=1
10 LET X=50: LET Y=4: LET A=1: LET V=0
20 CLS : OVER 1
30 PLOT 0,0: DRAW 0,175: DRAW 255,0: DRAW 0,-175: DRAW -255,0
40 PLOT X,175-Y: PLOT X+1,175-Y: PLOT X,174-Y: PLOT X+1,174-Y
50 IF Y>174 THEN GO SUB 5000: IF V=0 THEN LET V=-1
60 IF X>254-DX THEN GO SUB 6000
70 IF X<(1-DX) THEN GO SUB 7000
80 LET V=V+A
90 PLOT X,175-Y: PLOT X+1,175-Y: PLOT X,174-Y: PLOT X+1,174-Y
100 LET Y=Y+V: LET X=X+DX
104 IF V1=0 AND V=0 THEN GO TO 8000
105 LET V1=V
110 GO TO 40
5000 LET V=-V: SOUND 0,22;2,43;4,55;6,31;7,56;9,16;11,2;13,0
5010 RETURN
6000 LET DX=-DX: SOUND 0,33;1,0;7,62;8,16;11,232;12,1;13,0: PAUSE 1
6010 RETURN
7000 LET DX=-DX: SOUND 0,55;2,33;4,77;7,56;8,16;9,16;10,16;11,2;13,0
7010 RETURN
8000 LET DX=ABS DX+1
8010 GO TO 10
9998 CLEAR : SAVE "glasswalls" LINE 1
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
