4
Animation by Page FlippingDavid N. Plotkin
A special animation technique, storing several predrawn screens in memory at once, summons them to create movement, flashing "frames" on the screen as movie projectors do. This article includes a simple game, "Inferno," to show how it's done.
Have you ever wished you could make a picture simply appear on the screen, without drawing it line by line in front of the user? Or perhaps you have an animation sequence, and drawing each new "frame"--erasing the parts you don't need, and PLOTting and DRAWTOing the new parts--takes too long and ruins the animated nature of the program. Well, the Atari computers do provide a way to draw a picture in the memory while the user is looking at a different picture, and then instantly flash the completed picture on the screen. By drawing several pictures beforehand in memory, and then flashing them on the screen one by one in sequence, you can easily create animation for your BASIC program.
The key to page flipping is that you can write to an area of memory that you are not displaying on the screen. When you then tell the computer to display the area of memory you have previously written to, the picture drawn in that area of memory simply appears on the screen.
Whenever you issue a GRAPHICS command, the computer creates what is called a display list.This is just information telling the computer how to display data on the screen. The memory address of the display list is stored at locations 560 and 561 as:
DL Address = PEEK (560) + 256 * PEEK (561)
The fifth and sixth numbers of the display list (DL address + 4 and DL address + 5) contain the address of screen memory,that is, the address of the first byte of data to be displayed on the screen.
An entirely different set of memory locations contains the address of write memory,the memory address where the first byte of data is to be written from execution of keyboard commands and/or a running program:
Write Memory address = PEEK (88) + 256* PEEK (89)
Thus, when you type in a PLOT or DRAWTO command, the shape is written into computer memory at the location starting at the write memory address. The reason you normally see on the screen what has been written into write memory is that the address of write memory and the address of screen memory (or display memory) normally have the same value. To flip pages, then, you follow these steps:
1. POKE a value into locations 88 and 89 (write memory) which correspond to an empty, protected area of memory (more on this in a moment).
2. Execute PRINT, PLOT, DRAWTO, SETCOLOR, etc., commands, as usual, to draw the picture you want, using standard cursor limits. You will not see your picture on the screen.
3. Set DL address + 4 and DL address + 5 equal to the value in locations 88 and 89, respectively. Your picture will flash onto the screen.
Animating is just an extension of this method. You follow steps 1 and 2 listed above over and over, each time creating in memory a new "frame" of the animation. You have to keep track of where each new frame begins (the value of memory locations 88 and 89 for each screen) and make sure the screens don't overlap in memory. To prevent screens from overlapping, make sure that each screen starts further away in memory from the previous screen than the values listed below:
GRAPHICS 0 - 960 bytes
GRAPHICS 1 - 480 bytes
GRAPHICS 2 - 240 bytes
GRAPHICS 3 - 240 bytes
GRAPHICS 4 - 480 bytes
GRAPHICS 5 - 960 bytes
GRAPHICS 6 - 1920 bytes
GRAPHICS 7 - 3840 bytes
GRAPHICS 8 - 7680 bytes
These values are just the amount of memory used to store one full screen of data. Remember that a change of the value of either location 89 or DL address + 5 by one is equal to 256 bytes, and that locations 88 and DL address + 4 cannot exceed 255. You'll need to do some math so that whenever location 88 exceeds 255, you subtract 256 from it and add one to location 89. Similarly, if location 88 goes below zero, then you add 256 to it and subtract one from location 89. These same rules apply for DL address + 4 or DL address + 5.
A couple of other pointers before we get to the fun part. Player/missile graphics are the best way to handle user-manipulated shapes when animating using page flipping. P/M graphics are not affected by the display memory or write memory manipulations. Assuming you left the write memory address pointing to one of your frames (usually the last one you drew), any further BASIC graphics or text commands during the program run will flash on the screen only when the single frame to which the command was written is put on the screen. To avoid this, you have to keep changing the write memory to match the screen memory, which you are changing to "flip pages," and create the animation effect. This takes time and slows down program execution. To produce the P/M graphics for the included program, I've used Eric Stoltman's machine language utility from the article "Extending Player/Missile Graphics" (COMPUTE!'s First Book of Atari Graphics) with a new wrinkle.
To move vertically (see lines 150-170), I first read zeros into the P/M memory, increment the Y coordinate, and then read the correct shape back into memory. This occurs quickly and works well. One last thing--to get the empty, protected memory to store your pictures, step back RAMTOP as many pages as you need and read zeros into the protected memory to clear it. See program lines 900-910 for details.
"Inferno" demonstrates page-flipping animation. A large skyscraper is burning fiercely, and the only escape for the 20 occupants is the roof. It's up to you to pilot your helicopter to a safe landing on the roof, navigating through the flames, which move faster as the fire progresses. The flames aren't as bad on the left side of the building, but that is where the fire engine is coming, so you can't land there. A flashing red dot appears in the upper left of the screen for each person you successfully rescue. When you've lost three helicopters or rescued all 20 people, just press the fire button to play again.
Variables DIF: F: P: NUM: H: DL4: DL5: ST: PB: X0,Y0: X1,Y1: DL: RT: A, I, N, M: |
Measures difficulty. As DIF increases, flames move faster Helicopter facing flag; = 1 when copter faces right; = - 1 when copter faces left Person flag; = 1 when person on roof; = 0 when person rescued Number of people rescued Number of helicopters left Low byte of screen memory High byte of screen memory STICK (0) Start of P/M graphics memory Player 0 coordinates Player 1 coordinates Address of display list RAMTOP Loop variables |
Program Listing LINE 10 20-80 110 - 145 150 - 170 180 190 210 230 - 250 260 - 320 330 - 370 800 - 890 900 - 980 1000 - 1370 1500 - 1550 |
Call initializing subroutines, initialize variables Main Program Loop--set display memory address and jump to rescue subroutine Move helicopter horizontally, keep it from going offscreen, set direction of helicopter Move helicopter vertically Test for helicopter landing on roof Test for collision of helicopter with playing field Test for dropping off passenger Person runs to helicopter after it lands on roof Destruction of helicopter, test for all helicopters destroyed Passenger leaves helicopter after it lands. If all people are rescued, restart game. Increase difficulty as fire progresses POKE machine language routine Set up pages Flip pages Introduction |
Inferno
Download P099L1.BAS (Saved BASIC)Download / View P099L1.LST (Listed BASIC)
Return to Table of Contents | Previous Section | Next Section