Color, Animation and Sprite Graphics Statements Unique to the C128 - continued6.3 SPRITES: PROGRAMMABLE, MOVABLE OBJECT BLOCKSYou already have learned about some of the Commodore 128's exceptional graphic capabilities. You've learned how to use the first set of high-level graphics statements to draw circles, boxes, lines and dots. You have also learned how to color the screen, switch graphic modes, paint objects on the screen and scale them. Now it's time to take the next step in graphics programming - sprite animation. If you have worked with the Commomdore 64, you already know something about sprites. For those of you who are not familiar with the subject, a sprite is a movable object that you can form into any shape or image. You can color sprites in up to one of 16 colors. Sprites can even be multicolor. The best part is that you can move them on the screen. Sprites open the door to computer animation. Here is the set of sprite statements you will learn about in this section:
6.3.1 Sprite CreationThe first step in programming sprites is designing the way the sprites look. For example, suppose you want to design a rocket ship or a racing car sprite. Before you can color or move the sprite, you must first design the image. In C128 mode, you can create sprites in these three ways:
6.3.2 Using Sprite Statements in a ProgramThis method uses built-in statements so you don't have to use any aids outside your program to design your sprites as the other two methods require. This method uses some of the graphics statements you learned in the previous section. Here's the general procedure. The details will be added as you progress.
6.3.3 Drawing the Sprite ImageHere are the actual statements that perform the sprite operations. When you are finished with this section, you will have written your first sprite program. You'll be able to RUN the program as much as you like, and SAVE it for future reference. The first step is to draw a picture (24 by 21 pixels) on the screen using DRAW, CIRCLE, BOX or PAINT. This example is performed in standard bit map mode, using a black background. Here's the statements that set the graphic mode and color the screen background black. 5 COLOR 0,1:REM COLOR BACKGROUND BLACK 10 GRAPHIC 1,1:REM SET STND BIT MAP MODE The following statements DRAW a picture of a racing car in the upperleft corner of the screen. You already learned these statements in the last section. 5 COLOR 0,1:COLOR 4,1:COLOR 1,2 :REM SET COLORS 10 GRAPHIC 1,1 :REM SET HI-RES GRAPHIC MODE 15 BOX 1,2,2,45,45 :REM PICTURE FRAME 20 DRAW 1,17,10 TO 28,10 TO 26,30 :REM CAR BODY 22 DRAWTO 19,30 TO 17,10 :REM CAR BODY 24 BOX 1,11,10,15,18 :REM UPPER LEFT WHEEL 26 BOX 1,30,10,34,18 :REM UPPER RIGHT WHEEL 28 BOX 1,11,20,15,28 :REM LOWER LEFT WHEEL 30 BOX 1,30,20,34,28 :REM LOWER RIGHT WHEEL 32 DRAW 1,26,28 TO 19,28 :REM GRILLE 34 BOX 1,20,14,26,18,90,1 :REM CAR SEAT 36 BOX 1,150,35,195,40,90,1 :REM WHITE LINES 38 BOX 1,150,135,195,140,90,1 :REM WHITE LINES 40 BOX 1,150,215,195,220,90,1 :REM WHITE LINES 42 BOX 1,50,180,300,195 :REM FINISH OUTLINE 44 CHAR 1,18,23,"FINISH" :REM DISPLAY FINISH RUN the program. You have drawn a white racing car, enclosed in a box, in the upperleft corner of the screen. You have also drawn a raceway with a finish line at the bottom of the screen. At this point, the racing car is still only a stationary picture. The care isn't a sprite yet, but you have just completed the first step in sprite programming - creating the image. 6.3.4 Storing the Sprite Data with SSHAPEThe next step is to save the picture into a text string. Here's the SSHAPE statement that does it: 45 SSHAPE A$,11,10,34,30:REM SAVE THE PICTURE IN A STRING The SSHAPE command stores the screen image (bit pattern) into a string variable for later processing, according to the specified screen coordinates. The numbers 11, 10, 34, 30 are the coordinates of the picture. You must position the coordinates in the correct place or the SSHAPE statement can't store your picture data correctly into the string variable A$. If you position the SSHAPE statement on an empty screen location, the data string is empty. When you later transfer it into a sprite, you'll realize there is no data present. Make sure you position the SSHAPE statement correctly on the correct coordinates. Also be sure to create the picture with the dimensions 24 pixels wide by 21 pixels tall, the size of a single sprite. The SSHAPE statement transforms the picture of the racing car into a data string that the computer interprets as picture data. The data string, A$, stores a string of zeros and ones in the computer's memory that make up the picture on the screen. As in all computer graphics, the computer has a way it can represent visual graphics with bits in its memory. Each dot on the screen, called a pixel, has a bit in the computer's memory that controls it. In standard bit map mode, if the bit in memory in equal to an 1 (on), then the pixel on the screen is turned on. If the controlling bit in memory is equal to 0 (off), then the pixel is turned off. 6.3.5 Saving the Picture Data in a SpriteYour picture is now stored in a string. The next step is to transfer the picture data from the data string (A$) into the sprite data area so you can turn it on and animate it. The statement that does this is SPRSAV. Here are the statements: 50 SPRSAV A$,1:REM STORE DATA STRING IN SPRITE 1 55 SPRSAV A$,2:REM STORE DATA STRING IN SPRITE 2 Your picture is transferred into sprite 1 and sprite 2. Both sprites have the same data, so they look exactly the same. You can't see the sprites yet, because you have to turn them on. 6.3.6 Turning on SpritesThe SPRITE statement turns on a specific sprite (numbered 1 through 8), colors it, specifies its screen priority, expands the sprite's size and determines the type of sprite display. The screen priority refers to whether the sprite passes in front of or behind the objects on the screen. Sprites can be expanded to twice their original size in either horizontal or vertical directions. The type of sprite display determines whether the sprite is a standard bit mapped sprite or a multicolor bit mapped sprite. Here are the two statements that turn on sprites 1 and 2. 60 SPRITE 1,1,7,0,0,0,0:REM TURN ON SPR 1 70 SPRITE 2,1,3,0,0,0,0:REM TURN ON SPR 2 Here's what each of the numbers in the SPRITE statements mean:
As you can see, the SPRITE statement is powerful, giving you control over many sprite qualities. 6.3.7 Moving Sprites with MOVSPRNow that your sprite is on the screen, all you have to do is move it. The MOVSPR statement controls the motion of a sprite and allows you to animate it on the screen. The MOVSPR statement can be used in two ways. First, the MOVSPR statement can place a sprite at an absolute location on the screen, using the vertical and horizontal coordinates. Add the following statements to your program: 70 MOVSPR 1,240,70:REM POSITION SPRITE 1 - X=240,Y=70 80 MOVSPR 2,120,70:REM POSITION SPRITE 2 - X=120,Y=70 Line 70 positions sprite 1 at sprite coordinates (240,70). Line 80 places sprite 2 at sprite coordinates (120,70). You can also use the MOVSPR statement to move sprites relative to their original locations. For example, place sprites 1 and 2 at the coordinates as in lines 70 and 80. You want to move them from their original locations to another location on the screen. Use the following statements to move the sprites along a specific route on the screen: 85 MOVSPR 1,180 #6:REM MOVE SPRITE 1 FROM THE TOP TO THE BOTTOM 87 MOVSPR 2,180 #7:REM MOVE SPRITE 2 FROM THE TOP TO THE BOTTOM The first number in this statement is the sprite number. The second number is the direction expressed as the number of degrees to move in clockwise direction, relative to the original position of the sprite. The hash sign (#) signifies that the sprite is moved at the specific angle and speed relative to a starting position, instead of an absolute location, as in lines 70 and 80. The final number specifies the speed in which the sprite moves along its route on the screen, which ranges from 0 through 15. The MOVSPR command has two alternative forms. See Section 17, paragraph 17.59, of Chapter V, BASIC 7.0 Encyclopaedia for these notations. Sprites use an entirely different coordinate plane from bit map coordinates. The bit map coordinates range from points (0,0) (the top left corner) to 319,199 (the bottom right corner). The visible sprite coordinates start at point (50,24) and end at point (250,344). The rest of the sprite coordinates are off the screen and are not visible, but the sprite still moves according to them. The OFF-screen locations allow sprites to move smoothly onto and off the screen. Figure 6-7 illustrates the sprite coordinates and the visible sprite positions. Figure 6-7. Visible Sprite coordinates.Now RUN the entire program with all the steps included. You have just written you first sprite program. You have created a raceway with two racing cars. Try adding more cars and more objects on the screen. Experiment by drawing other sprites and include them in the raceway. You are now wel on the way in sprite programming. Use your imagination and think of other scenes and objects you can animate. Soon you can create all kinds of animated computer "movies". 6.3.8 Creating a Sprite ProgramYou now have a working sprite program example. Here's the complete program listing. 5 COLOR 0,1:COLOR 4,1:COLOR 1,2 : REM SET COLORS 10 GRAPHIC 1,1 : REM SET HI-RES GRAPHIC MODE 15 BOX 1,2,2,45,45 : REM PICTURE FRAME 20 DRAW 1,17,10 TO 28,10 TO 26,30 : REM CAR BODY 22 DRAWTO 19,30 TO 17,10 : REM CAR BODY 24 BOX 1,11,10,15,18 : REM UPPER LEFT WHEEL 26 BOX 1,30,10,34,18 : REM UPPER RIGHT WHEEL 28 BOX 1,11,20,15,28 : REM LOWER LEFT WHEEL 30 BOX 1,30,20,34,28 : REM LOWER RIGHT WHEEL 32 DRAW 1,26,28 TO 19,28 : REM GRILLE 34 BOX 1,20,14,26,18,90,1 : REM CAR SEAT 36 BOX 1,150,35,195,40,90,1 : REM WHITE LINES 38 BOX 1,150,135,195,140,90,1 : REM WHITE LINES 40 BOX 1,150,215,195,220,90,1 : REM WHITE LINES 42 BOX 1,50,180,300,195 : REM FINISH OUTLINE 44 CHAR 1,18,23,"FINISH" : REM DISPLAY FINISH 45 SSHAPE A$,11,10,34,30 : REM SAVE PICTURE INTO A$ 50 SPRSAV A$,1 : REM STORE A$ IN SPRITE 1 55 SPRSAV A$,2 : REM STORE A$ IN SPRITE 2 60 SPRITE 1,1,7,0,0,0,0 : REM TURN ON SPRITE 1 65 SPRITE 2,1,3,0,0,0,0 : REM TURN ON SPRITE 2 70 MOVSPR 1,240,70 : REM SPRITE 1 X=240, Y=70 80 MOVSPR 2,120,70 : REM SPRITE 2 X=120, Y=70 85 MOVSPR 1,180 #6 : REM MOV SPR 1 DOWN SCREEN 87 MOVSPR 2,180 #7 : REM MOV SPR 2 DOWN SCREEN 90 FOR I=1 TO 5000:NEXT I 99 GRAPHIC 0,1 Here's what the program does:
In this section, you have learned how to create sprites, using the built-in C128 graphics statements such as DRAW and BOX. You learned how to control the sprites, using the Commodore 128 sprite statements. The Commodore has two other ways of creating sprites. The first is the built-in SPRite DEFinition ability, as described in the following paragraphs. The other method of creating sprites is similar to that used for the Commodore 64; see the C64 Programmer's Reference Guide for details on this sprite-creation technique. 6.3.9 Sprite Definition Mode - The SPRDEF CommandThe Commodore 128 has a built-in SPRite DEFinition mode which enables you to create sprites on your Commodore 128. You may be familiar with the Commodore 64 method of creating sprites, in which you required to either have an additional sprite editor, or design a sprite on a piece of graph paper and then READ the coded sprite DATA and POKE it into an available sprite block. With the new Commodore sprite definition command SPRDEF, you can construct and edit your own sprites in a special sprite work area. To enter the SPRDEF mode, type: SPRDEFand press {return}. The Commodore 128 displays a sprite grid on the 40 column screen. In addition, the computer displays the prompt: SPRITE NUMBER ? Enter a number between 1 and 8. The computer displays the corresponding sprite in the upper right corner of the screen. From now on, we will refer to the sprite grid as the work area. The work area has the dimensions of 24 characters wide by 21 characters tall. Each character position within the work area corresponds to 1 pixel within the sprite, since a sprite is 24 pixels wide by 21 pixels tall. While within the work area in SPRDEF mode, you have several editing commands available to you. Here's a summary of the commands: 6.3.9.1 Sprite Defintion Mode Command Summary
6.3.10 Sprite Creation Procedure in SPRite DEFinition ModeHere's the general procedure to create a sprite in SPRite DEFinition mode:
Once you have created a sprite and have exited SPRite DEFinition mode, your sprite data is stored in the appropriate sprite storage area in the Commodore 128's memory. Since you are now back in control of the BASIC language, you have to turn on your sprite in order to see it on the screen. To turn it on again, use the SPRITE command you learned previously. For example if you created sprite 1 in SPRDEF mode. To turn it on in BASIC, color it blue and expand it in both the X and Y directions enter this command: SPRITE 1,1,7,0,1,1,0 Now use the MOVSPR command to move it as follows: MOVSPR 1, 45 # 5 Now you know all about SPRDEF mode. First, create the sprite, save the sprite data and exit from SPRDEF mode to BASIC. Next turn on your sprite with the SPRITE command. Move it with the MOVSPR command. When you're finished programming, SAVE your sprite data in a binary file with the BSAVE command as follows: BSAVE "filename", B0, P3584 TO P4096 When you want to use the sprite data again from disk, load the previously BSAVEd binary file with the BLOAD command as follows: BLOAD "filename"[, B0, P3584] The portion in brackets is optional. BLOAD loads data into the address from which it was saved if the optional portion is not specified. Now you know the new method for creating sprites. So you can use the following two methods: 1) SSHAPE, SPRSAV, SPRITE, MOVSPR, 2) SPRDEF mode. Experiment with both methods and master sprite animation. See paragraph 6.3.12, "Storing Sprite Data in Binary Files" later in this section for more information. 6.3.11 Adjoining SpritesYou have learned how to create, color, turn on and animate a sprite. An occasion may arise when you want to create a picture that is too detailed or too large to fit into a single sprite. In this case, you can join two or more sprites so the picture is larger and more detailed than with a single sprite. By joining sprites, each one can move independently of one another. This gives you much more control over animation than with a single sprite. This section includes an example using adjoining sprites. Here's the general procedure (algorithm) for writing a program with two or more adjoining sprites.
The following program is an example of adjoining sprites. The program creates an outer space environment. It draws stars, a planet and a spacecraft similar to Apollo. The spacecraft is drawn, then stored into two data strings, A$ and B$. The front of the spaceship, the capsule, is stored in sprite 1. The back half of the spaceship, the retro rocket, is stored in sprite 2. The spacecraft flies slowly across the screen. Since it is traveling so slowly and is very far from Earth, it needs to be launched earthward with the retro rockets. After a while, the retro rockets fire and propel the capsule safely to Earth. Here's the program listing: 5 COLOR 4,1:COLOR 0,1:COLOR 1,2 :REM SELECT COLORS 10 GRAPHIC 1,1 :REM SET HIRES MODE 17 FOR I=1 TO 40 18 X=INT (RND (1)*320)+1 19 Y=INT (RND (1)*200)+1 21 DRAW 1,X,Y:NEXT I :REM DRAW STARS 22 BOX 0,0,5,70,40,,1 :REM CLEAR BOX 23 BOX 1,1,5,70,40:COLOR1,8 :REM BOX-IN SPACESHIP 24 CIRCLE1,190,90,35,25:PAINT1,190,95 :REM DRAW AND PAINT THE PLANET 25 FOR I=90 TO 96 STEP 3:CIRCLE 1,190,I,65,10:NEXT I 26 DRAW 1,10,17TO16,17TO32,10TO33,20TO32,30TO16,23TO10,23TO10,17 28 DRAW 1,19,24TO20,21TO27,25TO26,28 :REM BOTTOM WINDOW 35 DRAW 1,20,19TO20,17TO29,13TO30,18TO28,23TO20,19:REM TOP WINDOW 38 PAINT 1,13,20 :REM PAINT SPACESHIP 40 DRAW 1,34,10TO36,20TO34,30TO45,30TO46,20TO45,10TO34,10 42 DRAW 1,45,10TO51,12TO57,10TO57,17TO51,15TO46,17:REM ENGINE 1 43 DRAW 1,46,22TO51,24TO57,22TO57,29TO51,27TO45,29:REM ENGINE 2 44 PAINT1,40,15:PAINT1,47,12:PAINT1,47,26:DRAW0,45,30TO46,20TO45,10 45 DRAW 0,34,14TO44,14:DRAW 0,34,21TO44,21:DRAW 0,34,28TO44,28 47 SSHAPE A$,10,10,33,32 :REM SAVE SPRITE IN A$ 48 SSHAPE B$,34,10,57,32 :REM SAVE SPRITE IN B$ 50 SPRSAV A$,1 :REM SPRITE1 DATA 55 SPRSAV B$,2 :REM SPRITE2 DATA 60 SPRITE 1,1,3,0,0,0,0 :REM ENABLE SPRITE 1 IN RED 65 SPRITE 2,1,7,0,0,0,0 :REM ENABLE SPRITE 2 IN BLUE 82 MOVSPR 1,150,150 :REM POSITION SPRITE 1 83 MOVSPR 2,172,150 :REM POSITION SPRITE 2 85 MOVSPR 1,270 # 5 :REM ANIMATE SPRITE 1 87 MOVSPR 2,270 # 5 :REM ANIMATE SPRITE 2 90 FOR I=1 TO 5000:NEXT I 92 MOVSPR 1,150,150 :REM RETRO POSITION 93 MOVSPR 2,174,150 95 MOVSPR 1,270 #10 :REM SPLIT SPRITES 1 & 2 96 MOVSPR 2,90 #5 :REM 97 FOR I=1 TO 1200:NEXT I 98 SPRITE 2,0 :REM TURN OFF SPRITE 2 99 FOR I=1 TO 5000:NEXT I 100 GRAPHIC 0,1 :REM RETURN TO TEXT Here's an explanation of the program:
Working with adjoining sprites can be more interesting than working with a single sprite. The main points to remember are: (1) Make sure you position the SSHAPE coordinates at the correct locations on the screen, so you save the picture data properly; and (2) be certain to position the sprite coordinates in the correct location when you are joining them with the MOVSPR statement. In this example you positioned sprite 2 at a location 24 pixels to the right of sprite 1. Once you master the technique of joining two sprites, try more than two. The more sprites you join, the better the detail and animation will be in your programs. The C128 has two additional sprite commands, SPRCOLOR and COLLISION, which are not covered in the section. To learn about these commands, refer to Chapter V, BASIC 7.0 Encyclopaedia. 6.3.12 Storing Sprite Data in Binary FilesNOTE: The following explanation assumes some knowledge of machine language, memory locations, binary files and object code files. The Commodore 128 has two new commands BLOAD and BSAVE, which make handling sprite data neat and easy. The "B" in BLOAD and BSAVE stands for BINARY. The BSAVE and BLOAD commands save and load binary files to and from disk. A binary file consists of either a portion of machine language program, or a collection of data within a specified address range. You may be familiar with the SAVE command within the built-in machine language monitor. when you use this SAVE command, the resulting file on disk is considered a binary file. A binary file is easier to work with than an object code file since you can load a binary file without any further preparation. An object code file must be loaded with a loader, as in the Commodore 64 Assembler Development System; then the SYSTEM command (SYS) must be used to execute it. When loading binary files, remember to load them in either of these two ways: LOAD "binary filename",8,1or BLOAD "binary filename",B0,PStartwhere start is 3584 if you are loading sprite data files. In the first method you must specify the ,1 at the end or else the computer treats it as a BASIC program file and loads it at the beginning of BASIC text. The ,1 tells the computer to load the binary file into the same place from which it was stored. You're probably wondering what this has to do with sprites. Here's the connection. The Commodore 128 has a dedicated portion of memory ranging from the address 3584 ($0E00) throught 4095 ($0FFF), where sprite data is stored. This portion of memory takes up 512 bytes. As you know, a sprite is 24 pixels wide and 21 pixels tall. Each pixel requires one bit of memory. If the bit in a sprite is off (equal to 0), the corresponding pixel on the screen is considered off and takes the color of the background. If a pixel within a sprite is on (equal to 1), the corresponding pixel on the screen is turned on in the foreground color. The combination of zeroes and ones produce the image you see on the screen. Since a sprite is 24 by 21 pixels and each pixel requires a bit of storage in memory, one sprite uses 63 bytes of memory. See Figure 6-8 to understand the storage requirements for a sprite's data. Figure 6-8. Sprite Data Requirements.12345678 12345678 12345678 1 ........ ........ ........ 2 ........ ........ ........ 3 ........ ........ ........ 4 ........ ........ ........ 5 ........ ........ ........ 6 ........ ........ ........ 7 ........ ........ ........ 8 ........ ........ ........ 9 ........ ........ ........ 10 ........ ........ ........ 11 ........ ........ ........ 12 ........ ........ ........ 13 ........ ........ ........ 14 ........ ........ ........ 15 ........ ........ ........ 16 ........ ........ ........ 17 ........ ........ ........ 18 ........ ........ ........ 19 ........ ........ ........ 20 ........ ........ ........ 21 ........ ........ ........ Each Row = 24 bits = 3 bytes A sprite requires 63 bytes of data. Each sprite block is actually made up of 64 bytes; the extra byte is not used. Since the Commodore 128 has eight sprites and each one consists of an 64-byte sprite block, the computer needs 512 (8 x 64) bytes to represent the data of all eight sprite images. The entire area where all eight sprite blocks reside starts at memory location 3584 ($0E00) and ends at location 4095 ($0FFF). Figure 6-9 lists the memory address ranges where each individual sprite stores its data: Figure 6-9. Memory Address Ranges for Sprite Storage.$0FFF (4095 decimal) ]- Sprite 8 $0FC0 ]- Sprite 7 $0F80 ]- Sprite 6 $0F40 ]- Sprite 5 $0F00 ]- Sprite 4 $0EC0 ]- Sprite 3 $0E80 ]- Sprite 2 $0E40 ]- Sprite 1 $0E00 (3584 Decimal) 6.3.12.1 BSAVEOnce you exit from the SPRDEF mode, you can save your sprite data in binary sprite files. This way, you can load any collection of sprites back into the Commodore 128 neatly and easily. Use this command to save your sprite data into a binary file: BSAVE "filename", B0, P3584 TO P4096 The "B0" specifies that you are saving the sprite data from bank 0. The parameters P3584 TO P4096 signify you are saving the address range 3584 ($0E00) through 4095 ($0FFF), which is the range where all the sprite data is stored. You do not have to define all of the sprites when you BSAVE them. The sprites you do define are BSAVEd from the correct sprite block. The undefined sprites are also BSAVEd in the binary file from the appropriate sprite block, but they do not matter to the computer. It is easier to BSAVE the entire 512 bytes of all eight sprites, regardless if all the sprites are used, rather than BSAVE each sprite block individually. 6.3.12.2 BLOADLater on, when you want to use the sprites again, just BLOAD the entire 512 bytes for all of the sprites into the range starting at 3584 ($0E00) and ending at 4095 ($0FFF). Here's the command to accomplish this: BLOAD "filename"[, B0, P3584] Use the same filename which you BSAVEd your original sprite data. The B0 stands for bank number 0 and the P3584 specifies the starting location where the binary sprite data is loaded. The last two parameters are optional. *************************************************************************** In this section you have seen how much the new Commodore 7.0 BASIC commands can simplify the usually complex process of creating and animating graphic images. The next section describes some other new BASIC 7.0 commands that do the same for music and sound. |
page URL: www.bigfoot.com/~c128page/c128sg/sect-06b.htm
contact: c128page@bigfoot.com