home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 17 / CD_ASCQ_17_101194.iso / vrac / qbmapex2.zip / MAPPING.BAS < prev    next >
BASIC Source File  |  1994-07-04  |  62KB  |  1,245 lines

  1. '*****************************************************************************
  2. '*MAPPING.BAS -- Example of mapping an area for a game by Professor X-Man    *
  3. '*(Eric Blanding) of ProXman Software, the gaming division of NubianWare     *
  4. '*Productions.  This code is STRICTLY Public Domain, and you may do anything *
  5. '*you wish with it.  I only ask that you please make no modifications without*
  6. '*prior consent from me (areas where i can be reached are in the DOC).  Also,*
  7. '*I ask that if you wish to distribute the ZIp file you obtained, distribute *
  8. '*it in it's ORIGINAL form!  Other than that, have fun!                      *
  9. '*****************************************************************************
  10. '                        DECLARES FOR SUBS/FUNCTIONS
  11. '=============================================================================
  12. DECLARE SUB ClearPort (MapArray%())
  13. DECLARE SUB DropInvItem (InventArray%(), MapArray%(), X%, Y%, Item2Drop$)
  14. DECLARE SUB GetItem (MapArray%(), InventArray%(), XLoc%, YLoc%)
  15. DECLARE SUB LoadBarrierData (BarrierArray%())
  16. DECLARE SUB MovePlayer (MapArray%(), BoundArray%(), KeyPressed%, CurrentXLoc%, CurrentYLoc%, item%)
  17. DECLARE SUB SetGameFlags (FlagArray%())
  18. DECLARE SUB ShowInv (InventArray%())
  19. DECLARE SUB ShowMove (MapArray%(), KeyPress%, X%, Y%)
  20. DECLARE FUNCTION InKeyCode% ()
  21. DECLARE FUNCTION Object% (MapArray%(), X%, Y%)
  22. DECLARE FUNCTION PlayerStart% (MapArray%(), PlayerChar%, CurXLoc%, CurYLoc%)
  23. DECLARE FUNCTION CheckFlags% (FlagArray%())
  24. DECLARE FUNCTION InvCheck% (InventoryArray%())
  25.  
  26. '***************************************************************************
  27. '                         SET PROGRAM DEFAULTS
  28. '===========================================================================
  29. DEFINT A-Z        '<--Makes sure that any variable not explictly ending with a
  30.                   '   % in the program, gets treated like an integer anyway.
  31.  
  32. OPTION BASE 1     '<--Makes sure that when an array is declared, it won't
  33.                   '   automatically use 0 as it's lowest subscript.
  34.                   '   Instead, it'll start with 1. This is so we don't have
  35.                   '   to have DIM Mine(1 TO 20) instead of using DIM Mine(20).
  36.  
  37. '***************************************************************************
  38. '                 ARRAY DEFINITIONS AND DESCRIPTIONS                  
  39. '===========================================================================
  40. REDIM HouseMap(10, 10) AS INTEGER      '<---This array holds our MAP
  41.  
  42. REDIM inventory(5) AS INTEGER   '<-----This array tracks the inventory status
  43. REDIM BarDat(2) AS INTEGER      '<-----This array holds data which can define
  44.                                 '      optional barricades in your game,
  45.                                 '      besides the four standard walls of our
  46.                                 '      sample "map."
  47. REDIM GameFlags(6) AS INTEGER   '<-----This array holds all our BOOLEAN flags
  48.                                 '      which is used to detect whether or not
  49.                                 '      the user has completed all the needed
  50.                                 '      tasks before the game will allow you
  51.                                 '      to continue and finish the game.
  52.  
  53. '****************************************************************************
  54. '                     READING THE MAP INTO THE ARRAY
  55. '============================================================================
  56. '  This FOR..NEXT loop will READ the map (below this loop) into the array
  57. 'named HouseMap%().  First of all, ya'll probably wondering why the heck I'm
  58. 'storing the image of a map as a bunch of INTEGERS, instead of STRING
  59. 'characters.  Sure. I could have done that, and it would have worked fine.
  60. 'But I'm wary of running out of string space whether I'm in the IDE or running
  61. 'a compiled program. Plus, I've found out that INTEGER operations run a lot
  62. 'faster than STRING operations.
  63. '
  64. '  Enuff of that, right now, you wanna know what I'm doing.  What's going on
  65. 'is that... Wait a sec. Is that FOR loop backwards? Should it be:
  66. '                   FOR X% = 1 to 10
  67. '                     FOR Y% = 1 to 10
  68. 'and not the other way around?  That's correct my friend. In other situations,
  69. 'this X before Y syntax would probably be easier for you to understand how
  70. 'that particular program manipulated it's arrays.  But since we're dealing
  71. 'with PLOTTING, we need to move our linear way of thinking into something more
  72. 'abstract.  To make this simpler to understand, I set this up so that it
  73. 'works like the graphics functions in QBasic/QuickBASIC/PDS/VBDOS, which
  74. 'all work as Y%, X% not X%, Y% (For those who already know about this, ya'll
  75. 'can move on to "THE INNER WERKINGS").
  76. '
  77. '
  78. '            BRIEF STUFF ON BASIC'S GRAPHIC COORDINATE SYSTEM
  79. '            ------------------------------------------------
  80. '
  81. '   We all know when in SCREEN 0 (or any other mode%) and using the infamous
  82. 'LOCATE X%, Y% statement, we automatically assume that:
  83. '
  84. '                       X% = a row; Y% = a column
  85. 'Illustrated like so:
  86. '
  87. 'X% = 5, Y% = 9
  88. '123456789 <--Nine columns of "-" (so Y% = 9)
  89. '--------- ]
  90. '--------- │
  91. '--------- <──Five rows of "---------" (so X% = 5)
  92. '--------- │
  93. '--------- ]
  94. '
  95. '   Now, when dealing with GRAPHICs, it's reversed; It's now Y%, X%, not
  96. 'X%, Y% (you'll find out in a moment). You must no longer think in
  97. 'Rows and Columns (if you do, you'll easily get confused!).  Instead, you
  98. 'must think like yer in a math class, studying graphs; the X-Axis and the
  99. 'Y-Axis.  Looky here.  Remember this?:
  100. '
  101. '                                 
  102. '                              3  │Y          <--Y, in the graphics sense,
  103. '                              2  │              would now be your "ROWS" (3
  104. '                              1  │              are shown here).
  105. '                                 ┼─────────
  106. '                                  1234567  X <--X, in the graphix sense,
  107. '                                                would now be your "COLUMNS"
  108. '                                                (7 are shown here).
  109. '
  110. '         Can't you see?  Before, X and Y were Rows and Columns respectively.
  111. 'Now (if you STILL wanna think like ROWS and COLS), it's Y and X.  If yer
  112. 'still stumped, just consult the section on GRAPHICS in your BASIC manual.
  113. 'In any case, the MAP system used here uses the above format for plotting
  114. 'the player's movements and such.  After all, all we're doing in this program
  115. 'is plotting a point on a graph. That's it. Nothing fancy, just good old
  116. 'fashioned graphing.  Besides, I think it's easier to understand this way.
  117. '(That and also the fact I had a heck of a time trying to get the !@#!ing
  118. 'program to work with loading the MAP with FOR X% = 1 to n:FOR Y% = 1 to n not
  119. 'the other way around!) ENUFF OF THIS GRAPHING CRAP! (Hope I didn't lose
  120. 'ya there...)
  121. '
  122. '
  123. '                             THE INNER WERKINGS
  124. '                             ------------------
  125. '
  126. '   This is what you've been waiting for; what the heck is going on in this
  127. 'dang loop.  What it's doing is:
  128. '
  129. '   1) Reading in a character from the DATA table
  130. '   2) If it runs across a NUL (the empty spaces in the DATA table), then
  131. '      assign a space (" ") in it's place, since I can't assign a NUL in
  132. '      the array.
  133. '   3) If we've reached the last... er.. COLUMN (X% value) in the DATA table,
  134. '      then only grab that one character, before it hits the single
  135. '      quotes ('). This is because DATA treats whatever is after that last
  136. '      comma as one big piece of data (this includes REMs (')!). If that
  137. '      LEFT$(S$,1) crap wasn't there, the comments to the right would
  138. '      be grabbed in the array as well (If you wanna see it, comment out
  139. '      the line with IF X% = UBOUND()... and put a watch on HouseMap(X%,Y%)).
  140. '
  141. '   4) We take the ASCII code of the character and put it into the array.
  142. '      In memory, we have the EXACT copy of the map as shown, but instead
  143. '      of the actual characters, we have a bunch of ASCII codes in it's place.
  144. '      Cool eh?  ;)
  145. '
  146. '============================================================================
  147. '                   ***!!!WARNING ABOUT DATA STATEMENTS!!!***
  148. '                         -----------------------------
  149. '
  150. '   DATA statements are good for testing out simple theories such as this
  151. 'program example, but it's REALLY NOT a good idea to use em in compiled
  152. 'programs. Not only do they take up valuable DGROUP space, but they are
  153. 'visible in your EXE when looked at thru a "file browser" (HEX editor).
  154. 'And if u like to use ASCII characters lower than 3 ("" = 1, "" = 2),
  155. 'yer gonna have a problem.  When I first compiled this DEMO (with the DATAs)
  156. 'I used "" as the player character instead of "#", and "" as the other
  157. ''PEOPLE' represented insted of "" and "".  For some reason, the EXE can't
  158. 'read those ASC 2 and 1 characters from DATA statements.  At any rate, I
  159. 'advise you all to NOT use the approach presented here.  Instead, load the
  160. 'map stuff in from a file.  I'll leave THAT part up to you.
  161. '============================================================================
  162. '
  163. FOR Y% = LBOUND(HouseMap, 2) TO UBOUND(HouseMap, 2)
  164.   FOR X% = LBOUND(HouseMap) TO UBOUND(HouseMap)
  165.      READ DataStuff$                          'Read in char from position X%
  166.                                               'in DATA statement.
  167.  
  168.      IF DataStuff$ = "" THEN DataStuff$ = " " 'If it runs across a NUL, then
  169.                                               'assign a SPACE to the variable.
  170.  
  171.      'If we hit the last position in the DATA statement line, only take the
  172.      'first character it comes to, and drop the rest ("The rest," in this
  173.      'case, being the comments (').
  174.      '
  175.      IF X% = UBOUND(HouseMap) THEN DataStuff$ = LEFT$(DataStuff$, 1)
  176.  
  177.        HouseMap(X%, Y%) = ASC(DataStuff$)  'Get the ASCII Val of the char
  178.                                            'and put it's INTEGER notation
  179.                                            'into the HouseMap array.
  180.   NEXT X%
  181. NEXT Y%
  182.  
  183. 'This is the map that we're reading into the array.
  184. '
  185. '    <----Xaxis/Col---->
  186. '    1 2 3 4 5 6 7 8 9 10
  187. DATA ┌,─,─,─,─,─,─,─,─,┐ '1  /\
  188. DATA │, , , , ,│, , ,≡,│ '2   |   
  189. DATA │, ,, , ,│, , , ,│ '3   |  
  190. DATA │, , , , ,│, , , ,│ '4   |     
  191. DATA │, , ,, ,\, ,*, ,│ '5   Yaxis/Row
  192. DATA │,─,─,─,─,│,─,\,─,│ '6   |     ┌──────────┤MAP KEY SYMBOLS├───────────┐
  193. DATA │, , , , ,│, , ,!,│ '7   |     │ = a guy        \ = door   = a girl │
  194. DATA │,$, , , ,\, ,+, ,│ '8   |     │≡ = staircase    * = ring             │
  195. DATA │, , ,$, ,│, ,#, ,│ '9   |     │! = timber boot  + = sword            │
  196. DATA └,─,─,─,─,─,─,─,─,┘ '10 \/     │$ = money bag    # = YOU! (The Player)│
  197.                          '          └──────────────────────────────────────┘
  198.  
  199. '****************************************************************************
  200. '                          CONSTANT DEFINTIONS
  201. '============================================================================
  202. 'This CONSTants are used only within this portion of the program.  They have
  203. 'nothing to do with the SUBS.  However, they DO work within other SUB/FUNCS
  204. 'etc, but I prefer to have everything self-contained within a SUB.  For
  205. 'example, you'll see plenty of these same CONSTs in other SUBs and have the
  206. 'comment "Local use only" by it, to indicate that the SUB's CONSTs will only
  207. 'be used locally within it's own procedure.  This is my attempt to try to
  208. 'make the procedures self-regulating; not being dependant on what's been
  209. 'declared in the main module (this portion of the program which does NOT
  210. 'have a SUB/FUNCTION header on it).  Altho, you could make an include file
  211. 'and throw all those CONSTs in em, but for clarity, I threw all the CONSTs,
  212. 'DECLAREs, and variable definitions in the main.
  213. '
  214. '--------------------------GENERAL DEFINITIONS-----------------------------
  215. CONST TRUE = -1, FALSE = NOT TRUE   '<--BOOLEANs. Self explanitory.
  216. CONST NOTEMPTY = -1, FULL = -2      '<--These are to detect the state of the
  217.                                     '   player's inventory: Is it FULL, or
  218.                                     '   NOTEMPTY?
  219. CONST BLANK = 32                    '<--Defined as a space (" ").  This is
  220.                                     '   used to denote an empty floor in the
  221.                                     '   map (go back and look at those BLANK
  222.                                     '   spots!).
  223.  
  224. '-----------------KEYBOARD COMMAND DEFINITIONS-----------------------------
  225. 'These CONSTs are just ASCII keycode values for the given keys: UP, DOWN,
  226. 'LEFT, RIGHT, and the letters (lower case values, NOT upper case!): G, D, U,
  227. 'T and S.  The FUNCTION InkeyCode% will automatically sense these values from
  228. 'the keyboard.
  229. CONST UP = 18432, DOWN = 20480, LEFT = 19200, RIGHT = 19712
  230. CONST G = 103, D = 100, U = 117, T = 116, S = 115
  231.  
  232. '------------------ASCII CODES OF INVENTORY ITEMS USED IN GAME-------------
  233. CONST BOOT = 33      '<--An item in the game, denoted by a "!" on the map.
  234. CONST STAIRS = 240   '<--The goal in the game, denoted by a "≡" on the map.
  235. CONST MONEY = 36     '<--An item in the game, denoted by a "$" on the map.
  236. CONST PERSON1 = 6    '<--A guy in the game, denoted by a "" on the map.
  237. CONST PERSON2 = 3    '<--A girl in the game, denoted by a "" on the map.
  238. CONST DOOR = 92      '<--An object in the game, denoted by a "\" on the map.
  239. CONST SWORD = 43     '<--An item in the game, denoted by a "+" on the map.
  240. CONST RING = 42      '<--An item in the game, denoted by a "*" on the map.
  241. CONST PLAYERDEF = 35 '<--The player's character, denoted by a "#" on the map.
  242.                      '   In other programs that you may create, this can be
  243.                      '   ANY character you want.  It's DEFINED as ASCII code
  244.                      '   35, hence the name PLAYERDEF.  Change as u see fit.
  245.  
  246. '***************************************************************************
  247. '                          INVENTORY ITEM NAMES
  248. '===========================================================================
  249. 'As the title above implies.  Just names of the items in the inventory.
  250. '
  251. Boots$ = "Timberland Boots"     'These variaibles are used
  252. StairCase$ = "Staircase"        'for descriptive purposes during
  253. MoneyBag$ = "Money Bag"         'game play.  We'll see how these come
  254. P1$ = "Michael Jordan"          'into play later.
  255. P2$ = "Halle Berry"
  256. ADoor$ = "Door"
  257. ASword$ = "Sword"
  258. ARing$ = "Ring"
  259.  
  260. '****************************************************************************
  261. '                              INITIALIZATION
  262. '============================================================================
  263. 'The following procedures set the game flag status and load programmer
  264. 'definiable barrier data.
  265. '
  266. CALL SetGameFlags(GameFlags())  'Set all flags to FALSE
  267. CALL LoadBarrierData(BarDat())  'Setup the barrier data table
  268.  
  269. '****************************************************************************
  270. '                          USER INTERFACE SETUP
  271. '============================================================================
  272. 'This part just sets up the statusbar and prints the inventory box.
  273. '
  274. CLS                                                    'Take a LONG guess! ;)
  275. StatusBar$ = "(G)et  (D)rop  (U)se  (T)alk  (H)elp  (S)how Map           │ Direction: "
  276. COLOR 15: LOCATE 18, 1: PRINT STRING$(80, 196);        'Print screen divider
  277.  
  278. LOCATE 1, 50: PRINT "┌────────┤Inventory├────────┐"    'Print the inventory
  279.               FOR Row% = 2 TO 6                        'container for names
  280. LOCATE Row%, 50: PRINT "│                           │" 'and stuff.
  281.               NEXT Row%
  282. LOCATE 7, 50: PRINT "└───────────────────────────┘"
  283.  
  284. LOCATE 17, 1: COLOR 12: PRINT "Press (ESC) to end this demo!" 'Exit message
  285. COLOR 0, 2: LOCATE 25, 1: PRINT STRING$(80, 32);  'Print blank status bar
  286. LOCATE 25, 1: PRINT StatusBar$;                   'Prints User Menu
  287.  
  288. '----------------------PRINT PLAYER'S OBJECTIVE-------------------------
  289. '
  290. VIEW PRINT 19 TO 25   'Reset text viewport
  291. COLOR 12, 0           'RED on BLACK background
  292. PRINT "You are on the bottom floor of a smelly old, nasty, slimy, funky old house!"
  293. PRINT "Your goal: To get all the items, talk to the two people who are in the"
  294. PRINT "house, and run upstairs! Hope ya make it! >:)"
  295. COLOR 28, 0: PRINT "                            Hit A Key to begin!"
  296. DO: LOOP WHILE INKEY$ = ""  'Wait until keypress
  297. CLS 2                       'Clear the current viewport
  298. VIEW PRINT 1 TO 25          'reset to default viewport
  299. COLOR 0, 2: LOCATE 25, 1: PRINT STRING$(80, 32);  'Print blank status bar
  300. LOCATE 25, 1: PRINT StatusBar$;                   'Prints User Menu
  301.  
  302. '**************************************************************************
  303. '                        PLAYER'S POSITION CHECK
  304. '==========================================================================
  305.  
  306. Found% = PlayerStart(HouseMap(), PLAYERDEF, X%, Y%) 'Find out where the
  307.                                                     'user starts in the
  308.                                                     'array. In this case,
  309.                                                     'it's (8,9) (Refer to
  310.                                                     'the DATA statements
  311.                                                     'for details).
  312.  
  313.  
  314. IF Found% THEN  'If the player's position has been found, continue with
  315.                 'program execution.
  316.  
  317. '**************************************************************************
  318. '                          MAIN PROGRAM LOOP
  319. '==========================================================================
  320. DO
  321.   COLOR 15, 0
  322.   LOCATE 24, 62: PRINT "X=" + LTRIM$(STR$(X%)) + " "; 'Print the current pos
  323.                  PRINT "Y=" + LTRIM$(STR$(Y%)) + " "; 'of the player's char
  324.                  PRINT "ITEM=" + LTRIM$((STR$(item%))) + "  "; 'in the array.
  325.  
  326.   'IF the user sets the SHOWMAP flag to TRUE, THEN display the array's
  327.   'contents (the map) on screen.
  328.   '
  329.   IF SHOWMAP = TRUE THEN CALL ShowMove(HouseMap(), KeyPress%, X%, Y%)
  330.   IF SHOWMAP = FALSE THEN CALL ClearPort(HouseMap())  'Clears map display
  331.                                                       'area.
  332.  
  333. KeyPress% = InKeyCode%      'Get ASCII keycode value from user's keypress
  334.  
  335. '--------------------------PLAYER'S DIRECTION-------------------------------
  336.   SELECT CASE KeyPress% '(*KeyPress*)
  337.    CASE UP                                             'They choose UP?
  338.     COLOR 15, 0: LOCATE 19, 1: PRINT STRING$(220, 32); 'Clear dialogue area
  339.     COLOR 15, 2: LOCATE 25, 73: PRINT "NORTH";         'Show current direction
  340.     'Update the player's move. If the user is over something of value, the
  341.     'parameter Item% will return a value (ZERO otherwise).  Item% will be
  342.     'used thruout the rest of this program to detect what kind of ITEM it
  343.     'may be (Item% is the ASCII code value of a character in the HouseMap()
  344.     'array).
  345.     '
  346.     CALL MovePlayer(HouseMap(), BarDat(), KeyPress%, X%, Y%, item%)
  347.  
  348.    CASE DOWN  'The same comments for CASE UP apply for the rest of the CASES.
  349.     COLOR 15, 0: LOCATE 19, 1: PRINT STRING$(220, 32);
  350.     COLOR 15, 2: LOCATE 25, 73: PRINT "SOUTH";
  351.     CALL MovePlayer(HouseMap(), BarDat(), KeyPress%, X%, Y%, item%)
  352.             
  353.    CASE LEFT
  354.     COLOR 15, 0: LOCATE 19, 1: PRINT STRING$(220, 32);
  355.     COLOR 15, 2: LOCATE 25, 73: PRINT "WEST ";
  356.     CALL MovePlayer(HouseMap(), BarDat(), KeyPress%, X%, Y%, item%)
  357.  
  358.    CASE RIGHT
  359.     COLOR 15, 0: LOCATE 19, 1: PRINT STRING$(220, 32);
  360.     COLOR 15, 2: LOCATE 25, 73: PRINT "EAST ";
  361.     CALL MovePlayer(HouseMap(), BarDat(), KeyPress%, X%, Y%, item%)
  362.  
  363. '-----------------------PLAYER'S MENU CHOICES----------------------------------
  364.    CASE G              'When the user presses lower case 'G' (GET)...
  365.     SELECT CASE item%    'Detect what Item was picked up.
  366.      CASE SWORD:           'If it's a SWORD (ASC 43)...
  367.        LOCATE 20, 1: PRINT STRING$(160, 32);         'Erase dialog area
  368.        LOCATE 20, 1: PRINT "Yes! You now have: ";    'Tell user what they
  369.        COLOR 10: PRINT "The Sword!"                  'picked up.
  370.        CALL GetItem(HouseMap(), inventory(), X%, Y%) 'Update the inventory
  371.        GameFlags(1) = TRUE                           'Set one of the FALSEs
  372.                                                      'in the GameFalg array
  373.                                                      'to TRUE, cause we did
  374.                                                      'something that was
  375.                                                      'required to be able to
  376.                                                      'win.
  377.      CASE RING:            'If it's a RING (ASC 42)...
  378.        LOCATE 20, 1: PRINT STRING$(160, 32);         'Same comments as CASE
  379.        LOCATE 20, 1: PRINT "Yes! You now have: ";    'SWORD.
  380.        COLOR 10: PRINT "The Invisibility ring!"
  381.        CALL GetItem(HouseMap(), inventory(), X%, Y%)
  382.        GameFlags(2) = TRUE
  383.  
  384.      CASE BOOT:            'If the user picked up a BOOT (ASC 33)...
  385.        LOCATE 20, 1: PRINT STRING$(160, 32);         'Same comments as CASE
  386.        LOCATE 20, 1: PRINT "Yes! You now have: ";    'SWORD.
  387.        COLOR 10: PRINT "A PHAT pair of Timberland Boots!"
  388.        CALL GetItem(HouseMap(), inventory(), X%, Y%)
  389.        GameFlags(3) = TRUE
  390.  
  391.      CASE MONEY:           'If the user picked up some MONEY (ASC 36)...
  392.        LOCATE 20, 1: PRINT STRING$(160, 32);         'Same comments as CASE
  393.        LOCATE 20, 1: PRINT "Yes! You now have: ";    'SWORD.
  394.        COLOR 10: PRINT "A Bag fulla ca$h!"
  395.        CALL GetItem(HouseMap(), inventory(), X%, Y%)
  396.        GameFlags(4) = TRUE
  397.     END SELECT
  398.     CALL ShowInv(inventory())  'Show the new inventory on the screen
  399.  
  400.    CASE D     'When the user presses lower case 'D' (DROP)...
  401.      'IF the inventory is NOT EMPTY or IF the inventory is FULL THEN
  402.      'tell the user what number of the item they wish to drop from the
  403.      'inventory.
  404.      '
  405.      IF InvCheck%(inventory()) = NOTEMPTY OR InvCheck%(inventory()) = FULL THEN
  406.       LOCATE 19, 1: PRINT "Choose the number of the item you want to drop from the inventory!"; : COLOR 12
  407.       DO
  408.        Item2Drop$ = INPUT$(1)   'Get the number of the item
  409.  
  410.        'Drop the item from the inventory.
  411.        CALL DropInvItem(inventory(), HouseMap(), X%, Y%, Item2Drop$)
  412.       LOOP UNTIL Item2Drop$ <> ""
  413.      END IF
  414.  
  415.    CASE T     'When the user presses lower case 'T' (TALK)...
  416.     SELECT CASE item%   'Check what person they are on.
  417.      CASE PERSON1:         'If PERSON1 (ASC 6)...
  418.        LOCATE 19, 1: PRINT STRING$(79, 32);   'Clear Dialog and print
  419.                                               'message.
  420.        PRINT "Micheal Jordan says that you should eat more wheaties. ";
  421.        PRINT "You can find an ecomony sized box upstairs."
  422.        GameFlags(5) = TRUE                    'Update GameFlag array.
  423.  
  424.      CASE PERSON2:        'If PERSON2 (ASC 3)....
  425.        LOCATE 19, 1: PRINT STRING$(79, 32);    'Clear dialog and print
  426.                                                'message
  427.        PRINT "Halle Berry says that you couldn't 'Hit it' if you had a bat.";
  428.        GameFlags(6) = TRUE                     'Update GameFlag Array.
  429.     END SELECT
  430.       
  431.    CASE S     'When the user presses lower case 'S' (SHOW MAP)...
  432.     SELECT CASE SHOWMAP              'BOOLEAN variable "SHOWMAP"
  433.      CASE TRUE: SHOWMAP = NOT TRUE   'IF SHOWMAP = TURE then show the map!
  434.      CASE FALSE: SHOWMAP = NOT FALSE 'If it's FALSE then DON'T show it!
  435.     END SELECT
  436.  
  437.    CASE U     'When the user presses lower case 'U' (USE)...
  438.     SELECT CASE item%  'Check what item they're over.
  439.      CASE STAIRS                       'IF they are over the STAIRS (ASC 240)...
  440.       IF CheckFlags(GameFlags()) THEN  'AND all the GameFlags return TRUE
  441.                                        'Show the winning message and end.
  442.        COLOR 26: LOCATE 20, 1: PRINT "YES! YOU'VE WON! YOU GOT UP THE STAIRS!"
  443.        COLOR 15: PRINT "This conlcudes the map example. Hidey-ho!": END
  444.       ELSE                             'IF CheckFlags() returns a FALSE
  445.                                        'Tell user they haven't finished all
  446.                                        'that was required yet.
  447.        LOCATE 20, 1: COLOR 12: PRINT "You haven't done all that's required yet!"
  448.       END IF
  449.      CASE ELSE:   'If user is over anything else...
  450.        LOCATE 20, 1: PRINT STRING$(220, 32); 'Clear dialgue area and tell
  451.                                              'user that they can't use
  452.                                              'anything else cause this is
  453.                                              'just a sample game.
  454.        LOCATE 20, 1: COLOR 2: PRINT "Use What? This is just a sample game. There's no functionality!"
  455.     END SELECT
  456.   END SELECT  '(*KeyPress*)
  457.  
  458. '------------------------ITEM DESCRIPTIONS------------------------------------
  459. 'This routine tells you what item you are on by looking at the current state
  460. 'of the Item% Parameter in the CALL MovePlayer() SUB.
  461. '
  462.   SELECT CASE item%
  463.     CASE SWORD   'If ITEM% value is (=) to the CONST SWORD value...
  464.          COLOR 15, 0: LOCATE 19, 1                 'Tell user they are in
  465.          PRINT "You see a sword in front of you."; 'front of a sword.
  466.  
  467.     CASE BOOT    'If ITEM% value is (=) to the CONST BOOT value...
  468.          COLOR 15, 0: LOCATE 19, 1                 'Tell user there are boots
  469.                                                    'in front of them.
  470.          PRINT "There are a pair of Timberland Boots here!"
  471.  
  472.     CASE RING    'Same concept as above applies to the rest of this routine.
  473.          COLOR 15, 0: LOCATE 19, 1
  474.          PRINT "There's a PHAT ring here!"
  475.  
  476.     CASE DOOR
  477.          COLOR 15, 0: LOCATE 19, 1
  478.          PRINT "You are at a door."
  479.  
  480.     CASE MONEY
  481.          COLOR 15, 0: LOCATE 19, 1
  482.          PRINT "There's a huge bag o' cash!"
  483.  
  484.     CASE PERSON2
  485.          COLOR 15, 0: LOCATE 19, 1
  486.          PRINT "You just ran into " + P2$; "! I wouldn't hurt her if I was you!"
  487.  
  488.     CASE PERSON1
  489.          COLOR 15, 0: LOCATE 19, 1
  490.          PRINT "You just ran into " + P1$ + "!!"
  491.  
  492.     CASE STAIRS
  493.          COLOR 14, 0: LOCATE 19, 1
  494.          PRINT "You're at the stairs!"
  495.  
  496.     CASE 0: COLOR 15, 0: LOCATE 19, 1: PRINT STRING$(79, 32);
  497.             'If ITEM% returns a ZERO value, then just clear the dialog area
  498.             '(Print blank lines).
  499.  
  500.   END SELECT
  501.  
  502. '****************************************************************************
  503.  
  504. LOOP UNTIL KeyPress% = 27  '<---ESC key
  505. 'This concludes the main program loop. So you see, even a simple little
  506. 'text game can be a bit involved.
  507.  
  508.  
  509. ELSE  'If the Player's Character canNOT be found in the HouseMap() array
  510.       'THEN tell the user that something is wrong, and end the program.
  511.   CLS
  512.   PRINT "The Player's position in the map array has NOT been found. Please see"
  513.   PRINT "what the heck is goin on here. Okay? Thanks a bunch! -Computer Ghost"
  514.   END
  515. END IF
  516.  
  517.                               '(*THE END*)
  518.  
  519. DEFSNG A-Z
  520. FUNCTION CheckFlags% (FlagArray%())
  521. 'This sub routine Checks to see if any BOOLEANS in the FlagArray% are FALSE.
  522. 'If any ARE FALSE, then it sets the function's value to FALSE, indicating that
  523. 'the user has not completed all the goals required of the the game/program.
  524. 'However, if the array contains all TRUEs, then the function's
  525. 'value is set to TRUE, and the game/program can trigger the ending sequence
  526. 'or whatever you decide to do.
  527. '
  528. 'Parameters:
  529. '-----------
  530. '
  531. 'FlagArray%() -- The array containing nothing but boolean values which
  532. '                indicated whether a user has completed a certain goal or
  533. '                passed certain reqiurements.
  534. '
  535. '***********************************************************************
  536. CONST TRUE = -1, FALSE = NOT TRUE   'Local to this function ONLY
  537.  
  538. 'This FOR..NEXT loop goes from the lowest subscript of the FlagArray%()
  539. 'to the highest subscript of the FlagArray%(), checking to see if just
  540. 'ONE is false.  If one IS false, the loop will stop.
  541. '
  542. FOR X% = LBOUND(FlagArray%) TO UBOUND(FlagArray%)
  543.     IF FlagArray%(X%) = FALSE THEN        'If we find a FALSE in there...
  544.         CheckFlags = FALSE                'Return the value FALSE (0)
  545.         EXIT FUNCTION                     'and exit this sucker!
  546.     ELSE                                  'However...
  547.         CheckFlags = TRUE                 'If no FALSEs were found, return
  548.     END IF                                'the value TRUE (-1).
  549. NEXT X%
  550.  
  551.  
  552.  
  553. END FUNCTION
  554.  
  555. SUB ClearPort (MapArray%())
  556. 'This SUB clears the area where the map is displayed.  This SUB is NOT
  557. 'essential for all programs, and is used just for this example program.
  558. 'Don't try to tailor this to your needs, as it'll be useless. But I'll tell
  559. 'you what it does anyway.
  560.  
  561. 'This loop prints nothing but blank spaces in place of the map dimensions on
  562. 'the screen.  It has no effect on the array itself.
  563. '
  564. FOR X% = LBOUND(MapArray%) TO UBOUND(MapArray%)
  565.   FOR Y% = LBOUND(MapArray%, 2) TO UBOUND(MapArray%, 2)
  566.        LOCATE Y%, X%: PRINT CHR$(32);
  567.        LOCATE Y%, X%: PRINT CHR$(32);
  568.   NEXT
  569. NEXT
  570.  
  571. END SUB
  572.  
  573. SUB DropInvItem (InventArray%(), MapArray%(), X%, Y%, Item2Drop$)
  574. 'This SUB removes an inventory item from the inventory array, removes it's
  575. 'name from the inventory list, and redisplays the dropped item on the screen
  576. 'where the user is currently located.  Altho this is no a generic SUB, I
  577. 'will tell you what's goin on anyway; maybe you can tailor this to your needs.
  578. '
  579. 'Parameters:
  580. '-----------
  581. '
  582. 'InventArray%() -- The Inventory Array that's going to be changed.
  583. '
  584. 'MapArray%()    -- You should know what this is by now...
  585. '
  586. 'X%, Y%         -- Where you are in the MapArray%()
  587. '
  588. 'Item2Drop$     -- The available inventory choices you can make. This
  589. '                  also corresponds to the number of available subscripts
  590. '                  in your InventArray%() array (In this case, five (5)).
  591. '                  To make this more generic, what you can do is count how
  592. '                  many subscripts are in the InventArray%(), and save it in
  593. '                  a string variable, which can then replace the "12345" you
  594. '                  see below. It was not done here cause this code will be
  595. '                  changed later on.
  596. '***********************************************************************
  597.  
  598.  
  599. IF INSTR("12345", Item2Drop$) THEN              'If the user chose 1234 or 5...
  600.  MapArray%(X%, Y%) = InventArray%(VAL(Item2Drop$)) 'Transfer the ASCII Val
  601.                                                    'of the item in the
  602.                                                    'InventArray%() back
  603.                                                    'into the MapArray%()
  604.                                                    'at YOUR current location.
  605.                                                    'When the screen gets
  606.                                                    'updated again, the item
  607.                                                    'will be displayed at the
  608.                                                    'point where you last
  609.                                                    'stood.
  610.  
  611.  
  612.  InventArray%(VAL(Item2Drop$)) = 0    'Reset that point in the InventArray%()
  613.                                       'with a value of ZERO (0) to indicate
  614.                                       'that nothing is there. Example:
  615.                                       'User wants to get rid of a knife that's
  616.                                       'located in InventArray%(2).  The ASCII
  617.                                       'code for the kinife is 196.  This value
  618.                                       'is replaced by a 0.  0, in the case of
  619.                                       'this program example, means that the
  620.                                       'user has an empty slot in their invent-
  621.                                       'ory.
  622.                                      
  623.  CALL ShowInv(InventArray%())         'Redisplay the inventory, minus the
  624.                                       'name of the item the user decided to
  625.                                       'drop.
  626. END IF
  627.  
  628. END SUB
  629.  
  630. SUB GetItem (MapArray%(), InventArray%(), XLoc%, YLoc%)
  631. 'This SUB gets an item defined in the MapArray%() and places it in the
  632. 'Inventory list array.
  633. '
  634. 'Parameters:
  635. '-----------
  636. '
  637. 'MapArray%()    -- You should be familiar with what this is by now.
  638. '
  639. 'InventArray%() -- The Inventory array that will contain all possible items
  640. '                  you can obtain from the MapArray%() (Since we used ASCII
  641. '                  values of certain characters in the MapArray%() to denote
  642. '                  items (look at the DATA statements again!), these values
  643. '                  will indicate exactly what item was picked up on the
  644. '                  "map."
  645. '
  646. 'XLoc%          -- Your Current X-Axis Location on the map.
  647. '
  648. 'YLoc%          -- Your Current Y-Axis location on the map.
  649. '
  650. '**************************************************************************
  651. CONST BLANK = 32                                    'Local to this SUB only
  652.  
  653.  
  654. 'This loop searches for an available slot in the InventArray%() (An available
  655. 'slot is indicated by a 0 value). If it finds an empty slot (a ZERO (0)),
  656. 'then it places the ASCII value of the item from the MapArray%() into the
  657. 'inventory at whatever Index% had the ZERO (0). This way, the inventory
  658. 'regulates itself, rather than you regulating the inventory.  Since this
  659. 'sample game has the same number of items as that of the inventory array
  660. 'subscripts, there is no checking to see if the inventory is "full." If you
  661. 'wish, you CAN do this by converting this into a function.  If there is space
  662. 'in your inventory, it'll return TRUE, and place the item somewhere in the
  663. 'inventory array.  If there isn't any room, then it'll return FALSE, and you
  664. 'can tell the user that the inventory is full and they need to drop some
  665. 'items or whatever.  Anything's possible.
  666. '
  667. FOR I% = LBOUND(InventArray%) TO UBOUND(InventArray%)
  668.    IF InventArray%(I%) = 0 THEN                 'If we've found an empty slot
  669.                                                 'in our inventory...
  670.      InventArray%(I%) = MapArray%(XLoc%, YLoc%) 'Put the item we've discovered
  671.      EXIT FOR                                   'at (XLoc%, YLoc%) in the
  672.                                                 'MapArray%() into our invent-
  673.                                                 'ory, then exit the loop. We
  674.                                                 'don't want to fill up EVERY
  675.                                                 'empty slot with one item
  676.                                                 'do we?
  677.    END IF
  678. NEXT I%
  679.  
  680. MapArray%(XLoc%, YLoc%) = BLANK            'After we pick up our item
  681.                                            'from the map, we denote it's
  682.                                            'non-existance by replacing the
  683.                                            'item with a BLANK (ASCII 32).
  684.                                            'On the screen it will show
  685.                                            'nothing but a blank space.
  686.                                            'Please note that WE have the item
  687.                                            'now, but it's just not on the
  688.                                            '"floor" of the map anymore.
  689.                                            'Get it?
  690.  
  691.  
  692. END SUB
  693.  
  694. FUNCTION InKeyCode% STATIC
  695. 'This FUNCTION converts the string values that's usually returned by INKEY$
  696. 'into ASCII keyCode values.  Instead of string checking, we use integers
  697. 'instead. You can use this any ANY program! More efficent speedwise!
  698. 'Think of this as the INTEGER version of INKEY$.
  699. '
  700. '************************************************************************
  701.  
  702. InKeyCode = CVI(INKEY$ + STRING$(2, 0))
  703.  
  704.  
  705. END FUNCTION
  706.  
  707. FUNCTION InvCheck% (InventoryArray%())
  708. '   This FUNCTION checks to see if the inventory has ANY items in it at all.
  709. 'If it doesn't find an empty slot (designated by a ZERO (0) value in the
  710. 'array), then it increments a counter that counts how many items it runs into
  711. 'and sets the FUNCTION's value to NOTEMPTY.
  712. '
  713. '   This Function returns one (1) custom value, which is CONST FULL = -2.
  714. 'If you plan to use this function in an IF..THEN test condition, you must
  715. 'EXPLICITLY Check for the values 0, -1, and -2, and not just test for a non-
  716. 'zero like: IF InvCheck(ArrayName%()) THEN...  Is this clear? Good!
  717. '
  718. 'Parameters:
  719. '-----------
  720. '
  721. 'InventoryArray%() -- The array that contains the contents of the user's
  722. '                     inventory. The contents will NOT be changed.
  723. '
  724. '***************************************************************************
  725. CONST EMPTY = 0                                'Local to this FUNCTION ONLY!
  726. CONST NOTEMPTY = -1                            'Local to this FUNCTION ONLY!
  727. CONST FULL = -2                                'Local to... You get the idea!
  728. '---------------------------------------------------------------------------
  729. 'This LOOP cycles thru all the items in the inventory, from the first
  730. 'subscript to the last.
  731. '
  732. FOR X% = LBOUND(InventoryArray%) TO UBOUND(InventoryArray%)
  733.   IF InventoryArray%(X%) <> EMPTY THEN  'If X% slot in the array is NOT EMPTY
  734.                                         'then...
  735.      ItemCount% = ItemCount% + 1        'Count that item and other items it
  736.                                         'may run into...
  737.      InvCheck = NOTEMPTY                'and tell the user that it's
  738.                                         'NOTEMPTY.
  739.   END IF
  740. NEXT X%
  741.  
  742.  
  743. 'If The number of Items matches the highest subscript value of the inventory
  744. 'array, then tell the user that the inventory is FULL! However, in this
  745. 'example, the number of items available or the same number of slots available
  746. 'in our inventory.  For your game, you can have the user selectively drop or
  747. 'add items, when they can no longer "carry any more."
  748. '
  749. IF ItemCount% = UBOUND(InventoryArray%) THEN InvCheck = FULL
  750.  
  751. IF ItemCount% = 0 THEN InvCheck = EMPTY  'If ItemCounter value hasn't changed
  752.                                          'from ZERO (0), then obviously
  753.                                          'the Inventory is EMPTY, cause there
  754.                                          'were no items in the array to COUNT!
  755.  
  756. END FUNCTION
  757.  
  758. SUB LoadBarrierData (BarrierArray%())
  759. 'SUB This SUB loads up the "barrier" data for the map. If the player runs
  760. 'into one the ASCII values listed, then he or she will not be able to
  761. 'move beyond it.
  762. '
  763. 'Parameters:
  764. '-----------
  765. '
  766. 'BarrierArray%() -- The array that contains items or objects in the Map
  767. '                   table array that the user cannot move over or pass thru.
  768. '
  769. '***************************************************************************
  770.  
  771. BarrierArray%(1) = 179 '│ -- defined as a wall in the HouseMap() array
  772. BarrierArray%(2) = 196 '─ -- defined as another wall in the HouseMap() array
  773.  
  774. END SUB
  775.  
  776. SUB MovePlayer (MapArray%(), BoundArray%(), KeyPressed%, CurrentXLoc%, CurrentYLoc%, item%)
  777. 'This sub moves the player around the 2-D array map.  It's important to
  778. 'know that this sub MUST be called continuously, throughout the program!
  779. '
  780. 'Parameters:
  781. '-----------
  782. '
  783. 'MapArray%()  - The map that's being passed to this procedure. In this example,
  784. '               it's passing "HouseMap()". It's to be sure that this routine
  785. '               is generic as possible, so anyone could use it, without
  786. '               requiring nothing more than the .BI file for this program.
  787. '
  788. 'KeyPressed%  - The ASCII key value of whatever key was pressed. If this
  789. '               routine is to be used, it's imperative that you use the
  790. '               K% = InkeyCode% function in your program.  I use it cause it's
  791. '               faster than handling that CHR$(0) + CHR$(56) stuff. A LIB
  792. '               of all these routines will be available at some point.
  793. '
  794. 'CurrentXLoc% - The Current X-Axis Location in the array.  If you're at (8,9)
  795. '               when you start, then you're at:
  796. '
  797. '                              X-Axis   1234567890
  798. '                            <-----------------┬--┐
  799. '                                              │  │| 1
  800. '                                              │  │| 3
  801. '                                              │  │| 5
  802. '                                              │  │| 7
  803. '                                              x  │| 9
  804. '                                                 │| Y-Axis
  805. '                                                 
  806. '
  807. '               From this illustration, it's appearant that what we used to
  808. '               refer to as "ROW" using a LOCATE statment, is now the
  809. '               "COLUMN" (Y-Axis), and the "COLUMN" in reference to a LOCATE
  810. '               statment is now the "ROW"(X-Axis). In other words, we're
  811. '               referencing the array is if it were in a graphic SCREEN mode,
  812. '               where instead of ROW, COLUMN, it's COLUMN, ROW.  Why do I
  813. '               bring this up? Because if you decide to think of the array
  814. '               as the standard ROW, COLUMN, you'll screw up. That's why in
  815. '               the LOCATE statement in the main module, I have LOCATE Y%, X%
  816. '               NOT LOCATE X%, Y%.  Remeber this! For if you use these
  817. '               routines, you gotta load your MAP as I did in this program!
  818. '
  819. 'CurrentYLoc% - The Current Y-Axis Location in the Array.  If you're at
  820. '               (8,9) when you start the game, then you're at:
  821. '
  822. '                              X-Axis   1234567890
  823. '                            <--------------------┐
  824. '                                                 │| 1
  825. '                                                 │| 3
  826. '                                                 │| 5
  827. '                                                 │| 7
  828. '                                              x──┤| 9
  829. '                                                 │| Y-Axis
  830. '                                                 
  831. '
  832. 'Item%        - If, in the array, you stumble across anything except a
  833. '               32 (SPACE), this will tell you what it is, ASCII key value
  834. '               style.  You can use this to detect all sorts of things you
  835. '               defined in your array.  If you run into a 179 (Defined as a
  836. '               wall/boundary in this example), then in your loop you could
  837. '               have code to handle that "collision."  There are other
  838. '               possible uses.  Have fun!
  839. '               NOTE: Item% returns ZERO (0) if there is nothing there.
  840. '**************************************************************************
  841. CONST UP = 18432, DOWN = 20480, LEFT = 19200, RIGHT = 19712 'Local use only!
  842.  
  843. X% = CurrentXLoc%      'Assign the current location values
  844. Y% = CurrentYLoc%      'into terms of X% and Y% for easier understanding
  845. '-------------------------------------------------------------------------
  846.  
  847. SELECT CASE KeyPressed%
  848.   CASE UP
  849.     'If the Y% Location (LOC) isn't at the lower end of the MapArray% (The
  850.     'one (1) is added because we don't want to include the BORDERS in the
  851.     'actual playing field. Example: Here's a sample map:
  852.     '                                            x,y
  853.     '           (X-Axis)           DIM SampleMap(1 TO 9,1 TO 7) AS INTEGER
  854.     '           123456789         
  855.     '           |-------| 1
  856.     '           |       | 2
  857.     '           |       | 3
  858.     '           |       | 4  (Y-Axis)
  859.     '           |       | 5
  860.     '           |       | 6
  861.     '           |-------| 7
  862.     '
  863.     'Notice the dimensions? They INCLUDE the borders, "|" and "-"!
  864.     'The user doesn't want to move around on the walls (unless you want em
  865.     'to), so u gotta set the wall boundaries so that you cannot move on the
  866.     'walls and only within the wall space. Therefore, the dimensions of the
  867.     'area that the user can only move within is:
  868.     '
  869.     '               SampleMap(2 TO 8, 2 TO 6)
  870.     '
  871.     '                        (X-Axis)
  872.     '                        2345678  <----See? The borders aren't included
  873.     '                       |-------|      in the area that the user can move
  874.     '                       |you can| 2    around in.
  875.     '                       | only  | 3
  876.     '                       |move in| 4  (Y-Axis)
  877.     '                       | this  | 5
  878.     '                       | box!  | 6
  879.     '                       |-------|
  880.     '   
  881.     '     Get it? No? Well consider the original dimensions again:
  882.     '                   DIM SampleMap(1 TO 9, 1 TO 7) AS INTEGER
  883.     '
  884.     '               And our movable area dimensions:
  885.     '                   SampleMap(2 TO 8, 2 TO 6)
  886.     '
  887.     '     Say you're going UP, and you change the value of the Y% until you
  888.     'have reached the end of the map array. Without the "+ 1" you see below,
  889.     'your 'movements' would also include the wall, where you DON'T want to
  890.     'be. However, if you INCREMENT it ahead of time by 1, you'll be able to
  891.     'check for the "wall" sooner, and your movements wouldn't include _THE_
  892.     'wall.  The LBOUND of the SampleMap would be 1 (in 2D arrays, it only
  893.     'looks at the "X" value (ex. Array%(X,Y)), which in our cheap illustration
  894.     'includes a "|" as a wall. If 1 is added to that, then the value would be
  895.     'a 2. So if I wanted to move along the X-Axis and I reached the X location
  896.     'value of 2, and I ran into the Lower BOUNDs of the SampleMap + 1, I would
  897.     'have to stop right there, cause my X location would be 2, plus the lower
  898.     'bounds of the array (which is 1 in this case! Use OPTION BASE ALWAYS!)
  899.     'with 1 added to it = 2.  See? I hope so...  Can't explain it better than
  900.     'that.
  901.     '
  902.     '   In the case below, we use LBOUND(MapArray%) cause the LBOUND of ANY
  903.     'portion of this array is one (1).  I could have put a 1 in place of
  904.     'the LBOUND(array%) but it would be unreadable and hard to follow.
  905.     '
  906.     IF Y% <> LBOUND(MapArray%, 2) + 1 THEN 'If we make it beyond this point we
  907.     '(*"IF THERE'S A WALL"*)             'haven't run into any "walls."
  908.  
  909.       'This loops checks to see if the current X%,Y% location contains
  910.       'any barriers, such as a wall part like "│" (179) or "─" (196) as
  911.       'defined in the BoundArray%().  By the way, I designed this so that
  912.       'all you need to do is add an ASCII value of whatever item or character
  913.       'you used in your HouseMap() to the BarDat() Array, in oder for the
  914.       'user to not be able to penetrate/pass it. Since our BoundArray%()
  915.       'only contains two things that can't be moved beyond, it'll loop
  916.       'twice. Please note that as the list gets longer, the testing
  917.       'gets longer.
  918.       '
  919.       FOR I% = LBOUND(BoundArray%) TO UBOUND(BoundArray%)
  920.        'IF an Object at user Location X%,Y% is listed in the BoundArray%()
  921.        '"listing", then just EXIT the SUB; you can't move past whatever
  922.        'it is anyway...
  923.        '
  924.        IF Object(MapArray%(), X%, Y% - 1) = BoundArray%(I%) THEN EXIT SUB
  925.       NEXT I%
  926.  
  927.          Y% = Y% - 1     'Since we made it to here and there are no
  928.                          'barriers in the way, we can safely update our
  929.                          'user's position. We SUBTRACT -1 from Y% to show that
  930.                          'the player's going up in the array.
  931.                          'Just to let you know, all that
  932.                          'X, Y testing before was for the CURRENT location.
  933.                          'We have now "Moved" to Y% Loc in our HouseMap.
  934.  
  935.          IF Object(MapArray%(), X%, Y%) THEN 'Now. At our NEW loc, we check
  936.          '(*Object Testing*)                 'to see if there are any OBJECTS
  937.                                              'there. If there is, the ASCII
  938.                                              'value of the object (an item
  939.                                              'perhaps?) as defined by the
  940.                                              'HouseMap in the main module
  941.                                              'will be returned, which you can
  942.                                              'do with as you wish. This is
  943.                                              'good for when the user runs
  944.                                              'over an item, he/she can pick it
  945.                                              'up, or you can pick it up for
  946.                                              'them.  NOTE: For you greenhorns,
  947.                                              'if the condition is true, it'll
  948.                                              'return a non-zero. Any non-zero
  949.                                              'is considered true with an
  950.                                              'IF..THEN (unless u say otherwise)
  951.                                              'condition.
  952.  
  953.           item% = Object(MapArray%(), X%, Y%) 'Return the ASCII value of the
  954.                                               'object on the HouseMap "Floor".
  955.  
  956.          ELSE                                 'If NO Object was found (This
  957.                                               'Object Function screens out
  958.                                               'the ASCII 32's (spaces))...
  959.           item% = 0                           'Then return a ZERO (0) for item
  960.                                               'to show that no item was
  961.                                               'detected....
  962.  
  963.          END IF  '(*Object testing*)
  964.     END IF       '(*"IF THERE'S A WALL"*)
  965.  
  966.  
  967.     CASE DOWN
  968.         'The rest of this mess is the same as the above, except:
  969.         '1) Yer going DOWN, LEFT, and RIGHT
  970.         '2) In the case below, we're using UBOUND(Array%,2) cause we need
  971.         '   to get at the last subscript of the second dimension.  Put the
  972.         '   cursor under it and hit F1 to find out more info.
  973.         '
  974.         IF Y% <> UBOUND(MapArray%, 2) - 1 THEN 'If there aren't any WALLS going DOWN...
  975.          FOR I% = LBOUND(BoundArray%) TO UBOUND(BoundArray%)
  976.           'Check objects against our boundary array to see if we can
  977.           'continue.  If there's a boundary, we EXIT the SUB.
  978.           '
  979.           IF Object(MapArray%(), X%, Y% + 1) = BoundArray%(I%) THEN EXIT SUB
  980.          NEXT I%
  981.  
  982.           Y% = Y% + 1 'Update the player's position. We ADD +1 to Y% to
  983.                       'show that he's going DOWN. In the case of going UP,
  984.                       'we SUBTRACT -1 from Y%.
  985.  
  986.           IF Object(MapArray%(), X%, Y%) THEN    'If an object found, return
  987.              item% = Object(MapArray%(), X%, Y%) 'the Item% value.
  988.           ELSE
  989.              item% = 0                           'If no object found, return
  990.           END IF                                 'zero for Item%.
  991.         END IF
  992.  
  993.     CASE LEFT
  994.         IF X% <> LBOUND(MapArray%) + 1 THEN  'If no walls going LEFT...
  995.  
  996.          'Check for other boundaries...
  997.          'If found, EXIT SUB.
  998.          '
  999.          FOR I% = LBOUND(BoundArray%) TO UBOUND(BoundArray%)
  1000.           IF Object(MapArray%(), X% - 1, Y%) = BoundArray%(I%) THEN EXIT SUB
  1001.          NEXT I%
  1002.           X% = X% - 1  'Update player's position, SUBTRACTING -1 from X% to
  1003.                        'go to the LEFT.
  1004.  
  1005.           IF Object(MapArray%(), X%, Y%) THEN     'If object found, return
  1006.              item% = Object(MapArray%(), X%, Y%)  'Item% value.
  1007.           ELSE
  1008.              item% = 0                            'If none found, return zero
  1009.           END IF                                  'for Item% value.
  1010.         END IF
  1011.  
  1012.     CASE RIGHT
  1013.         IF X% <> UBOUND(MapArray%) - 1 THEN      'If no WALLS going RIGHT...
  1014.  
  1015.       'Check for boundaries; EXIT SUB if any found
  1016.       '
  1017.       FOR I% = LBOUND(BoundArray%) TO UBOUND(BoundArray%)
  1018.        IF Object(MapArray%(), X% + 1, Y%) = BoundArray%(I%) THEN EXIT SUB
  1019.       NEXT I%
  1020.           X% = X% + 1    'Update player's position by ADDING +1 to X% to
  1021.                          'go to the RIGHT.
  1022.  
  1023.           IF Object(MapArray%(), X%, Y%) THEN    'If object found, return
  1024.              item% = Object(MapArray%(), X%, Y%) 'Item% value, blah blah blah.
  1025.           ELSE
  1026.              item% = 0                           'Return zero if none found.
  1027.           END IF
  1028.         END IF
  1029.  
  1030. END SELECT
  1031.  
  1032. CurrentXLoc% = X%  'After all is said and done, return the NEW coords of
  1033. CurrentYLoc% = Y%  'the player.
  1034.  
  1035. END SUB
  1036.  
  1037. FUNCTION Object% (MapArray%(), X%, Y%)
  1038. 'This FUNCTION Detects whether or not the present (X%,Y%) location has
  1039. 'a value other that a BLANK space in it. It's used to detect walls, items,
  1040. 'people, etc.
  1041. '
  1042. 'Parameters:
  1043. '-----------
  1044. '
  1045. 'MapArray%() -- The array containing out HouseMap() as defined in our
  1046. '               DATA statements.
  1047. '
  1048. 'X%, Y%      -- The X and Y coordinates of where the user is in respect to
  1049. '               the map dimensions.
  1050. '
  1051. '*************************************************************************
  1052. CONST BLANK = 32               'BLANK is CHR$(32) (Space). Local use only!
  1053.  
  1054. IF MapArray%(X%, Y%) <> BLANK THEN  'IF the location doesn't contain a
  1055.                                     'BLANK (CHR$(32))....
  1056.    Object = MapArray%(X%, Y%)       'Then return whatever item value is at
  1057.                                     'coords X%, Y%.
  1058. END IF
  1059.  
  1060. END FUNCTION
  1061.  
  1062. FUNCTION PlayerStart% (MapArray%(), PlayerChar%, CurXLoc%, CurYLoc%)
  1063. 'This FUNCTION detects the user's starting point in the array. In this example,
  1064. 'it's gonna be (8,9).
  1065. '
  1066. 'Parameters:
  1067. '-----------
  1068. '
  1069. 'MapArray%()  - The 2-D Map being looked at.
  1070. '
  1071. 'PlayerChar%  - Whatever ASCII character value yer using for your player.
  1072. '               If yer using CHR$(2), then that's what it'll look for. If
  1073. '               it's CHR$(17), then it'll look for that, and so on.
  1074. '
  1075. 'CurXLoc%     - Current X Location. Wherever you are on the X-Axis in the
  1076. '               array.  This value is returned.
  1077. '
  1078. 'CurYLoc%     - Current Y Location. Wherever you are on the Y-Axis in the
  1079. '               array.  This value is returned.
  1080. '
  1081. 'PlayerStart  - This function will return a TRUE (-1) if the player has been
  1082. '               found in the grid, and FALSE if it hasn't. This is really
  1083. '               more of a debug feature rather than anything useful.
  1084. '**************************************************************************
  1085. CONST BLANK = 32      'The ASCII Value for a space in the map. Local use only!
  1086. CONST TRUE = -1        'BOOLEAN for Local use!
  1087. CONST FALSE = NOT TRUE 'BOOLEAN for Local use!
  1088. CONST NOTDEF = -2  'Means that parameter PlayerChar% has NO value! Local use!
  1089.  
  1090.  
  1091. IF PlayerChar% THEN  'If a PlayerChar% value is there (NON-ZERO)...
  1092.  
  1093.   'This FOR loop loops until it reaches the Upper bound of the X-Axis.  It's
  1094.   'looking for the Player%.  Player% is the ASCII value of whatever character
  1095.   'it comes across in the MapArray%(). If it matches with the ASCII value of
  1096.   'the character YOU wanted to start with, it retrieves the X,Y location
  1097.   'of where it was found.
  1098.   '
  1099.   FOR X% = LBOUND(MapArray%) TO UBOUND(MapArray%)
  1100.    FOR Y% = LBOUND(MapArray%, 2) TO UBOUND(MapArray%, 2)
  1101.     Player% = MapArray%(X%, Y%)     'Bring in all ASCII values of the map
  1102.       IF Player% = PlayerChar% THEN 'If PLAYER% value equals the PlayerChar%
  1103.                                     'that was defined...
  1104.           MapArray%(X%, Y%) = BLANK 'Put a BLANK (ASCII 32) there
  1105.                                     '(Since we no longer need this info!),
  1106.           CurXLoc% = X%             'return the X-Axis position of the player,
  1107.           CurYLoc% = Y%             'return the Y-Axis position of the player,
  1108.           PlayerStart = TRUE        'Set FUNC to TRUE since we found starting
  1109.           EXIT FUNCTION             'point, and exit this function.
  1110.       END IF
  1111.    NEXT Y%
  1112.   NEXT X%
  1113.           PlayerStart = FALSE       'If we've made it here, then obviously
  1114.                                     'the FOR loop finished, and it couldn't
  1115.                                     'FIND the freakin Player% Character
  1116.                                     'anywhere in the array! I find that this
  1117.                                     'could be useful in EXE compilation, if
  1118.                                     'you decide to use DATA statements in yer
  1119.                                     'EXE. See the warning on DATA statements
  1120.                                     'in the main module.
  1121. ELSE
  1122.  
  1123.   PlayerStart = NOTDEF              'This is REALLY for DEBUGGING. Since
  1124.                                     'you haven't defined a value for
  1125.                                     'PlayerChar% in the parameters, we return
  1126.                                     'a -2 (NOTDEF).
  1127. END IF
  1128.  
  1129. END FUNCTION
  1130.  
  1131. DEFINT A-Z
  1132. SUB SetGameFlags (FlagArray%())
  1133. 'This SUB Initializes all possible goals you can get to FALSE. This is good
  1134. 'for RPG gaming, when you have your character complete certain tasks thruout
  1135. 'your game.  However, the flag checking in this program example is only
  1136. 'used to detect whether or not you have completed everything; if so, then
  1137. 'you can run a SUB to do your ending sequence or whatever. You can probably
  1138. 'modify this so that you can use it to track WHAT goals have been completed
  1139. 'as opposed to HOW MANY goals have been completed.  The Example:
  1140. '
  1141. 'DIM Flags(1 TO 20, 1 TO 2) AS STRING * 10
  1142. '
  1143. 'Flags(1) = "TALKALIEN"  <--Talked to an Alien
  1144. 'Flags(2) = "GOTGOLD"    <--Obtained some gold
  1145. 'Flags(3) = "GOTLAID"    <--Guess?
  1146. '.
  1147. '.
  1148. 'Flags(20) = "KILLDKING" <--Killed the king
  1149. '
  1150. 'You get the idea. Instead of checking for a FALSE value (like in the
  1151. 'CheckFlags FUNCTION), just check for a string indicating what tasks have
  1152. 'been completed, and run a SUB or something in response. My example used
  1153. 'lengthy strings, but yours can be as small and cryptic as you like. Heck,
  1154. 'You can even use INTEGER values! Be creative!
  1155. '
  1156. 'Parameters:
  1157. '-----------
  1158. '
  1159. 'FlagArray%() -- The array that will contain BOOLEANS to check if any task
  1160. '                has NOT been completed before allowing you to complete
  1161. '                your mission and show the "YOU'VE WON" message.
  1162. '
  1163. '***************************************************************************
  1164. CONST FALSE = 0                                             'Local Use ONLY!
  1165.  
  1166.  
  1167. FOR X% = LBOUND(FlagArray%) TO UBOUND(FlagArray%) 'Cycle thru the FlagArray%()
  1168.    FlagArray%(X%) = FALSE                         'Initial everything to FALSE
  1169. NEXT X%
  1170.  
  1171.  
  1172. END SUB
  1173.  
  1174. DEFSNG A-Z
  1175. SUB ShowInv (InventArray%())
  1176. 'This SUB is responsible for showing you the contents of your inventory.
  1177. 'This SUB is tailor made just for this example, so I don't recommend you try
  1178. 'to use this AS IS in one of your own programs.  You can probably gather an
  1179. 'idea from this though. If you wanted to, you could use a 2D array for the
  1180. 'inventory, and not have to do what you see below.  In the 2D inventory, not
  1181. 'only could you have the number of an inventory item, but the description
  1182. 'along with it.  Example:
  1183. '
  1184. 'DIM Inventory(1 TO 5, 1 TO 1) AS STRING * 12
  1185. '
  1186. 'Inventory(1,1) = "+"          <--an item that you defined
  1187. 'Inventory(1,2) = "Big Sword"  <--Item description
  1188. '
  1189. 'But I didn't do this cause of simplicity, and the fact that some dude
  1190. 'wanted a demo of something like this really bad, so I wanted to cut a few
  1191. 'corners.
  1192. '
  1193. '**************************************************************************
  1194. FOR X% = LBOUND(InventArray%) TO UBOUND(InventArray%)
  1195.     IF InventArray%(X%) <> 0 THEN             'If the slot's not blank...
  1196.        LOCATE X% + 1, 51                      'Locate Inventory box
  1197.        COLOR 15: PRINT LTRIM$(STR$(X%)); ") "; 'Print the number of the item
  1198.        COLOR 14: PRINT CHR$(InventArray%(X%)); 'And print the Item itself.
  1199.        SELECT CASE InventArray%(X%)            'See what ASC val of the item
  1200.                                                'is, check it against the
  1201.                                                'CONSTants as defined in the
  1202.                                                'main module, and print out
  1203.                                                'the description it matches.
  1204.         CASE MONEY: COLOR 12: PRINT " - Money Bag!"
  1205.         CASE BOOT: COLOR 12: PRINT " - Timberland Boots"
  1206.         CASE SWORD: COLOR 12: PRINT " - Double-Edged Sword"
  1207.         CASE RING: COLOR 12: PRINT " - Invisiblity Ring"
  1208.        END SELECT
  1209.     ELSEIF InventArray%(X%) = 0 THEN              'If there's an empty slot
  1210.         LOCATE X% + 1, 51: PRINT STRING$(26, 32); 'Just print a blank in the
  1211.                                                   'description's place.
  1212.     END IF
  1213. NEXT X%
  1214.  
  1215. END SUB
  1216.  
  1217. SUB ShowMove (MapArray%(), KeyPress%, X%, Y%)
  1218. 'This SUB shows the movement of the player on the screen (If SHOW MAP
  1219. 'is enabled).  Please note that this SUB is ONLY for this example, and will
  1220. 'NOT be thoroughly commented.  If you figger you can use this in any of your
  1221. 'own programs, go right ahead.
  1222. '
  1223. '****************************************************************************
  1224. CONST UP = 18432, DOWN = 20480, LEFT = 19200, RIGHT = 19712  'Local use only!
  1225.  
  1226.  
  1227. 'This loop is constantly being called throughout the program to update
  1228. 'the display of the MAP.
  1229. '
  1230. FOR a% = 1 TO 10
  1231.   FOR B% = 1 TO 10
  1232.        LOCATE B%, a%: PRINT CHR$(MapArray%(a%, B%));
  1233.        LOCATE Y%, X%: PRINT CHR$(35);  '# - what we use for the player's char
  1234.                                        'on screen.
  1235.   NEXT B%
  1236. NEXT a%
  1237.  
  1238. SELECT CASE KeyPress%                     'Update player's movement in the
  1239.    CASE UP, DOWN, LEFT, RIGHT             'MAP array.
  1240.      LOCATE Y%, X%: PRINT CHR$(35);
  1241. END SELECT
  1242.  
  1243. END SUB
  1244.  
  1245.