home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mnth0105.zip / Timur / vol1n5.txt < prev   
Text File  |  1994-03-25  |  9KB  |  214 lines

  1. Paint by Numbers
  2.  
  3. This month, we will make our first attempt at creating a real 
  4. terrain for the combat map.  Each hexagon is a thirty-meter 
  5. wide area of a particular "terrain", such as grasslands, 
  6. water, buildings, and so on.  There is still a lot of work 
  7. left, however.  The terrain is represented by colors and 
  8. patterns instead of bitmaps.  So instead of seeing an icon of 
  9. a building inside a hexagon, you see a shade of pink.  Yes, I 
  10. realize that pink is a dumb color for a building.  Like I 
  11. said, the program needs work, and bitmaps will have to wait 
  12. until I decide how scrolling and scaling will be handled.  
  13.  
  14. Ideally, the map could have any size (even hundreds of 
  15. hexagons per side) that can be scrolled in the four main 
  16. directions and scaled to any size.  The only problem with 
  17. this grandiose idea is the speed at which it runs.  The 
  18. current version has a fixed window without bitmaps, and 
  19. drawing the entire map takes several seconds.  Most of the 
  20. time is spent filling the hexagons, a task handled by 
  21. function HexFillDraw(), shown in Listing 1.  Filling an 
  22. area takes too long, so I need to find a faster method.  Any 
  23. suggestions?
  24.  
  25. The pull-down menus allow you to toggle edit-mode and select 
  26. the terrain type, and a simple mouse click will change a 
  27. hexagon to the new terrain.  Unfortunately, the load and save 
  28. options are not available, so you will have to wait until 
  29. next month before you can share your playing fields with the 
  30. rest of the world.  But since my articles are due about two 
  31. months before they are published, you can cheat a little by 
  32. skipping ahead to the code for the October issue.  When I 
  33. submit an article to "OS/2 Monthly", I also upload the 
  34. accompanying source code to my local BBS.  So the code for 
  35. the October issue is actually available in early August.
  36.  
  37. The overall structure of the program has been slightly 
  38. modified.  For starters, global variables are declared 
  39. differently.  True object-oriented techniques frown upon 
  40. global variables, but sometimes they can result in simpler 
  41. and faster code.  Listing 1 is an excerpt from HEXES.C that 
  42. implements the idea.
  43.  
  44. This technique may or may not be original, but I haven't seen 
  45. it before.  The constant HEXES_C is defined at the top of 
  46. HEXES.C, and is used to alter the declaration of these 
  47. globals depending on whether they are being included inside 
  48. HEXES.C.  The compiler sees the line "HPS hpsHex" when it 
  49. processes HEXES.C, but it sees "extern HPS hpsHex" when it 
  50. compiles any other file.  Therefore, the declaration and 
  51. definition of this variable are in the same place.
  52.  
  53. The other unorthodox change is also related to global 
  54. variables.  The presentation space handles are now created 
  55. once during initialization and kept open until the program 
  56. terminates.  This has three advantages.  First, stack space 
  57. is reduced because these variables are no longer local to the 
  58. window procedure.  Second, speed is increased because the 
  59. handles are only obtained once, and not every time a button 
  60. is pressed.  Third, function calls are simplified since the 
  61. handles are stored in global variables and not passed as 
  62. parameters.
  63.  
  64. I haven't seen this technique used elsewhere either, which 
  65. means it will probably backfire on me six months down the 
  66. road.  There may be a problem with keeping a P.S. handle open 
  67. across successive window procedure calls.  However, it 
  68. appears to work flawlessly, and it does produce more 
  69. efficient code.
  70.  
  71. The targetting routines have been moved from the window 
  72. procedure to their own module.  The primary reason for this 
  73. change was to reduce the size of WinProc().  With the 
  74. addition of pull-down menus, the mouse has gained a second 
  75. function - map editing.  The routines for changing and 
  76. drawing the map are in the same module, but this combination 
  77. may be split in the future, especially since the load and 
  78. save features will be added next month.  These features 
  79. require dialog boxes, which will be the primary focus of the 
  80. September installment.
  81.  
  82. Each hexagon on the map has various attributes associated 
  83. with it.  These attributes are stored in a two-dimensional 
  84. array of structures called amap.  The structure, aptly 
  85. labelled MAP, only stores the terrain type and the height.  
  86. More fields will be added as the mapping system becomes more 
  87. complex.
  88.  
  89. The terrain types are listed in the resource file and cover 
  90. the majority of features one would find on a typical combat 
  91. field.  Of course, there is plenty of room for additions if 
  92. anyone would like to submit their ideas.  Pull-down menus are 
  93. being used because it is the easiest way to incorporate these 
  94. features into the program.  
  95.  
  96. The menu for terrain selection will eventually be replaced by 
  97. something more graphical.  One possibility would be to create 
  98. a second window that shows each of the terrain types as a 
  99. small icon on which you can select.  Clicking with the left 
  100. button will make that terrain the current choice.  Clicking 
  101. with the right button will pop up an information window 
  102. showing the attributes of that terrain, such as how it 
  103. affects visibility and maneuverability.
  104.  
  105. This game deviates from the rule books in its treatment of 
  106. height.  In the original game, hills were simply another type 
  107. of terrain.  I want a little more flexibility than that, 
  108. because there is no reason why woods or buildings cannot be 
  109. located on elevated ground.
  110.  
  111. Representing the change in elevation is tricky.  Using 
  112. different shades or intensities would render the map 
  113. illegible because of the confusing array of colors.  
  114. Surrounding all the hexagons of equal height with a contour 
  115. line requires a very complex and time-consuming algorithm.  
  116. Showing a number inside a hexagon is simple, but it might not 
  117. be distinguishable from any bitmap which would also occupy 
  118. the hex.  As you can see, support for height was not been 
  119. included this month since I have not yet decided on how to 
  120. represent it on the screen.
  121.  
  122. The variable eMode (an enumerated type defined in GAME.C) 
  123. indicates the user's current activity.  This version supports 
  124. only two choices: targetting and editing.  Targetting is the 
  125. initial mode and the code is identical to last month's.  The 
  126. source hexagon cycles more quickly during targetting, but 
  127. nothing else has changed.  The next addition to targetting 
  128. will be a display of the current angle and length of the 
  129. targetting line.  As you move the line, the computer will 
  130. tell you at what bearing and range your target is.  It will 
  131. also calculate the visibility and inform you of the chance of 
  132. hitting the target.
  133.  
  134. In the final version of this game, the map editor will be 
  135. separate from the combat phase.  Changing the playing field 
  136. during a battle is not a priviledge that mere mortals can 
  137. enjoy.  Once a campaign has been created, it cannot be 
  138. changed during play.  However, the editor will remain 
  139. connected to the rest of the game until it is completed.
  140.  
  141. The window procedure has changed the most.  WM_CREATE perfoms 
  142. more initializations, especially since the presentation space 
  143. handles are now global variables.  Variable bDefTerrain is 
  144. used by WM_PAINT to draw the window background quickly.  Any 
  145. hexagons which are the same color as the background are not 
  146. redrawn.  The default is the color for clear ground, which 
  147. will most likely be the majority of the map.
  148.  
  149. The button-down routine (WM_BUTTON1DOWN message) checks the 
  150. current mode, and either activates targetting or changes the 
  151. hexagon's terrain type.  This is the only message that is 
  152. important to both modes.  WM_BUTTON1UP and WM_MOUSEMOVE are 
  153. important only to targetting, so these routines have not 
  154. changed significantly.
  155.  
  156. The WM_COMMAND message processes all the menu selections.  If 
  157. any of the terrain types have been selected, than the 
  158. check-mark for the current terrain is cleared, and the new 
  159. terrain is selected.  When the user clicks on "Edit," the the 
  160. user mode is toggled.
  161.  
  162. That wraps it up for this month.  I hope that obtaining the 
  163. source code has not been a problem, but we are still working 
  164. on opening the distribution channels.  The main focus in the 
  165. September issue will be dialog boxes and lots of other good 
  166. stuff.
  167.  
  168.  
  169. Listing 1: functions HexDraw() and HexFillDraw()
  170. ---------
  171.  
  172. void HexDraw(HPS hps, HEXINDEX hi) {
  173.   POINTL ptlHex[]={ {HEX_SIDE,0},
  174.                     {HEX_SIDE+HEX_EXT,HEX_HEIGHT/2},
  175.                     {HEX_SIDE,HEX_HEIGHT},
  176.                     {0,HEX_HEIGHT},
  177.                     {-HEX_EXT,HEX_HEIGHT/2},
  178.                     {0,0}                         };
  179.   int i=0;
  180.  
  181.   ptlHex[5]=HexCoord(hi);
  182.   GpiMove(hps,&ptlHex[5]);
  183.   for (;i<5;i++) {
  184.     ptlHex[i].x+=ptlHex[5].x;
  185.     ptlHex[i].y+=ptlHex[5].y;
  186.   }
  187.   GpiPolyLine(hps,6L,&ptlHex[0]);
  188. }
  189.  
  190. void HexFillDraw(HEXINDEX hi) {
  191.   GpiSetColor(hpsHex,HexTerrainColor(abMap[hi.c][hi.r].bTerrain));
  192.   GpiSetPattern(hpsHex,HexTerrainPattern(abMap[hi.c][hi.r].bTerrain));
  193.   GpiBeginArea(hpsHex,BA_NOBOUNDARY);
  194.   HexDraw(hpsHex,hi);
  195.   GpiEndArea(hpsHex);
  196.   GpiSetColor(hpsHex,HEX_COLOR);
  197.   HexDraw(hpsHex,hi);
  198. }
  199.  
  200.  
  201. Listing 2: "#define EXTERN extern" trick
  202. ---------
  203.  
  204. #ifdef HEXES_C
  205. #define EXTERN
  206. #else
  207. #define EXTERN extern
  208. #endif
  209.  
  210. EXTERN HPS hpsHex;
  211. EXTERN TARGET target;
  212. EXTERN long lNumColors;
  213. EXTERN MAP amap[NUM_COLUMNS][NUM_ROWS];
  214. #undef EXTERN