home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / pascal / anivga12 / anivga.tut < prev    next >
Text File  |  1993-07-11  |  13KB  |  227 lines

  1.        ░░░░░░▄ ░░░▄ ░░▄ ░░░░░░▄                ░░▄ ░░▄  ░░░░▄  ░░░░░░▄
  2.        ░░█▀░░█ ░░░░▄░░█   ░░█▀▀                ░░█ ░░█ ░░█▀▀▀  ░░█▀░░█
  3.        ░░░░░░█ ░░█░░░░█   ░░█      ░░░░░░▄     ░░█ ░░█ ░░█░░░▄ ░░░░░░█
  4.        ░░█▀░░█ ░░█ ░░░█   ░░█       ▀▀▀▀▀▀      ░█ ░█▀ ░░█ ░░█ ░░█▀░░█
  5.        ░░█ ░░█ ░░█  ░░█ ░░░░░░▄                  ░░█▀   ░░░░█▀ ░░█ ░░█
  6.         ▀▀  ▀▀  ▀▀   ▀▀  ▀▀▀▀▀▀                   ▀▀     ▀▀▀▀   ▀▀  ▀▀
  7.  
  8.  
  9.                           ░░░░░░▄░░▄ ░░▄░░░░░░▄
  10.                             ░░█▀▀░░█ ░░█  ░░█▀▀
  11.                             ░░█  ░░█ ░░█  ░░█
  12.                             ░░█  ░░█ ░░█  ░░█
  13.                        ░░▄  ░░█  ░░░░░░█  ░░█
  14.                         ▀▀   ▀▀   ▀▀▀▀▀▀   ▀▀
  15.  
  16.                             (a short tutorial)
  17.  
  18.  
  19. Okay; now you have installed AniVGA and ran the small demo programs. You got
  20. interested and looked into ANIVGA.DOC. Gee! That huge thing nearly killed
  21. you! But what the heck, you are a programmer and *hate* reading manuals!
  22. So you took a look into ANIVGA.PAS, just to find out how easy it is to become
  23. frustrated by looking at 10000+ lines source code and understanding nothing?
  24. Boy, after all, you were only looking for a simple toolkit to realize your
  25. ultimate-hyper-whopping-super-game, ain't it? Well...
  26.  
  27. So you stumbled across this file --congrats! This text is AniVGA "in a
  28. nutshell". It contains nothing which you wouldn't find in ANIVGA.DOC or the
  29. example programs, too. But it concentrates on telling you the basic concepts
  30. of AniVGA from a different side: namely YOU, the experienced Pascal- but
  31. not-so-experienced AniVGA-programmer!
  32. We won't bother with much details here: look into ANIVGA.DOC for that, we
  33. will concentrate on the basics!!
  34.  
  35. | Therefore, we will work out the principles, leading you to special terms,
  36. | always typed between "-signs. Use these terms as an index into the manual
  37. | ANIVGA.DOC!
  38.  
  39. ___
  40.  
  41.  
  42. Imagine YOU had the chance to specify how a sprite engine for your
  43. applications should work; what concepts would you like?
  44.  
  45. Thinking a bit, your first idea will surely be something simple like:
  46. - sprites
  47. - background images
  48. - an update routine which erases the old sprites and draws the new ones
  49.  
  50. Sprites are your basic graphic objects which you want to move around the
  51. screen to do some fancy things and yes, you want that all actions shall take
  52. place in front of some background image, which you load into the graphic
  53. memory.
  54. Your sprites will be driven by: you tell which sprite should be drawn at
  55. which screen coordinate. You use arrays "SpriteX[]" and "SpriteY[]" to store
  56. the coordinates of your sprites and "SpriteN[]" holds the number of the
  57. sprite to display at this coordinate. You implement a procedure "Animate"
  58. which updates the screen accordingly, erasing the old sprites and drawing the
  59. new ones at their specified coordinates -- All pretty simple, you think, eh?
  60.  
  61. So you start writing your game. But doing so, you find out that your approach
  62. was to simple:
  63. - A sprite (read: an animated graphic object at the screen) most often isn't
  64.   static. Instead, it consists of several frames repeating one after another.
  65.   For example, if you want to animate a burning torch, you should use a few
  66.   images showing the torch with different shapes of the flame and repeat the
  67.   animation through these single stages endlessly. This leads to what AniVGA
  68.   calls a "sprite cycle"
  69. - Your shoot'em-up game attacks the player with 50 aliens at once. Perhaps
  70.   you have 5 different alien types, but even then every 10 aliens have the
  71.   same shape. In the OOP, one would say, these 10 aliens are instances of the
  72.   same object. It's the same thing here: we have the data representing the
  73.   sprite's shape, which only has to be loaded into RAM _once_. This will be
  74.   called a "spriteLOAD number" in AniVGA. This is a handle used to access
  75.   the physical data. And then we have the 10 copies of this data on the
  76.   screen --what you normally would simply call "sprites".
  77.   These individuals are accessed by what AniVGA calls "sprite numbers".
  78.   It works like this: AniVGA loads the alien's data into memory and labels it
  79.   with a spriteLOAD number. You pick up this number and put it into 10 'slots'
  80.   of the "SpriteN[]" table: voilà, you just set up 10 aliens!
  81.  
  82. But then you see that your background assumptions were to simple, too:
  83. - Drawing sprites deletes the background image, thus if you remove the sprite
  84.   from the screen later on, a hole remains at that area. So we need some kind
  85.   of repainting the erased area.
  86.  
  87. Again, you think a bit and come up with a great idea: let's store the
  88. background image somewhere else, too and use that duplicate to repaint the
  89. erased areas! And indeed, AniVGA uses a "BACKGNDPAGE" for this purpose.
  90. Nevertheless, it ain't that simple: doing your animations would now consist
  91. of the following cycle:
  92.  a) draw sprites
  93.     ...
  94.  b) overdraw them with background area
  95.  c) draw sprites at new position
  96. But by doing so, there is a time (namely: between b) and c) ) where there is
  97. no visible image of your sprite on the screen! The human eye perceives this
  98. as 'blinking' or 'flickering' of the animation.
  99. The solution is called "page flipping": one uses (at least) two drawing
  100. pages which are displayed alternately. While you are showing one page, you
  101. are creating the next image on the other, invisible page. When you are done,
  102. you just flip the pages (by reprogramming the hardware), thus displaying the
  103. ready frame and using the formerly shown page as new (invisible) working page
  104. to draw upon.
  105. The flipping is done automatically in AniVGA; it uses two pages (0 & 1) for
  106. this purpose. Normally you don't have to bother which page is currently shown
  107. and which is used for drawing the next frame, but if you DO have, then you
  108. can query the variable "PAGE" for that purpose. It will report the number of
  109. the actually working page. Note that due to the page flipping scheme, this is
  110. *always* the number of the invisible page, i.e.: the visible page is always
  111. 1-PAGE.
  112.  
  113.  
  114. Great! Now you may draw & erase sprites/sprite cycles, have taken care about
  115. the background image and avoided flickering effects. Unfortunately, 320x200
  116. pixels isn't a big area for graphics. Why not using a larger area than this
  117. physical screen area and use the screen only as a window to this 'world'?
  118.  
  119. --Congrats, you just invented "virtual coordinates"!
  120. So you setup a coordinate space (it ranges from -16000..+16000 for both axis
  121. in AniVGA) and want your physical screen display to be a part of this area,
  122. 320x200 pixels in size.
  123. How do you control _which_ 320x200 pixels are displayed?
  124. Well, simply specify the upper left corner of that area: if that is (a,b),
  125. then the screen should display the area (a+0,b+0)..(a+319,b+199); if for
  126. example you increment the x-coordinate (that is: 'a') by 10, then the next
  127. frame should slide the display 10 pixels to the right. AniVGA does exactly
  128. this, calling the upper left corner of your display "StartVirtualX" and
  129. "StartVirtualY".
  130. But during implementation of this scheme, you run into problems: your
  131. virtual screen has size 32000x32000 points, a complete background image
  132. would need 1GB (!) of memory! So what to do now?
  133. There are two methods:
  134. a) Use a 'fixed' background image: whatever area of your virtual coordinate
  135.    space is displayed, always use the same background image, 320x200 pixels
  136.    in size.
  137.    This works, if a monochrome background image suffices or you have an
  138.    image which is perspectively very far away (some mountains in the
  139.    distance, for example)
  140. b) Reduce the amount of background memory needed by cutting down the image
  141.    into "tiles": instead of storing each pixel, you define the picture
  142.    to consist of small areas. Then, each area is assigned a number which
  143.    determines how to paint that area.
  144.  
  145. The former method a) is what is called "static" backgrounds in AniVGA, the
  146. latter method b) is called "scrolling" backgrounds.
  147. Note that in "scrolling" backgrounds, the background image itself doesn't
  148. exist physically! It will be 'puzzled' together by tiles each animation
  149. cycle: there is only a memory area "SCROLLPAGE", which holds the up to 256
  150. tiles (each 16x16 pixels) used to build the image. (Note that you are
  151. restricted to 256 _different_ tiles, but that you may use these to build
  152. up a background image of up to 10000 tiles.)
  153. On the other hand, the "static" background image _does_ exist (as page
  154. "BACKGNDPAGE") and thus may be changed easily.
  155.  
  156.  
  157. Now our sprite engine went to 10000+ lines code and works as it should. But
  158. you come up with a new eager idea: it would be nice if one could have a sort
  159. of *both* "scrolling" and "static" backgrounds in one. That is: you want to
  160. have an animation window on your screen, but the 'rest' of the screen area
  161. should be used statically for displaying text, hiscores, special items, etc.
  162. Starting with V1.2, AniVGA gives you this oppotunity as well: there's a
  163. routine named "SetAnimateWindow()" which restricts animations to the screen
  164. area you name. The area outside this window becomes filled with the *static*
  165. background page contents from page "BACKGNDPAGE". On the other hand, the
  166. animation window area will use "BACKGNDPAGE" or "SCROLLPAGE" as background,
  167. depending on which "background mode" you use: "STATIC" or "SCROLLING",
  168. respectively. (In other words: when not using the "SetAnimateWindow()"-
  169. routine, AniVGA uses an implicit SetAnimateWindow(0,0,319,199) call).
  170.  
  171. However, let's think about the area outside the animation window:
  172. Should it be updated every animation cycle automatically (like the area
  173. _inside_ the window is)? No! In normal applications, this area won't be
  174. updated for a 'long' time, say 30 animation cycles or so. Therefore, AniVGA
  175. doesn't change this area at all --unless you explicitely tell it to do so.
  176. Let's take an example: you want to output a hiscore to that outer area.
  177. How would you do it?
  178. a) use a sprite for that (there's a routine "MakeTextSprite()" which would
  179.    assist you for this method)
  180. b) write the text to the ("static") background page "BACKGNDPAGE"
  181. c) write the text directly to the two display pages
  182.  
  183. Let's postpone a) for a moment; using b) wouldn't be a good idea for two
  184. reasons:
  185. - You wouldn't see the results on the screen. Why? Well, you did the change
  186.   to the background page, lying somewhere in memory. To see it, the updated
  187.   background page must first be copied to the visible display page --but as
  188.   mentioned before, AniVGA won't do so for the outer area. (You would have
  189.   to tell it by setting "UpdateOuterArea:=2". Then the next call to
  190.   "Animate()" will update the outer area, too)
  191. - The second reason is that you 'brand' the text into the background area,
  192.   which most often isn't what you want: the only way to get rid of this text
  193.   is to overwrite the background area concerned somehow. Nasty!
  194.  
  195. Method c) is much better: write the text directly to both pages: as AniVGA
  196. doesn't change the outer screen area, the information will stay there.
  197. If you want to erase it later on, you still have the choice, how:
  198. - just undraw the text, overwrite it, paste over it with a previously
  199.   saved "GetImage()" area, ...
  200. - set "UpdateOuterArea:=2"
  201. The former method is suitable whenever the area which needs mending is small
  202. and/or you know how to easily achieve that. The latter method is the 'sledge-
  203. hammer-method', as it replaces the _complete_ outer area by the contents of
  204. the background page. This is handy, if you did a lot of changes to the area
  205. and/or it would be difficult to undo the changes.
  206.  
  207. What about a), I hear you ask? Hm... perhaps you should first re-think your
  208. question: didn't we set up an animation window to _restrict_ sprites to that
  209. inner area? And now you want to draw sprites _outside_ the animation window?
  210. Gee, strange! ;-)
  211. Indeed, it seems as if we need two groups of sprites: one, which really get
  212. clipped to the animation window and another, which may be drawn everywhere.
  213. In AniVGA, you may divide the sprites into two groups by using the routine
  214. "SetSplitIndex(n)": after that call, all sprites "SpriteN[0]".."SpriteN[n]"
  215. will be 'free' to be drawn everywhere on the screen while all others will
  216. be restricted to the animation window.
  217.  
  218. Similiarly, a second question should come to your mind: how should other
  219. graphic actions behave in the area outside the animation window?
  220. For example, should a line which runs diagonally through your animation
  221. window be drawn completely or should the parts which lie outside the window
  222. be clipped off? Both ways of acting make sense!
  223. Therefore you can control the way AniVGA treats its pixeldrawing routines
  224. by using the boolean variable "WinClip": if it's set to FALSE (the default
  225. value), then pixels outside the animation window won't be clipped; if
  226. WinClip=TRUE, they will be clipped.
  227.