PROGRAM THE BOUNCING BALL
Player/Missile graphics tutorial
By DAVID FOX & MITCHELL WAITEThis article is an edited excerpt from the book Computer Animation
Primer by David Fox and Mitchell Waite, copyright 1984, published by Byte
Books/ McGraw Hill Book Co. and reproduced by permission.
The BASIC program listing, which demonstrates the ideas
discussed in the article, runs on all Atari computers of all memory configurations.
No joystick is needed. Antic Disk subscribers RUN"D:EXAMPLE8.BAS"
WHAT ARE PLAYER/ MISSILE GRAPHICS?
Atari's player/missile graphics use the
special ANTIC and GTIA microchips to let you move animated figures anywhere
on the video screen without disturbing the background.
A "player" is actually a section of RAM that contains
an eight-bit-wide vertical bar from top to bottom of the screen.
This vertical bar can be positioned horizontally anywhere across the screen.
Players can be created in the shapes you choose, with
the same programming techniques applicable to user-defined character sets.
Atari computers can handle a total of four players and
four missiles-each of which can be moved independently in a horizontal,
vertical or diagonal direction.
Missiles are two bits wide, while the players are eight
bits wide. Therefore, if you're designing a game that doesn't require
missiles you can combine your eight available missile bits to create a
fifth player.
Let's explore the applications of Player/Missile (P/M)
graphics using a bouncing ball program. You will be able to enter
the speed of the ball and its elasticity coefficient-how bouncy it will
be. The ball (made out of a player) will not only bounce, but will
"squash" when it hits.
We use GRAPHICS 3 even though P/M graphics works in any
graphics mode. You may wonder, "Why GRAPHICS 3? It has such coarse
resolution." That is exactly why we chose it - coarse graphics means low
memory overhead. No Atari graphics mode uses less memory than GRAPHICS
3.
There are three POKEs which must be executed to turn on
P/M graphics: first POKE address 54279 with the memory page where P/M RAM
begins.
POKE 54279,PMPAGE
Next, ANTIC microchip must be told that it should begin
grabbing information from P/M memory.
A POKE of 42 into 559 Will leave us with a normal screen,
a two-line P/M display and an enabled Player direct memory access (DMA):
POKE 559,42
The third POKE gives ANTIC, the go ahead to begin sending
player, missile information to the GTIA microchip for display on the screen.
Player graphics are now enabled and ready to go.
HOW TO USE THE PROGRAM
Type in the BASIC listing at the end of this article. It's called
Example 8 because it's the eighth program in the book from which this article
is excerpted. Check it with TYPO, and SAVE an extra backup copy.
RUN the program, and you'll see a ball bouncing according the initial program
values for velocity (speed) and elasticity. When the ball has finished
bouncing, you'll be prompted for a new velocity. Type in any positive
number. Next, you're asked for a value for elasticity. This
value should normally be within the range zero to one, but if you use a
value higher than one, each bounce of the ball will be higher than the
one before.
ANALYSIS OF BOUNCING BALL PROGRAM
First look at line 70. This is where the first entry into the
variable value table is made with string variable PLRO$. This line
must be entered before entering any other line containing variables or
the program will not work properly. Later, the location of the data
for this variable will be moved to match the RAM for Player 0.
The subroutine on lines 100-130 is called when the value
of a 16-bit number, X, needs to be separated into high and low bytes.
This is necessary when the HIBYTE and/or LOBYTE will be put into memory
address by a POKE.
Lines 140-330 initialize the program's variables and send
the computer off into four initializing subroutines. On line 150,
three variables are DIMensioned-BLANK$ will be used to clear a temporary
player buffer; PLR(n) will hold the RAM address of the four players; and
HPLR(n) will be set to the address of the horizontal position registers
for the four players.
On line 160, an Atari BASIC trick is used to fill BLANK$
with 128 ATASCII 0 (Atari ASCII) characters. After the first and
last characters of BLANK$ are initialized to CHR$(0), the magic begins
with the statement:
BLANK$(2)=BLANK$
| |
Destination string source string
BASIC copies the first character of the source string into the second
character of the destination string, then the second character of the source
string into the third character of the destination string, and so on.
In this way, each character of the string will be copied from the earlier
one until the string is filled!
Line 170 sets the screen to GRAPHICS 3, turns off the
cursor and PRINTs a message on the screen. Lines 180-240 call some
special subroutines that we will cover next. Lines 300-320 PRINT
information on the screen and set the initial VELocity (speed) and ELASTICity
values. By elasticity, we mean the percentage of the ball's current
velocity which remains when it hits the ground. An elasticity of
0.5 (50 percent) means that the ball maintains half its current velocity
and loses the other half every time it bounces. An elasticity of
1.0 (100 percent) is a perfect bouncing ball. It never loses any
energy and will bounce forever. The closest to perfect we have seen
in real life is about 0.85 (85 percent) for a toy super ball. An
elasticity of 0 (O percent) is a ball that will not bounce at all - it
just hits the ground and dies.
The subroutine (5000-5360) reserves memory space, in the
form of strings for the frame data, (frame means a single screen picture,
just like in a movie). Line 5100 reads the number of frames used
in the sequence (FRAMES=3), the size of each frame in bytes (FRMSIZE=7),
and the number of players used in this program (NUMPLRS=1). The data
is located on line 20060. On line 5120, the variable PLRFRMMEM (PLayeR
FRaMe MEMory) is set to the total number of bytes necessary to store the
frames for each player. Line 5130 sets FRAMEMEM (FRAME MEMory) to
the total number of frame bytes needed for all players.
PERFECT ELASTICITY
On line 5170, string memory is reserved for three variables.
BUFFER$ is the temporary buffer used in vertical player movement.
FRAME$ will hold the current frame to be displayed and FRAMEMEM$ holds
all frames for every player.
In this section 7000-7130, memory is reserved for the
players, and P/M graphics are enabled.
Line 7020 tells ANTIC where to find PM RAM by placing
the starting memory page number (TEMP) in 54279 (D407 Hex). The actual
RAM address of PM RAM is calculated and stored in PMBASE in line 7030.
In lines 7040-7070, two arrays are initialized.
PLR(I) holds the RAM address for Players 0 through 3. HPLR(I) holds the
address of the horizontal position register for each player.
In line 7080, SDMCTL, address 559, is initialized and
ANTIC begins DMA from player RAM. A POKE of 42 into 559 leaves us
with a normal screen, a two-line P/M display and enabled player DMA, but
no missiles.
In line 7100, ANTIC starts sending player information
to GTLA so it can be displayed on the screen when POKED with a 2.
In lines 9000-9080, BASIC is tricked into moving a string
variable to coincide with Player 0 RAM. In lines 9010-9020 the locations
of the string array area and the variable value table are calculated.
In 9030 the number of bytes from the beginning to the string/ array area
to the start of Player 0 RAM is stored in OFFSET. Line 9040 uses
the HI/LO byte subroutine on OFFSET so these values can be POKED into the
variable value table and the first variable in the program is now relocated!
The loop in lines 10000-10140 and 21000-21060 reads the
frame data for the bouncing ball into the string FRAMEMEM$. Each
BYTE is converted to a character with CHR$.
The main animation loop (lines 400-570) controls the movement
of the ball on the screen.
On line 410 four constants are initialized. BOTTOM
is the lowest vertical screen position to which the ball will go and is
analogous to the floor. XPOS is the starting horizontal position
of the ball (off the xcreen to the left). TIME holds the elapsed
time from the moment the ball is launched or bounced. HORIZ holds
the horizontal velocity. This value is constant until the ball begins
to roll.
The ball is moved to the left of the screen in line 420,
and the value of ELASTIC is checked in 430. Later, when input is
accepted from the keyboard, this line makes sure that if the elasticity
is very low, there is at least one bouncing noise when the ball hits the
ground.
FORCE OF GRAVITY
Starting at line 440 is the gravity calculation. The effect gravity
has on the motion of an object can be represented by the formula
-16*TIME*TIME
This shows the acceleration of gravity over time. By subtracting the above value from the current velocity (VEL) multiplied by TIME, the current height of the ball off the ground is obtained:
VEL*TIME-16*TIME*TIME
This must be subtracted from the value of the ground (BOTTOM) to convert the number to screen coordinates:
YPOS=BOTTOM-(VEL*TIME-16*TIME*TIME)
FRM0, the number of the current frame to be displayed, is set to 1 (the
round ball).
Line 460 checks for contact with the ground. If
the ball has hit, (YPOS will be greater than or equal to BOTTOM), the ball's
VELocity is recalculated by multiplying the current VELocity by EIASTIC.
With the initial ELASTICity of 0.8, 80 percent of the current velocity
will be conserved and 20 percent lost. TIME is set to 0 since as
far as gravity is concerned, the ball is first starting out and was thrown
by the ground.
Line 470 checks to see if the ball is still on the screen.
If not, the animation loop is exited, and new values can be entered from
the routine starting at 600.
Now that all the values are calculated, the ball will
be positioned on the screen. The horizontal position of the player
is set in line 480. On 490 the correct frame is transferred from
FRAMEMEM$ (where all three frames are kept) to FRAME$. Lines 500-520
position FRAME$ at the proper vertical position in player RAM. The
ball is now in place.
In line 530, the horizontal position of the ball (XPOS)
is incremented. Line 540 turns on the bounce sound if the ball has
just struck bottom and the velocity is high enough. If SNDFLAG was
set in line 430 (low elasticity), the sound will be heard on the first
bounce.
In line 550, TIME is incremented by 0.15 and the loop
continues at line 440 if the velocity is greater than 0.5. A different
value can be substituted for the 0.15 to stimulate the ball bouncing in
slow or fast motion. Use a smaller TIME increment to make the ball
move in tinier increments (slow motion).
Finally, line 560 will be reached if the velocity of the
ball is so slow that it can only roll rather than bounce. HORIZ is
decremented to simulate the effect of friction on the ball's horizontal
velocity. If the ball is still rolling (HORIZ will be greater than
0), frame 1 is selected, and the program jumps to 470 since the bouncing
calculations of 440-460 are no longer needed. If the ball has stopped
rolling, the program will fall through the routine at 600.
Lines 600-690 are executed after every ball finishes bouncing
to allow you to enter your own velocity and elasticity values. The
ball is moved off the screen in line 610. The TRAP command is used
in line 640 to trap any INPUT errors which may occur. If there are
any, the program will jump to line 630 and the values can be reentered.
In line 670, after executing the "cursor off" POKE, at least one PRINT
statement must be executed before the cursor vanishes. Line 680 turns
off error trapping by setting TRAP to a nonexistent line number, and the
animation loop is restarted.
CHANGING AROUND THE PROGRAM
Try the following modifications:
1. Experiment with different velocities and elasticities. Try a velocity of 1 and a velocity greater than 1.0. Did you ever see the Walt Disney movie, The Absent-Minded Professor, which is about an amazing substance called Flubber? This flying rubber gained velocity every time it bounced.
2. Change the constant (16) in the gravity equation (fine 440) to simulate a ball on a different planet with stronger or weaker gravity.
3. Modify the program so there is a ceiling as well as a floor off of which the ball can bounce. Will the ball speed up if you use an elasticity greater than or equal to 1.0?
David Fox is the Lucasfilm computer games project leader who spearheaded Rescue On Fractalus for release on the Atari. Mitchell Waite is president of the Waite Group Inc, which has produced over 30 books on personal computing.
Listing: EXAMPLE8.BAS Download