home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Graphics / graphics-16000.iso / msdos / animutil / fastgfx / fg303b / manuals.arj / USER12.DOC < prev    next >
Text File  |  1993-10-02  |  26KB  |  629 lines

  1. Chapter 12
  2.  
  3.  
  4.  
  5.  
  6.  
  7. Animation Techniques
  8. 238   Fastgraph User's Guide
  9.  
  10. Overview
  11.  
  12.      Unlike other microcomputers, the IBM PC and PS/2 family of systems do
  13. not have any special graphics hardware or firmware to help in performing
  14. animation.  This means that any animation done on these systems must be
  15. implemented entirely through software.  This chapter will show how to do this
  16. using Fastgraph's video page management, image display, and block transfer
  17. routines.  The methods described in this chapter are not intended to be all
  18. inclusive, for that would itself fill a separate volume at least as large as
  19. this manual.  However, the animation techniques presented here should provide
  20. a basis that you can readily extend to develop more sophisticated uses of
  21. animation.  The examples in this chapter are restricted to graphics video
  22. modes.
  23.  
  24.  
  25. Simple Animation
  26.  
  27.      The first type of animation we'll examine is called simple animation.
  28. In simple animation, we display an object, erase it, and then display it in a
  29. new position.  When we perform this "erase and redisplay" sequence
  30. repetitively, the object moves.  This method, however, has two drawbacks.
  31. First, unless the object is rather small, it will flicker because the erasing
  32. and display of the object does not coincide with the refresh rate of the
  33. video display.  Second, and perhaps more importantly, anything underneath the
  34. object is not saved as the object moves across it.  Despite these
  35. limitations, simple animation is sometimes useful, and it is a good place to
  36. begin our discussion of animation techniques.
  37.  
  38.      Example 12-1 moves a small bright green rectangle (magenta in CGA) from
  39. left to right across the screen in any 320 by 200 color graphics mode.  The
  40. program moves the rectangle, 20 pixels wide and 10 pixels high, using a for
  41. loop.  This loop first uses the fg_clprect routine to display the rectangle,
  42. then uses the fg_waitfor routine to leave the object on the screen
  43. momentarily, and finally uses fg_clprect again to erase the rectangle by
  44. redisplaying it in the original background color (the fg_waitfor routine is
  45. described in Chapter 16).  We use fg_clprect rather than fg_rect because the
  46. first few and last few loop iterations result in at least part of the
  47. rectangle being off the screen.  Each successive loop iteration displays the
  48. rectangle five pixels to the right of its previous position.
  49.  
  50.                                 Example 12-1.
  51.  
  52.           #include <fastgraf.h>
  53.           #include <stdio.h>
  54.           #include <stdlib.h>
  55.           void main(void);
  56.  
  57.           void main()
  58.           {
  59.              int new_mode, old_mode;
  60.              int x;
  61.  
  62.              /* initialize the video environment */
  63.  
  64.              new_mode = fg_bestmode(320,200,1);
  65.              if (new_mode < 0 || new_mode == 12) {
  66.                                        Chapter 12:  Animation Techniques   239
  67.  
  68.                 printf("This program requires a 320 ");
  69.                 printf("x 200 color graphics mode.\n");
  70.                 exit(1);
  71.                 }
  72.              old_mode = fg_getmode();
  73.              fg_setmode(new_mode);
  74.  
  75.              /* move the object across the screen */
  76.  
  77.              for (x = -20; x < 320; x+=5) {
  78.                 fg_setcolor(10);
  79.                 fg_clprect(x,x+19,95,104);
  80.                 fg_waitfor(1);
  81.                 fg_setcolor(0);
  82.                 fg_clprect(x,x+19,95,104);
  83.                 }
  84.  
  85.              /* restore the original video mode and return to DOS */
  86.  
  87.              fg_setmode(old_mode);
  88.              fg_reset();
  89.           }
  90.  
  91.      Example 12-2 is the same as example 12-1, but it shows what happens when
  92. we move the rectangle across an existing background (in this case, the
  93. background is solid white).  If you run this program, you'll see that the
  94. rectangle leaves a trail of color 0 behind it.  While this might be
  95. occasionally useful, it demonstrates that simple animation is destructive
  96. because it does not preserve the background.  In this example, if we changed
  97. the second call to fg_setcolor within the for loop to revert to color 15
  98. instead of color 0, the background would be restored.  In general, though, it
  99. may not be this easy to replace the background, so we must rely on some other
  100. method for preserving it.
  101.  
  102.                                 Example 12-2.
  103.  
  104.           #include <fastgraf.h>
  105.           #include <stdio.h>
  106.           #include <stdlib.h>
  107.           void main(void);
  108.  
  109.           void main()
  110.           {
  111.              int new_mode, old_mode;
  112.              int x;
  113.  
  114.              /* initialize the video environment */
  115.  
  116.              new_mode = fg_bestmode(320,200,1);
  117.              if (new_mode < 0 || new_mode == 12) {
  118.                 printf("This program requires a 320 ");
  119.                 printf("x 200 color graphics mode.\n");
  120.                 exit(1);
  121.                 }
  122.              old_mode = fg_getmode();
  123.              fg_setmode(new_mode);
  124. 240   Fastgraph User's Guide
  125.  
  126.  
  127.              /* draw some type of background */
  128.  
  129.              fg_setcolor(15);
  130.              fg_rect(0,319,0,199);
  131.  
  132.              /* move the object across the screen */
  133.  
  134.              for (x = -20; x < 320; x+=5) {
  135.                 fg_setcolor(10);
  136.                 fg_clprect(x,x+19,95,104);
  137.                 fg_waitfor(1);
  138.                 fg_setcolor(0);
  139.                 fg_clprect(x,x+19,95,104);
  140.                 }
  141.  
  142.              /* restore the original video mode and return to DOS */
  143.  
  144.              fg_setmode(old_mode);
  145.              fg_reset();
  146.           }
  147.  
  148.      To summarize, we see that simple animation is easy to implement, but it
  149. is destructive and typically causes the animated object to flicker.  For
  150. these reasons, it is not used too frequently.
  151.  
  152.  
  153. XOR Animation
  154.  
  155.      "Exclusive or" animation, or XOR animation for short, is an interesting
  156. extension of simple animation and is most useful when animating a single-
  157. color object against a single-color background.  Like simple animation, it
  158. uses the "erase and redisplay" technique to move an object, but it does this
  159. differently.  Instead of erasing the object by displaying it in the
  160. background color, XOR animation does so by displaying it in the same color
  161. using an exclusive or, or XOR, operation.  This method relies on a specific
  162. property of the exclusive or operator:
  163.  
  164.                (object XOR background) XOR object = background
  165.  
  166. In other words, if you XOR something twice in the same position, the result
  167. is the same as the original image in that position.
  168.  
  169.      Example 12-3 demonstrates XOR animation.  This program is similar to
  170. example 12-2, but it only runs in the 320 by 200 EGA graphics mode (mode 13).
  171. After establishing the video mode, it uses the Fastgraph routine fg_setfunc
  172. to select XOR mode.  This causes any subsequent graphics output to be XORed
  173. with the contents of video memory instead of just replacing it.  The
  174. fg_setfunc routine is described further in Chapter 17.
  175.  
  176.      The other differences between examples 12-3 and 12-2 are that the call
  177. to fg_setcolor has been moved outside the for loop, and that fg_setcolor
  178. takes a different value.  Since the existing background is bright white
  179. (color 15), we can't just use color 10 if we want to display a bright green
  180. object.  The desired value is that which when XORed with color 15 produces
  181. color 10; the easiest way to obtain this value is to XOR these two numbers.
  182.                                        Chapter 12:  Animation Techniques   241
  183.  
  184. The call to fg_setcolor can be moved outside the loop because we display the
  185. object using the same color index throughout.
  186.  
  187.                                 Example 12-3.
  188.  
  189.           #include <fastgraf.h>
  190.           #include <stdio.h>
  191.           #include <stdlib.h>
  192.           void main(void);
  193.  
  194.           void main()
  195.           {
  196.              int old_mode;
  197.              int x;
  198.  
  199.              /* initialize the video environment */
  200.  
  201.              if (fg_testmode(13,1) == 0) {
  202.                 printf("This program requires EGA.\n");
  203.                 exit(1);
  204.                 }
  205.              old_mode = fg_getmode();
  206.              fg_setmode(13);
  207.              fg_setfunc(3);
  208.  
  209.              /* draw some type of background */
  210.  
  211.              fg_setcolor(15);
  212.              fg_rect(0,319,0,199);
  213.  
  214.              /* move the object across the screen */
  215.  
  216.              fg_setcolor(10^15);
  217.              for (x = -20; x < 320; x+=5) {
  218.                 fg_clprect(x,x+19,95,104);
  219.                 fg_waitfor(1);
  220.                 fg_clprect(x,x+19,95,104);
  221.                 }
  222.  
  223.              /* restore the original video mode and return to DOS */
  224.  
  225.              fg_setmode(old_mode);
  226.              fg_reset();
  227.           }
  228.  
  229.  
  230.      Fastgraph only supports the XOR pixel operation in the native EGA and
  231. VGA graphics video modes (modes 13 through 18).  Thus, you cannot use XOR
  232. animation in CGA, Tandy/PCjr, Hercules, or MCGA graphics modes.
  233.  
  234.      While XOR animation is non-destructive (that is, it restores the
  235. original background), it still suffers from the flickering encountered in
  236. simple animation.  In spite of this, it may be useful when animating a
  237. single-color object against a single-color background.
  238. 242   Fastgraph User's Guide
  239.  
  240.  
  241. Static Frame Animation
  242.  
  243.      Static frame animation uses a different strategy than simple animation
  244. or XOR animation.  The general scheme of this method is to create the entire
  245. animation sequence off-screen and then successively display each item, or
  246. frame, in this sequence on one position of the visual video page.  This
  247. results in a visually appealing animation that is non-destructive and does
  248. not include the flickering associated with simple animation and XOR
  249. animation.  Static frame animation requires the visual video page and one or
  250. more additional pages to implement.  The number of pages needed depends on
  251. the number of frames and the size of each frame.
  252.  
  253.      Example 12-4 runs in any 320 by 200 color graphics video mode and
  254. illustrates a simple use of static frame animation.  The program displays an
  255. animation sequence containing 12 frames; it displays this sequence three
  256. times.  The animation sequence consists of a bright green rectangle (magenta
  257. in CGA) moving from left to right across the center of the frame.  Each frame
  258. is 96 pixels wide and 50 pixels high.  The 12 frames are set up on an off-
  259. screen video page as shown below.
  260.  
  261.                          0       95 96     191 192    287
  262.  
  263.                       0
  264.                           frame 1    frame 2    frame 3
  265.                      49
  266.  
  267.                      50
  268.                           frame 4    frame 5    frame 6
  269.                      99
  270.  
  271.                     100
  272.                           frame 7    frame 8    frame 9
  273.                     149
  274.  
  275.                     150
  276.                           frame 10   frame 11   frame 12
  277.                     199
  278.  
  279.  
  280.      Example 12-4 first establishes the video mode and allocates the
  281. additional video page (needed if using a video mode in which page 1 is a
  282. virtual video page).  The program then generates the background for frame 1;
  283. the background is a blue rectangle (cyan in CGA) with a white ellipse
  284. centered on it.  After the call to fg_ellipse, the first frame is ready.
  285.  
  286.      The next step is to create the remaining 11 frames.  In frame 2, the
  287. right half of the 20-pixel wide rectangle will enter the left edge of the
  288. frame.  In frame 3, the rectangle will be ten pixels farther right, or
  289. aligned against the left edge of the frame.  In frames 4 through 12, the
  290. rectangle will be ten pixels farther right in each frame, so by frame 12 only
  291. the left half of the rectangle appears on the right edge of the frame.  The
  292. first for loop in the program builds frames 2 through 12 by copying the
  293. background from frame 1 and then displaying the rectangle (that is, the
  294. animated object) in the proper position for that frame.
  295.                                        Chapter 12:  Animation Techniques   243
  296.      The second for loop performs the animation sequence.  To display the 12-
  297. frame sequence three times, it must perform 36 iterations.  The loop simply
  298. copies each frame from the proper position on video page 1 to the middle of
  299. the visual video page.  Note how the fg_waitfor routine is used to pause
  300. momentarily between each frame.
  301.  
  302.                                 Example 12-4.
  303.  
  304.        #include <fastgraf.h>
  305.        #include <stdio.h>
  306.        #include <stdlib.h>
  307.        void main(void);
  308.  
  309.        #define VISUAL 0
  310.        #define HIDDEN 1
  311.  
  312.        int xmin[] = {  0, 96,192,  0, 96,192,  0, 96,192,  0, 96,192};
  313.        int ymax[] = { 49, 49, 49, 99, 99, 99,149,149,149,199,199,199};
  314.  
  315.        void main()
  316.        {
  317.           int new_mode, old_mode;
  318.           int frame, offset;
  319.           int i, x, y;
  320.  
  321.           /* initialize the video environment */
  322.  
  323.           new_mode = fg_bestmode(320,200,2);
  324.           if (new_mode < 0 || new_mode == 12) {
  325.              printf("This program requires a 320 ");
  326.              printf("x 200 color graphics mode.\n");
  327.              exit(1);
  328.              }
  329.           old_mode = fg_getmode();
  330.           fg_setmode(new_mode);
  331.           fg_allocate(HIDDEN);
  332.  
  333.           /* draw the background in the upper left corner */
  334.  
  335.           fg_setpage(HIDDEN);
  336.           fg_setcolor(1);
  337.           fg_rect(0,95,0,49);
  338.           fg_setcolor(15);
  339.           fg_move(48,25);
  340.           fg_ellipse(20,20);
  341.  
  342.           /* display the animated object against each background */
  343.  
  344.           fg_setcolor(10);
  345.           offset = -10;
  346.           for (i = 1; i < 12; i++) {
  347.              x = xmin[i];
  348.              y = ymax[i];
  349.              fg_transfer(0,95,0,49,x,y,HIDDEN,HIDDEN);
  350.              fg_setclip(x,x+95,0,199);
  351.              fg_clprect(x+offset,x+offset+19,y-29,y-20);
  352.              offset += 10;
  353. 244   Fastgraph User's Guide
  354.  
  355.              }
  356.  
  357.           /* slide the object across the background three times */
  358.  
  359.           for (i = 0; i < 36; i++) {
  360.              frame = i % 12;
  361.              x = xmin[frame];
  362.              y = ymax[frame];
  363.              fg_transfer(x,x+95,y-49,y,112,124,HIDDEN,VISUAL);
  364.              fg_waitfor(2);
  365.              }
  366.  
  367.           /* restore the original video mode and return to DOS */
  368.  
  369.           fg_freepage(HIDDEN);
  370.           fg_setmode(old_mode);
  371.           fg_reset();
  372.        }
  373.  
  374.  
  375. Dynamic Frame Animation
  376.  
  377.      Dynamic frame animation is similar to static frame animation, but all
  378. the animation frames are built as needed during the animation sequence
  379. instead of in advance.  When using this method, you must first store a copy
  380. of the background on an off-screen video page.  Then, to build a frame,
  381. create another copy (called the workspace) of the background elsewhere on the
  382. off-screen page (or even to a different off-screen page) and display the
  383. object on that copy.  Finally, transfer the workspace to the visual page.
  384. Like static frame animation, this method produces a non-destructive, flicker-
  385. free animation sequence.
  386.  
  387.      Example 12-5 is functionally identical to example 12-4, but it uses
  388. dynamic rather than static frame animation.  As before, the program builds
  389. the background in the upper left corner of video page 1, but it then uses
  390. fg_transfer to copy it to the center of the visual video page.  The for loop
  391. builds each frame as it is needed and also copies it to the center of the
  392. visual page.  Again, fg_waitfor creates the necessary pause between frames.
  393.  
  394.                                 Example 12-5.
  395.  
  396.          #include <fastgraf.h>
  397.          #include <stdio.h>
  398.          #include <stdlib.h>
  399.          void main(void);
  400.  
  401.          #define VISUAL 0
  402.          #define HIDDEN 1
  403.  
  404.          void main()
  405.          {
  406.             int new_mode, old_mode;
  407.             int frame, offset;
  408.             int i;
  409.  
  410.                                        Chapter 12:  Animation Techniques   245
  411.  
  412.             /* initialize the video environment */
  413.  
  414.             new_mode = fg_bestmode(320,200,2);
  415.             if (new_mode < 0 || new_mode == 12) {
  416.                printf("This program requires a 320 ");
  417.                printf("x 200 color graphics mode.\n");
  418.                exit(1);
  419.                }
  420.             old_mode = fg_getmode();
  421.             fg_setmode(new_mode);
  422.             fg_allocate(HIDDEN);
  423.  
  424.             /* draw the background in the upper left corner */
  425.  
  426.             fg_setpage(HIDDEN);
  427.             fg_setcolor(1);
  428.             fg_rect(0,95,0,49);
  429.             fg_setcolor(15);
  430.             fg_move(48,25);
  431.             fg_ellipse(20,20);
  432.  
  433.             /* copy it to the center of the visual page */
  434.  
  435.             fg_transfer(0,95,0,49,112,124,HIDDEN,VISUAL);
  436.  
  437.             /* slide the object across the background three times */
  438.  
  439.             fg_setcolor(10);
  440.             for (i = 0; i < 36; i++) {
  441.                frame  = i % 12;
  442.                offset = 10 * frame - 10;
  443.                fg_transfer(0,95,20,29,112,105,HIDDEN,HIDDEN);
  444.                fg_rect(112+offset,131+offset,96,105);
  445.                fg_transfer(112,207,96,105,112,105,HIDDEN,VISUAL);
  446.                fg_waitfor(2);
  447.                }
  448.  
  449.             /* restore the original video mode and return to DOS */
  450.  
  451.             fg_freepage(HIDDEN);
  452.             fg_setmode(old_mode);
  453.             fg_reset();
  454.          }
  455.  
  456.      Two items in example 12-5 merit further discussion.  First, we have
  457. chosen our workspace on page 1 so it uses the same screen space coordinates
  458. as the image area on the visual page.  This is not necessary unless you are
  459. using the fg_restore routine instead of fg_transfer.  Second, the program can
  460. use the faster fg_rect routine in place of fg_clprect.  It can do this
  461. because even though the object will extend beyond the workspace limits, we
  462. only transfer the workspace itself.  However, for this to function properly,
  463. the workspace's horizontal limits must fall on byte boundaries.
  464.  
  465.      Note too that we do not need to transfer the entire frame during the
  466. animation sequence.  In example 12-5, we know the vertical extremes of the
  467. moving image are y=96 and y=105, so we only transfer 10 rows instead of the
  468. 246   Fastgraph User's Guide
  469.  
  470. entire frame.  We could similarly compute the x extremes for each frame and
  471. only transfer the necessary portion.  Recall, however, that fg_transfer
  472. extends the horizontal coordinates to byte boundaries, so we may copy a few
  473. extra pixels as well.  This may or may not affect the animation sequence.
  474. Again, the problem is eliminated if you align your workspace on byte
  475. boundaries.
  476.  
  477.      When we use dynamic frame animation, it is easy to change the number of
  478. frames in the animation sequence.  Suppose we wish to produce a smoother
  479. animation by increasing the number of frames from 12 to 24.  This means the
  480. object will move in increments of five pixels instead of ten.  The only
  481. changes needed are to double the number of loop iterations, modify the
  482. calculations for the frame number and offset values as shown below, and
  483. reduce the fg_waitfor pause from 2 to 1.
  484.  
  485.                            frame  = i % 24;
  486.                            offset = 5 * frame - 10;
  487.  
  488. Compare this to all the changes that would be necessary if we were using
  489. static frame animation.
  490.  
  491.  
  492. Page Flipping
  493.  
  494.      Page flipping is a variation of frame animation in which you construct
  495. images on off-screen video pages and then repetitively make those pages the
  496. visual page.  We can further divide the page flipping technique into static
  497. and dynamic variants, as we did with frame animation.
  498.  
  499.      In static page flipping, we construct the entire animation sequence in
  500. advance, with one frame per video page.  Once this is done, we can display
  501. each frame by using the fg_setvpage routine to switch instantly from one
  502. video page to another.  Although this produces a smooth, flicker-free
  503. animation, we cannot carry the sequence very far before running out of video
  504. pages (and hence animation frames).
  505.  
  506.      In dynamic page flipping, we construct each animation frame when it is
  507. needed.  As in static page flipping, we construct each frame on a separate
  508. video page.  However, as example 12-6 demonstrates, we only need three video
  509. pages to produce the animation sequence, regardless of the number of frames
  510. in the sequence.  Two of the three video pages will alternate as the visual
  511. page, while the remaining video page keeps a copy of the background.
  512.  
  513.      Example 12-6, which performs an animation sequence similar to examples
  514. 12-4 and 12-5, illustrates dynamic frame animation in the 320 by 200 EGA
  515. graphics video mode (mode 13).  The program begins by displaying the
  516. background on video page 2.  Video pages 0 and 1 will alternate as the visual
  517. page; the page that is not the visual page is called the hidden page.  We
  518. start with page 0 as the visual page, and hence page 1 as the hidden page.
  519. To build each frame, the program uses fg_transfer to copy the background from
  520. page 2 to the hidden page and then uses fg_clprect to display the animated
  521. object at the correct position on the hidden page.  After this, it displays
  522. the next frame by using fg_setvpage to make the hidden page the visual page.
  523. Before beginning the next iteration, the program toggles the hidden page
  524. number in preparation for the next frame.
  525.                                        Chapter 12:  Animation Techniques   247
  526.  
  527.                                 Example 12-6.
  528.  
  529.           #include <fastgraf.h>
  530.           #include <stdio.h>
  531.           #include <stdlib.h>
  532.           void main(void);
  533.  
  534.           void main()
  535.           {
  536.              int old_mode;
  537.              int hidden;
  538.              int x;
  539.  
  540.              /* initialize the video environment */
  541.  
  542.              if (testmode(fg_13,3) == 0) {
  543.                 printf("This program requires EGA.\n");
  544.                 exit(1);
  545.                 }
  546.              old_mode = fg_getmode();
  547.              fg_setmode(13);
  548.  
  549.              /* draw the background on page two */
  550.  
  551.              fg_setpage(2);
  552.              fg_setcolor(1);
  553.              fg_rect(0,319,0,199);
  554.              fg_setcolor(15);
  555.              fg_move(160,100);
  556.              fg_ellipse(20,20);
  557.  
  558.              /* slide the object across the screen */
  559.  
  560.              hidden = 1;
  561.              setcolor(10);
  562.              for (x = -10; x < 320; x+=4) {
  563.                 fg_setpage(hidden);
  564.                 fg_transfer(0,319,0,199,0,199,2,hidden);
  565.                 fg_clprect(x,x+19,96,105);
  566.                 fg_setvpage(hidden);
  567.                 hidden = 1 - hidden;
  568.                 fg_waitfor(1);
  569.                 }
  570.  
  571.              /* restore the original video mode and return to DOS */
  572.  
  573.              fg_setmode(old_mode);
  574.              fg_reset();
  575.           }
  576.  
  577.      A problem with either page flipping technique arises if we use virtual
  578. video pages.  Page flipping relies on the fact that changing the visual page
  579. number occurs instantly, which is exactly what happens when we use physical
  580. video pages.  However, such is not the case with virtual or logical pages
  581. because Fastgraph must copy the entire page contents into video memory.
  582. 248   Fastgraph User's Guide
  583.  
  584. While this occurs quite rapidly, it is not instantaneous, and its effects are
  585. immediately apparent on the animation.
  586.  
  587.  
  588. An Animation Example:  The Fastgraph Fish Tank
  589.  
  590.      If you installed the example programs when you installed Fastgraph, the
  591. EXAMPLES subdirectory will include a fully-commented program called the fish
  592. tank that illustrates dynamic frame animation.  The fish tank is an excellent
  593. example of multi-object non-destructive animation in which several types of
  594. tropical fish swim back and forth against a coral reef background.  As a
  595. picture is worth 1,024 words, we suggest studying the fish tank source code
  596. for some useful techniques in developing a complete animation program.  The
  597. source code for the fish tank program is in FISHTANK.C, FISHTANK.BAS,
  598. FISHTANK.FOR, or FISHTANK.PAS, depending on what language support you've
  599. installed with Fastgraph.
  600.  
  601.  
  602. Summary of Animation Techniques
  603.  
  604.      This chapter has presented five animation techniques:  simple animation,
  605. XOR animation, static frame animation, dynamic frame animation, and page
  606. flipping.  The following table summarizes their behavior.
  607.  
  608.                technique     destructive?        flicker-free?
  609.  
  610.                simple             yes                 no
  611.                XOR                no                  no
  612.                static frame       no                  yes
  613.                dynamic frame      no                  yes
  614.                page flipping      no                  yes
  615.  
  616. Simple animation and XOR animation are elementary techniques that are seldom
  617. used once you master frame animation and page flipping.
  618.  
  619.      As stated at the beginning of this chapter, the simple examples
  620. presented here serve as the basis for understanding the mechanics of the
  621. animation techniques we have discussed.  In "real world" programs, you'll
  622. typically want to display an image using the fg_drwimage or fg_drawmap family
  623. of routines instead using rudimentary images such as the rectangles in our
  624. examples.  A helpful rule is to use PCX, GIF, or pixel run files for both
  625. backgrounds and moving objects, and then use fg_getimage or fg_getmap to
  626. retrieve the moving objects as bit-mapped images for later display.  Of
  627. course, it's desirable to do this "behind the scenes" work on video pages
  628. other than the visual page.  This is precisely the technique used in the
  629. Fastgraph fish tank.