True Basic Programming Techniques: R.W.Tarara Saint Mary's College Notre Dame, IN rtarara@saintmarys.edu MASKED, BITMAPPED ANIMATION WHAT? Masked, bitmapped animation is the technique that lets you move an object across a complex background. The object can be of complex shape and can have 'transparent' regions within through which the background will show. The techniques for accomplishing this kind of animation within Windows are slightly different from the DOS versions (and unfortunately--just like with the old Mac versions, still don't work with Version 5 and above for the Mac). In fact, the new TrueBasic versions allow for a much improvement in the animation appearance. HOW? You must begin by drawing the bitmapped images. For illustration, I will show TrueBasic commands for drawing a simple ball, however, the instructions below can be used (with a drawing program) to create complex graphic objects. 1. The background color of the IMAGE must be BLACK. Any transparent areas of the image must also be BLACK. 2. The main IMAGE can be any combination of colors from the palette. You can now have up to 256 different colors. The code below draws the main image of a red ball and saves it as ball$. CLEAR SET COLOR "black" BOX AREA 1,50,1,50 SET COLOR "red" BOX CIRCLE 1,50,1,50 FLOOD 25,25 BOX KEEP 1,50,1,50 in ball$ 3. You must now create a MASK. The background of the MASK must be WHITE and for every non-black pixel in the IMAGE, you need a corresponding BLACK pixel in the MASK. The code below draws the mask for the ball image and saves it as ballmask$. clear SET COLOR "white" BOX AREA 1,50,1,50 SET COLOR "black" BOX CIRCLE 1,50,1,50 FLOOD 25,25 BOX KEEP 1,50,1,50 in ballmask$ 4. Draw any kind of background you want--even use a full color jpeg image. As an example, we'll draw a green rectangular grid as a background. Clear SET COLOR "green" FOR x = 1 to xmax step 20 BOX LINES x,x,1,ymax NEXT x FOR y = 1 to ymax step 20 BOX LINES 1,xmax,y,y NEXT y Where xmax is the maximum horizontal coordinate and ymax is the maximum vertical coordinate for the window being used. 5. Save the rectangular area of the background over which you intend to display the ball image. Save this to a string variable. BOX KEEP x,x+50,y,y-50 in bkground$ 6) Then BOX SHOW the MASK using AND. BOX SHOW ballmask$ at x,y using "and" 7) Then immediately BOX SHOW the IMAGE at the same location using OR. BOX SHOW ball$ at x,y using "or" 8) Pause a short bit Pause .1 9) BOX SHOW the background string over the Image. BOX SHOW bkground$ at x,y 10) Increment x and/or y and repeat--save background, box show mask using and, box show image using or, pause, box show background. This works and you will get animations that will look the same as you could do in the DOS versions. HOWEVER, there is a way to improve this dramatically under Version 5.x and above. By using TWO screens, one invisible, you can avoid the flickering that invevitably occurs with the above technique as you catch screen refreshes in between the BOX SHOW commands. To illustrate the technique, I'll show the whole program below for a ball that bounces off the screen edges and moves over the rectangular background. LIBRARY "d:\tbsilver\tblibs\truectrl.trc" CALL tc_init CALL tc_setunitstopixels CALL tc_show_default (0) SET MODE "color256" RANDOMIZE ! set up path to the True Controls Library ! Create a full screen Window with title bar. See tutorial on Full Screen Graphics Windows. DIM vals(6) CALL TC_GETSCREENSIZE(XL,XR,YB,YT) CALL tc_getsysinfo("MENU HEIGHT",VAL$,VALS()) LET winbar=vals(1) CALL tc_getsysinfo("TITLE BAR HEIGHT",VAL$,VALS()) LET winbar=winbar+vals(1) CALL tc_win_create (w1,"close|size|title",0,XR-1,YB-1,WINBAR) CALL tc_win_settitle(w1,"BOUNCE") ASK PIXELS xmax,ymax SET WINDOW 1,xmax,ymax,1 CALL tc_show (w1) !create a second window (W2) of identical size CALL tc_win_create (w2,"close|size|title",0,XR-1,YB-1,WINBAR) CALL tc_win_settitle(w2,"BOUNCE2") SET WINDOW 1,xmax,ymax,1 CALL tc_show (w2) ! draw ball SET BACK "white" CLEAR SET COLOR "black" BOX AREA 1,50,1,50 SET COLOR "red" BOX CIRCLE 1,50,1,50 FLOOD 25,25 BOX KEEP 1,50,1,50 in ball$ ! draw ball mask CLEAR SET COLOR "white" BOX AREA 1,50,1,50 SET COLOR "black" BOX CIRCLE 1,50,1,50 FLOOD 25,25 BOX KEEP 1,50,1,50 in ballmask$ ! draw background CLEAR SET COLOR "green" FOR x = 1 to xmax step 20 BOX LINES x,x,1,ymax NEXT x FOR y = 1 to ymax step 20 BOX LINES 1,xmax,y,y NEXT y SET COLOR "blue" PLOT TEXT, AT 250,20:"Hit any key to end" ! draw border BOX LINES 10,xmax-10,ymax-10,10 BOX LINES 9,xmax-9,ymax-9,9 ! Redraw the identical background in W1 CALL tc_win_target (w1) SET COLOR "green" FOR x = 1 to xmax step 20 BOX LINES x,x,1,ymax NEXT x FOR y = 1 to ymax step 20 BOX LINES 1,xmax,y,y NEXT y SET COLOR "blue" PLOT TEXT, AT 250,20:"Hit any key to end" BOX LINES 10,xmax-10,ymax-10,10 BOX LINES 9,xmax-9,ymax-9,9 ! set starting position of ball and randomly select x and y velocities LET x = 400 LET y = 300 LET vx = int(8*rnd+2) LET vy = int(8*rnd+2) LET d = 0 ! The tc_win_target command directs input to the selected Window BUT DOES NOT SHOW the Window. The visible window in this program is now W2. CALL tc_win_target (w1) DO while d=0 ! increment x and y and check for collisions with the right, left, top, and bottom of screen. LET x = x+vx IF x < 11 then LET x = 11 LET vx = -vx END IF IF x > xmax-60 then LET x = xmax-60 LET vx = -vx END IF LET y = y+vy IF y < 60 then LET y = 60 LET vy = -vy END IF IF y > ymax-11 then LET y = ymax-11 LET vy = -vy END IF BOX KEEP x,x+50,y,y-50 in bkground$ BOX SHOW ballmask$ at x,y using "and" BOX SHOW ball$ at x,y using "or" ! copy the image region of W1 and keep in showball$. A region larger than the image is saved such that the next increment of movement will not extend outside the saved region. On fast enough machines, the ENTIRE screen can be save in showball$. BOX KEEP x-10,x+60,y+10,y-60 in showball$ ! Switch output to the visible Window W2 and display the image region. CALL tc_win_switch (w2) BOX SHOW showball$ at x-10,y+10 PAUSE .05 ! Switch back to the invisible screen and complete the animation sequence--then repeat. CALL tc_win_target (w1) BOX SHOW bkground$ at x,y IF key input then GET KEY d LOOP GET KEY d CALL tc_cleanup END To summarize the technique above: Set up two identical windows and draw the same background in each. Make one window visible and then switch to the second invisible window. Use the masked bitmapped techniques outlined earlier IN THE INVISIBLE window-save background, box show mask using 'and'., box show image using 'or'. Save the image region or whole screen if possible (speed of computer will determine) in a box show string. Switch to the visible screen and box show the saved string from step 4 at the appropriate position. Switch back to the invisible screen and restore the background, then repeat the process. The advantage of this technique is that the animation appears very smooth on the visible screen. You lose all the flickering that was common using these techniques in DOS. The limitations are in the speed of the computer and the size of the image being moved. If you save only a small region to be displayed between windows, be sure it is large enough to overlap any movement in the image to the next 'frame' of the animation, otherwise some pieces of the image will get permanently painted on the background. NOTES for DOS programmers. The main difference in the Windows technique versus the DOS technique for masked bitmapped animation are: You must use BLACK and WHITE as the background/mask colors rather than color '0' and color '15' as you did in VGA mode. The background of the IMAGE is now BLACK rather than the background color. You use the using 'or' rather than using 'xor' when placing the image. By drawing on the invisible screen you can greatly improve the appearance of the animation. Rick Tarara