Author Topic: Isometric Demo re-revisited (getting better!)  (Read 782 times)

0 Members and 1 Guest are viewing this topic.

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
Isometric Demo re-revisited (getting better!)
« on: December 02, 2021, 10:40:31 am »
I did more playing around with the Isometric Mapping Demo code from
https://www.qb64.org/forum/index.php?topic=1903.30
and added a "walk around" mode with code to render cubes that block the view of the player as transparent,
with a simultaneous 2-D top down "map" view of the player's current Z slice.
This could be the beginning of a framework for simple 2.5d games.
Anyway I hope someone enjoys this or finds it helpful...
Any comments welcome.

Code: QB64: [Select]
  1. ' ################################################################################################################################################################
  2. ' Isomatric mapping demo re-revisited
  3. ' Version 2.69 by madscijr
  4.  
  5. ' Based on Isometric Mapping Demo
  6. ' by SMcNeill, bplus, and others at
  7. ' https://www.qb64.org/forum/index.php?topic=1903.30
  8.  
  9. ' This crude version uses a 3-dimensional array (32x32x32)
  10. ' to store cubes of different colors,
  11. ' and draws them to the screen in 2.5D "isometric".
  12. ' Added code to render cubes that block the view of
  13. ' the player as transparent. Added a 2-D top down "map"
  14. ' view of the player's current Z slice.
  15.  
  16. ' TO DO:
  17. ' * allow player to rotate their view
  18. ' * option to hide objects out of player's line-of-sight
  19. ' * add objects (water, ladders, ropes, windows, doors, ramps, etc.)
  20. ' * shrink grid size to 8x8 (may need to use some other rendering method)
  21. ' * expand world to bigger than screen (2.5d scrolling view)
  22. ' * show player as a stick figure (like "Realm of Impossibility")
  23. ' * add ability to walk up ramps / climb ladders / etc.
  24. ' * simultaneously show additional 1st person view
  25. ' * add ability for tilting head up/down in first person
  26. ' * split screen (x2 or x4) local multi-player version
  27. ' * make simple open world (players can add/remove blocks, build in real time, save screens)
  28. ' * make simple games (maze craze, capture the flag, snake, surround, 2.5d pong)
  29. ' * make more complex games (berzerk, lode runner, atari combat / tank)
  30. ' * make awesome complex games (2.5d lunar lander, atari adventure, asteroids, gravitar, etc.)
  31.  
  32. ' ################################################################################################################################################################
  33.  
  34. ' =============================================================================
  35. ' GLOBAL DECLARATIONS a$=string, i%=integer, L&=long, s!=single, d#=double
  36. ' div: int1% = num1% \ den1%
  37. ' mod: rem1% = num1% MOD den1%
  38.  
  39. ' -----------------------------------------------------------------------------
  40. ' boolean constants
  41. ' -----------------------------------------------------------------------------
  42. Const FALSE = 0
  43. Const TRUE = Not FALSE
  44.  
  45. ' -----------------------------------------------------------------------------
  46. ' KeyDownConstants
  47. ' -----------------------------------------------------------------------------
  48. Const c_iKeyDown_Esc = 27
  49. Const c_iKeyDown_F1 = 15104
  50. Const c_iKeyDown_F2 = 15360
  51. Const c_iKeyDown_F3 = 15616
  52. Const c_iKeyDown_F4 = 15872
  53. Const c_iKeyDown_F5 = 16128
  54. Const c_iKeyDown_F6 = 16384
  55. Const c_iKeyDown_F7 = 16640
  56. Const c_iKeyDown_F8 = 16896
  57. Const c_iKeyDown_F9 = 17152
  58. Const c_iKeyDown_F10 = 17408
  59. Const c_iKeyDown_Tilde = 96
  60. Const c_iKeyDown_1 = 49
  61. Const c_iKeyDown_2 = 50
  62. Const c_iKeyDown_3 = 51
  63. Const c_iKeyDown_4 = 52
  64. Const c_iKeyDown_5 = 53
  65. Const c_iKeyDown_6 = 54
  66. Const c_iKeyDown_7 = 55
  67. Const c_iKeyDown_8 = 56
  68. Const c_iKeyDown_9 = 57
  69. Const c_iKeyDown_0 = 48
  70. Const c_iKeyDown_Minus = 45
  71. Const c_iKeyDown_EqualPlus = 61
  72. Const c_iKeyDown_BkSp = 8
  73. Const c_iKeyDown_Ins = 20992
  74. Const c_iKeyDown_Home = 18176
  75. Const c_iKeyDown_PgUp = 18688
  76. Const c_iKeyDown_Del = 21248
  77. Const c_iKeyDown_End = 20224
  78. Const c_iKeyDown_PgDn = 20736
  79. Const c_iKeyDown_KEYPAD_7_Home = 18176
  80. Const c_iKeyDown_KEYPAD_8_Up = 18432
  81. Const c_iKeyDown_KEYPAD_9_PgUp = 18688
  82. Const c_iKeyDown_KEYPAD_4_Left = 19200
  83. Const c_iKeyDown_KEYPAD_6_Right = 19712
  84. Const c_iKeyDown_KEYPAD_1_End = 20224
  85. Const c_iKeyDown_KEYPAD_2_Down = 20480
  86. Const c_iKeyDown_KEYPAD_3_PgDn = 20736
  87. Const c_iKeyDown_KEYPAD_0_Ins = 20992
  88. Const c_iKeyDown_KEYPAD_Period_Del = 21248
  89. Const c_iKeyDown_Tab = 9
  90. Const c_iKeyDown_Q = 113
  91. Const c_iKeyDown_W = 119
  92. Const c_iKeyDown_E = 101
  93. Const c_iKeyDown_R = 114
  94. Const c_iKeyDown_T = 116
  95. Const c_iKeyDown_Y = 121
  96. Const c_iKeyDown_U = 117
  97. Const c_iKeyDown_Pipe = 105
  98. Const c_iKeyDown_O = 111
  99. Const c_iKeyDown_P = 112
  100. Const c_iKeyDown_BracketLeft = 91
  101. Const c_iKeyDown_BracketRight = 93
  102. Const c_iKeyDown_Backslash = 92
  103. Const c_iKeyDown_A = 97
  104. Const c_iKeyDown_S = 115
  105. Const c_iKeyDown_D = 100
  106. Const c_iKeyDown_F = 102
  107. Const c_iKeyDown_G = 103
  108. Const c_iKeyDown_H = 104
  109. Const c_iKeyDown_J = 106
  110. Const c_iKeyDown_K = 107
  111. Const c_iKeyDown_L = 108
  112. Const c_iKeyDown_SemiColon = 59
  113. Const c_iKeyDown_Apostrophe = 39
  114. Const c_iKeyDown_Enter = 13
  115. Const c_iKeyDown_Z = 22
  116. Const c_iKeyDown_X = 120
  117. Const c_iKeyDown_C = 99
  118. Const c_iKeyDown_V = 118
  119. Const c_iKeyDown_B = 98
  120. Const c_iKeyDown_N = 110
  121. Const c_iKeyDown_M = 109
  122. Const c_iKeyDown_Comma = 44
  123. Const c_iKeyDown_Period = 46
  124. Const c_iKeyDown_Slash = 47
  125. Const c_iKeyDown_Up = 18432
  126. Const c_iKeyDown_Left = 19200
  127. Const c_iKeyDown_Down = 20480
  128. Const c_iKeyDown_Right = 19712
  129. Const c_iKeyDown_Spacebar = 32
  130.  
  131. ' -----------------------------------------------------------------------------
  132. ' constants for map (MapBlockType.Typ)
  133. ' -----------------------------------------------------------------------------
  134. Const c_iMapType_Empty = 0
  135. Const c_iMapType_Floor_Tiled = 1
  136. Const c_iMapType_Wall = 2
  137. Const c_iMapType_Water = 3
  138. Const c_iMapType_Window = 4
  139. Const c_iMapType_Player1 = 5
  140. Const c_iMapType_Player2 = 6
  141.  
  142. ' -----------------------------------------------------------------------------
  143. ' constants for 2.5D movement
  144. ' -----------------------------------------------------------------------------
  145. Const c_iDir_Down = 1
  146. Const c_iDir_Up = 2
  147. Const c_iDir_Left = 3
  148. Const c_iDir_Right = 4
  149. Const c_iDir_Back = 5
  150. Const c_iDir_Forward = 6
  151. Const c_iDir_Min = 1
  152. Const c_iDir_Max = 6
  153.  
  154. ' -----------------------------------------------------------------------------
  155. ' constants for drawing the 2.5D screen
  156. ' -----------------------------------------------------------------------------
  157. Const cGridOffsetX = 50
  158. Const cGridOffsetY = 50
  159. Const cGridOffsetZ = 0
  160. Const cScreenOffsetX = 500 ' 450
  161. Const cScreenOffsetY = 300 ' 50
  162. Const cScreenOffsetZ = 0
  163.  
  164. ' =============================================================================
  165. ' USER DEFINED TYPES
  166. ' =============================================================================
  167. Type MapBlockType
  168.     Typ As Integer ' c_iMapType_Empty, c_iMap_Floor_Tiled, c_iMap_Wall, etc.
  169.     'Vis As Integer ' TRUE = visible, FALSE = don't render
  170.     'Lit As Long ' light offset
  171.     Color1 As Long ' main color
  172.     Color2 As Long ' secondary color if needed
  173.     Color3 As Long ' third color if needed
  174.     AlphaOverride As Integer ' can be used to override alpha (0 treated as opaque)
  175. End Type ' MapBlockType
  176.  
  177. ' =============================================================================
  178. ' GLOBAL VARIABLES
  179. Dim Shared m_ProgramPath$: m_ProgramPath$ = Left$(Command$(0), _InStrRev(Command$(0), "\"))
  180. Dim Shared m_ProgramName$: m_ProgramName$ = Mid$(Command$(0), _InStrRev(Command$(0), "\") + 1)
  181. Dim Shared m_iGridSize As Integer: m_iGridSize = 10 ' < 10 is causing problems with PAINT
  182. Dim Shared m_iMapMinX As Integer: m_iMapMinX = 0
  183. Dim Shared m_iMapMaxX As Integer: m_iMapMaxX = 32
  184. Dim Shared m_iMapMidX As Integer: m_iMapMidX = (m_iMapMaxX - m_iMapMinX) \ 2
  185. Dim Shared m_iMapMinY As Integer: m_iMapMinY = 0
  186. Dim Shared m_iMapMaxY As Integer: m_iMapMaxY = 32
  187. Dim Shared m_iMapMidY As Integer: m_iMapMidY = (m_iMapMaxY - m_iMapMinY) \ 2
  188. Dim Shared m_iMapMinZ As Integer: m_iMapMinZ = 0
  189. Dim Shared m_iMapMaxZ As Integer: m_iMapMaxZ = 32
  190. Dim Shared m_iMapMidZ As Integer: m_iMapMidZ = (m_iMapMaxZ - m_iMapMinZ) \ 2
  191.  
  192. ' =============================================================================
  193. ' LOCAL VARIABLES
  194. Dim in$
  195.  
  196. ' ****************************************************************************************************************************************************************
  197. ' ACTIVATE DEBUGGING WINDOW
  198. _Echo "Started " + m_ProgramName$
  199. _Echo "Debugging on..."
  200. ' ****************************************************************************************************************************************************************
  201.  
  202. ' =============================================================================
  203. ' START THE MAIN ROUTINE
  204. main
  205.  
  206. ' =============================================================================
  207. ' FINISH
  208. System ' return control to the operating system
  209. Print m_ProgramName$ + " finished."
  210. Input "Press <ENTER> to continue", in$
  211.  
  212. ' ****************************************************************************************************************************************************************
  213. ' DEACTIVATE DEBUGGING WINDOW
  214. ' ****************************************************************************************************************************************************************
  215.  
  216.  
  217. ' /////////////////////////////////////////////////////////////////////////////
  218.  
  219. Sub main
  220.     Dim RoutineName As String: RoutineName = "main"
  221.     Dim in$
  222.     Dim result$
  223.    
  224.     Screen 0
  225.  
  226.     Do
  227.         Cls
  228.         Print m_ProgramName$
  229.         Print
  230.         Print "Isomatric Mapping Demo Re-visited"
  231.         Print "v2.69, by Softintheheadware (Dec, 2021)"
  232.         Print
  233.         'PRINT "CONTROLS: PRESS <ESC> TO RETURN TO MENU"
  234.         'PRINT "PLAYER  LEFT       RIGHT       UP        DOWN       "
  235.         'PRINT "1       CRSR LEFT  CRSR RIGHT  CRSR UP   CRSR DOWN  "
  236.         'PRINT "2       KEYPAD 4   KEYPAD 6    KEYPAD 8  KEYPAD 2   "
  237.         'PRINT "3       A          S           W         Z          "
  238.         'PRINT "4       J          K           I         M          "
  239.         'PRINT
  240.  
  241.         Print "1. IsometricDemo1"
  242.         Print "2. IsometricDemo2"
  243.         Print "3. Move around in 2.5D"
  244.         Print
  245.         Print "What to do? ('q' to exit)"
  246.  
  247.         Input in$: in$ = LCase$(Left$(in$, 1))
  248.  
  249.         If in$ = "1" Then
  250.             result$ = IsometricDemo1
  251.         ElseIf in$ = "2" Then
  252.             result$ = IsometricDemo2
  253.         ElseIf in$ = "3" Then
  254.             result$ = IsometricDemo3
  255.         End If
  256.        
  257.         If Len(result$) > 0 Then
  258.             Print result$
  259.         End If
  260.        
  261.     Loop Until in$ = "q"
  262. End Sub ' main
  263.  
  264. ' /////////////////////////////////////////////////////////////////////////////
  265.  
  266. Function IsometricDemo1$
  267.     Dim RoutineName As String: RoutineName = "IsometricDemo1"
  268.     Dim sResult As String: sResult = ""
  269.     Dim arrMap(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapBlockType
  270.     Dim iX%
  271.     Dim iY%
  272.     Dim iZ%
  273.     Dim iNextX%
  274.     Dim iNextY%
  275.     Dim iNextZ%
  276.     Dim iPosX1%
  277.     Dim iPosX2%
  278.     Dim iPosY1%
  279.     Dim iPosY2%
  280.     Dim iLoopX%
  281.     Dim iLoopY%
  282.     Dim iLoopZ%
  283.     Dim iNextColor&
  284.     Dim iColorScheme%
  285.     Dim bContinue As Integer
  286.     Dim iDirection%
  287.     Dim bFinished As Integer
  288.     Dim iCount%
  289.     Dim iOpen%
  290.     Dim iMove%
  291.     Dim iSegmentLength%
  292.     Dim iMaxLength%
  293.     Dim bFirst As Integer
  294.     Dim bQuit As Integer
  295.     Dim in$
  296.    
  297.     ' INITIALIZE
  298.     'Screen _NewImage(1024, 720, 32) : _ScreenMove _Middle
  299.     Screen _NewImage(1280, 1024, 32)
  300.    
  301.     ' =============================================================================
  302.     ' MAIN LOOP
  303.     bQuit = FALSE
  304.     Do
  305.         Cls
  306.  
  307.         ' -----------------------------------------------------------------------------
  308.         ' INITIALIZE MAP TO EMPTY
  309.         ClearIsometricMap arrMap()
  310.        
  311.         ' -----------------------------------------------------------------------------
  312.         ' DRAW FLOOR
  313.         iZ% = 0
  314.         For iLoopX% = 0 To 32
  315.             For iLoopY% = 0 To 32
  316.                 arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iMapType_Floor_Tiled
  317.                 arrMap(iLoopX%, iLoopY%, iZ%).Color1 = cGray&
  318.                 arrMap(iLoopX%, iLoopY%, iZ%).Color2 = cLightGray&
  319.             Next iLoopY%
  320.         Next iLoopX%
  321.        
  322.         ' -----------------------------------------------------------------------------
  323.         ' DRAW BLOCKS TO CHECK ORIENTATION
  324.        
  325.         For iLoopZ% = m_iMapMinZ + 1 To m_iMapMaxZ
  326.             arrMap(m_iMapMinX, m_iMapMinY, iLoopZ%).Typ = c_iMapType_Wall
  327.             arrMap(m_iMapMinX, m_iMapMinY, iLoopZ%).Color1 = cRed&
  328.            
  329.             arrMap(m_iMapMaxX, m_iMapMinY, iLoopZ%).Typ = c_iMapType_Wall
  330.             arrMap(m_iMapMaxX, m_iMapMinY, iLoopZ%).Color1 = cBlue&
  331.            
  332.             arrMap(m_iMapMinX, m_iMapMaxY, iLoopZ%).Typ = c_iMapType_Wall
  333.             arrMap(m_iMapMinX, m_iMapMaxY, iLoopZ%).Color1 = cGreen&
  334.            
  335.             'arrMap(m_iMapMaxX, m_iMapMaxY, iLoopZ%).Typ = c_iMapType_Wall
  336.             'arrMap(m_iMapMaxX, m_iMapMaxY, iLoopZ%).Color1 = cYellow&
  337.            
  338.             'arrMap(m_iMapMinX, m_iMapMidY, iLoopZ%).Typ = c_iMapType_Wall
  339.             'arrMap(m_iMapMinX, m_iMapMidY, iLoopZ%).Color1 = cOrange&
  340.             '
  341.             'arrMap(m_iMapMaxX, m_iMapMidY, iLoopZ%).Typ = c_iMapType_Wall
  342.             'arrMap(m_iMapMaxX, m_iMapMidY, iLoopZ%).Color1 = cPurple&
  343.             '
  344.             'arrMap(m_iMapMidX, m_iMapMinY, iLoopZ%).Typ = c_iMapType_Wall
  345.             'arrMap(m_iMapMidX, m_iMapMinY, iLoopZ%).Color1 = cLime&
  346.             '
  347.             'arrMap(m_iMapMidX, m_iMapMaxY, iLoopZ%).Typ = c_iMapType_Wall
  348.             'arrMap(m_iMapMidX, m_iMapMaxY, iLoopZ%).Color1 = cCyan&
  349.         Next iLoopZ%
  350.        
  351.         ' -----------------------------------------------------------------------------
  352.         ' DRAW SOME OBJECTS
  353.         If TRUE = TRUE Then
  354.             iX% = 16
  355.             iY% = 3
  356.            
  357.             iNextColor& = cRed&
  358.             iLoopZ% = 1
  359.             iLoopY% = iY%
  360.             For iLoopX% = iX% To (iX% + 10)
  361.                 arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iMapType_Wall
  362.                 arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1 = iNextColor&
  363.             Next iLoopX%
  364.            
  365.             iNextColor& = cBlue&
  366.             iLoopZ% = 1
  367.             iLoopY% = iY% + 8
  368.             For iLoopX% = iX% To (iX% + 10)
  369.                 arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iMapType_Wall
  370.                 arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1 = iNextColor&
  371.             Next iLoopX%
  372.            
  373.             iNextColor& = cGreen&
  374.             iLoopZ% = 1
  375.             iLoopX% = iX% + 1
  376.             For iLoopY% = (iY% + 1) To (iY% + 7)
  377.                 arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iMapType_Wall
  378.                 arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1 = iNextColor&
  379.             Next iLoopY%
  380.            
  381.             iNextColor& = cYellow&
  382.             iLoopZ% = 1
  383.             iLoopX% = iX% + 9
  384.             For iLoopY% = (iY% + 1) To (iY% + 7)
  385.                 arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iMapType_Wall
  386.                 arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1 = iNextColor&
  387.             Next iLoopY%
  388.         End If
  389.        
  390.         ' -----------------------------------------------------------------------------
  391.         ' DRAW A PYRAMID
  392.         If TRUE = TRUE Then
  393.             iX% = 2
  394.             iY% = 18
  395.             iZ% = 1
  396.             iPosX1% = iX%
  397.             iPosX2% = iX% + 10
  398.             iPosY1% = iY%
  399.             iPosY2% = iY% + 10
  400.             iNextColor& = cRed&
  401.             iColorScheme% = 1 ' 1 = Rainbow6 #1, 9 = Rainbow6 #2, etc.
  402.            
  403.             bContinue = TRUE
  404.             Do
  405.                 ' PLOT NEXT LEVEL
  406.                 For iLoopX% = iPosX1% To iPosX2%
  407.                     For iLoopY% = iPosY1% To iPosY2%
  408.                         arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iMapType_Wall
  409.                         arrMap(iLoopX%, iLoopY%, iZ%).Color1 = iNextColor&
  410.                     Next iLoopY%
  411.                 Next iLoopX%
  412.                
  413.                 ' MOVE UP A LEVEL
  414.                 iPosX1% = iPosX1% + 1
  415.                 iPosX2% = iPosX2% - 1
  416.                 iPosY1% = iPosY1% + 1
  417.                 iPosY2% = iPosY2% - 1
  418.                 DoCycleColor iColorScheme%, iNextColor&
  419.                
  420.                 ' QUIT AFTER WE REACH THE TOP
  421.                 If (iPosX1% <= iPosX2%) And (iPosY1% <= iPosY2%) Then
  422.                     iZ% = iZ% + 1
  423.                 Else
  424.                     bContinue = FALSE
  425.                 End If
  426.                
  427.             Loop Until bContinue = FALSE
  428.         End If
  429.  
  430.         ' -----------------------------------------------------------------------------
  431.         ' DRAW PIPES
  432.         If TRUE = TRUE Then
  433.             ' START POSITION
  434.             iX% = m_iMapMaxX ' 30 ' RandomNumber(0, 32)
  435.             iY% = m_iMapMaxY ' 28 ' RandomNumber(0, 32)
  436.             iZ% = 1 ' 32
  437.            
  438.             ' LENGTH OF PIPES
  439.             iSegmentLength% = 4
  440.             iMaxLength% = 64
  441.            
  442.             ' START COLOR + DEFINE HOW COLOR CHANGES
  443.             iNextColor& = cRed&
  444.             iColorScheme% = 2 ' 0 = don't change, 2 = Rainbow18 #1, 10 = Rainbow18 #2, etc.
  445.            
  446.             ' INITIALIZE
  447.             bFirst = TRUE
  448.             iCount% = 0
  449.             iMove% = 0
  450.             bFinished = FALSE
  451.             Do
  452.                 iNextX% = iX%
  453.                 iNextY% = iY%
  454.                 iNextZ% = iZ%
  455.                
  456.                 ' CHANGE DIRECTION EVERY iSegmentLength% SPACES
  457.                 iMove% = iMove% + 1
  458.                 If iMove% > iSegmentLength% Then
  459.                     iMove% = 0
  460.                    
  461.                     ' PICK A DIRECTION
  462.                     If bFirst = TRUE Then
  463.                         ' MOVE UP FOR FIRST MOVE
  464.                         iDirection% = c_iDir_Up
  465.                         bFirst = FALSE
  466.                     Else
  467.                         ' PICK A RANDOM DIRECTION
  468.                         iDirection% = RandomNumber(c_iDir_Min, c_iDir_Max)
  469.                     End If
  470.                 End If
  471.                
  472.                 Select Case iDirection%
  473.                     Case c_iDir_Down:
  474.                         If iNextZ% > 0 Then
  475.                             iNextZ% = iNextZ% - 1
  476.                         End If
  477.                     Case c_iDir_Up:
  478.                         If iNextZ% < 32 Then
  479.                             iNextZ% = iNextZ% + 1
  480.                         End If
  481.                     Case c_iDir_Left:
  482.                         If iNextX% > 0 Then
  483.                             iNextX% = iNextX% - 1
  484.                         End If
  485.                     Case c_iDir_Right:
  486.                         If iNextX% < 32 Then
  487.                             iNextX% = iNextX% + 1
  488.                         End If
  489.                     Case c_iDir_Back:
  490.                         If iNextY% > 0 Then
  491.                             iNextY% = iNextY% - 1
  492.                         End If
  493.                     Case Else: ' c_iDir_Forward
  494.                         If iNextY% < 32 Then
  495.                             iNextY% = iNextY% + 1
  496.                         End If
  497.                 End Select
  498.                
  499.                 ' CHECK IF NEXT SPACE IS EMPTY
  500.                 If arrMap(iNextX%, iNextY%, iNextZ%).Typ = c_iMapType_Empty Then
  501.                     ' SPACE IS EMPTY
  502.                     ' DRAW HERE
  503.                    
  504.                     iCount% = iCount% + 1
  505.                     iX% = iNextX%
  506.                     iY% = iNextY%
  507.                     iZ% = iNextZ%
  508.                    
  509.                     ' GET NEXT COLOR AND DRAW BLOCK
  510.                     DoCycleColor iColorScheme%, iNextColor&
  511.                     arrMap(iX%, iY%, iZ%).Typ = c_iMapType_Wall
  512.                     arrMap(iX%, iY%, iZ%).Color1 = iNextColor&
  513.                    
  514.                     ' HAVE WE PLACED MAX # OF BLOCKS?
  515.                     If iCount% > iMaxLength% Then
  516.                         bFinished = TRUE
  517.                     End If
  518.                 Else
  519.                     ' SPACE IS OCCUPIED
  520.                     ' SEE IF WE HAVE ANY OPEN SPACES TO MOVE TO
  521.                     iOpen% = 0
  522.                     If iZ% > 0 Then
  523.                         If arrMap(iX%, iY%, iZ% - 1).Typ = c_iMapType_Empty Then
  524.                             iOpen% = iOpen% + 1
  525.                         End If
  526.                     End If
  527.                     If iZ% < 32 Then
  528.                         If arrMap(iX%, iY%, iZ% + 1).Typ = c_iMapType_Empty Then
  529.                             iOpen% = iOpen% + 1
  530.                         End If
  531.                     End If
  532.                     If iX% > 0 Then
  533.                         If arrMap(iX% - 1, iY%, iZ%).Typ = c_iMapType_Empty Then
  534.                             iOpen% = iOpen% + 1
  535.                         End If
  536.                     End If
  537.                     If iX% < 32 Then
  538.                         If arrMap(iX% + 1, iY%, iZ%).Typ = c_iMapType_Empty Then
  539.                             iOpen% = iOpen% + 1
  540.                         End If
  541.                     End If
  542.                     If iY% > 0 Then
  543.                         If arrMap(iX%, iY% - 1, iZ%).Typ = c_iMapType_Empty Then
  544.                             iOpen% = iOpen% + 1
  545.                         End If
  546.                     End If
  547.                     If iY% < 32 Then
  548.                         If arrMap(iX%, iY% + 1, iZ%).Typ = c_iMapType_Empty Then
  549.                             iOpen% = iOpen% + 1
  550.                         End If
  551.                     End If
  552.                    
  553.                     ' QUIT IF NO OPEN SPACES AVAILABLE
  554.                     If iOpen% = 0 Then
  555.                         ' NOWHERE TO GO, EXIT
  556.                         bFinished = TRUE
  557.                     End If
  558.                 End If
  559.                
  560.             Loop Until bFinished = TRUE
  561.         End If
  562.  
  563.         ' PLOT GRAPHICS TO SCREEN
  564.         DrawIsometricScreen arrMap()
  565.        
  566.         Input "Type q to quit? ", in$
  567.        
  568.         If LCase$(in$) = LCase$("q") Then
  569.             bQuit = TRUE
  570.         End If
  571.        
  572.     Loop Until bQuit = TRUE
  573.    
  574.     Screen 0
  575.    
  576.     IsometricDemo1 = sResult
  577. End Function ' IsometricDemo1
  578.  
  579. ' /////////////////////////////////////////////////////////////////////////////
  580.  
  581. Function IsometricDemo2$
  582.     Dim RoutineName As String: RoutineName = "IsometricDemo2"
  583.     Dim sResult As String: sResult = ""
  584.     Dim arrMap(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapBlockType
  585.     Dim iX%
  586.     Dim iY%
  587.     Dim iZ%
  588.     Dim iNextX%
  589.     Dim iNextY%
  590.     Dim iNextZ%
  591.     Dim iPosX1%
  592.     Dim iPosX2%
  593.     Dim iPosY1%
  594.     Dim iPosY2%
  595.     Dim iLoopX%
  596.     Dim iLoopY%
  597.     Dim iLoopZ%
  598.     Dim iNextColor&
  599.     Dim iColorScheme%
  600.     Dim bContinue As Integer
  601.     Dim iDirection%
  602.     Dim bFinished As Integer
  603.     Dim iCount%
  604.     Dim iOpen%
  605.     Dim iMove%
  606.     Dim iSegmentLength%
  607.     Dim iMaxLength%
  608.     Dim bFirst As Integer
  609.     Dim bQuit As Integer
  610.     Dim in$
  611.    
  612.     ' INITIALIZE
  613.     'Screen _NewImage(1024, 720, 32) : _ScreenMove _Middle
  614.     Screen _NewImage(1280, 1024, 32)
  615.    
  616.     ' =============================================================================
  617.     ' MAIN LOOP
  618.     bQuit = FALSE
  619.     Do
  620.         Cls
  621.  
  622.         ' -----------------------------------------------------------------------------
  623.         ' INITIALIZE MAP TO EMPTY
  624.         ClearIsometricMap arrMap()
  625.        
  626.         ' -----------------------------------------------------------------------------
  627.         ' DRAW FLOOR
  628.         'For iLoopZ% = m_iMapMinZ To m_iMapMaxZ Step 8
  629.         For iLoopZ% = m_iMapMinZ To m_iMapMinZ
  630.             For iLoopX% = m_iMapMinX To m_iMapMaxX
  631.                 For iLoopY% = m_iMapMinY To m_iMapMaxY
  632.                     arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iMapType_Floor_Tiled
  633.                     arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1 = cGray&
  634.                     arrMap(iLoopX%, iLoopY%, iLoopZ%).Color2 = cLightGray&
  635.                 Next iLoopY%
  636.             Next iLoopX%
  637.         Next iLoopZ%
  638.        
  639.         ' -----------------------------------------------------------------------------
  640.         ' DRAW FRAME AROUND ENTIRE SPACE
  641.        
  642.         For iLoopZ% = m_iMapMinZ + 1 To m_iMapMaxZ
  643.             arrMap(m_iMapMinX, m_iMapMinY, iLoopZ%).Typ = c_iMapType_Wall
  644.             arrMap(m_iMapMinX, m_iMapMinY, iLoopZ%).Color1 = cRed&
  645.            
  646.             arrMap(m_iMapMaxX, m_iMapMinY, iLoopZ%).Typ = c_iMapType_Wall
  647.             arrMap(m_iMapMaxX, m_iMapMinY, iLoopZ%).Color1 = cBlue&
  648.            
  649.             arrMap(m_iMapMinX, m_iMapMaxY, iLoopZ%).Typ = c_iMapType_Wall
  650.             arrMap(m_iMapMinX, m_iMapMaxY, iLoopZ%).Color1 = cGreen&
  651.            
  652.             arrMap(m_iMapMaxX, m_iMapMaxY, iLoopZ%).Typ = c_iMapType_Wall
  653.             arrMap(m_iMapMaxX, m_iMapMaxY, iLoopZ%).Color1 = cYellow&
  654.         Next iLoopZ%
  655.        
  656.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  657.             arrMap(iLoopX%, m_iMapMinY, m_iMapMinZ + 1).Typ = c_iMapType_Wall
  658.             arrMap(iLoopX%, m_iMapMinY, m_iMapMinZ + 1).Color1 = cOrange&
  659.            
  660.             arrMap(iLoopX%, m_iMapMaxY, m_iMapMaxZ).Typ = c_iMapType_Wall
  661.             arrMap(iLoopX%, m_iMapMaxY, m_iMapMaxZ).Color1 = cPurple&
  662.            
  663.             arrMap(iLoopX%, m_iMapMaxY, m_iMapMinZ + 1).Typ = c_iMapType_Wall
  664.             arrMap(iLoopX%, m_iMapMaxY, m_iMapMinZ + 1).Color1 = cLime&
  665.            
  666.             arrMap(iLoopX%, m_iMapMinY, m_iMapMaxZ).Typ = c_iMapType_Wall
  667.             arrMap(iLoopX%, m_iMapMinY, m_iMapMaxZ).Color1 = cCyan&
  668.         Next iLoopX%
  669.        
  670.         For iLoopY% = m_iMapMinY To m_iMapMaxY
  671.             arrMap(m_iMapMinX, iLoopY%, m_iMapMinZ + 1).Typ = c_iMapType_Wall
  672.             arrMap(m_iMapMinX, iLoopY%, m_iMapMinZ + 1).Color1 = cDodgerBlue&
  673.            
  674.             arrMap(m_iMapMinX, iLoopY%, m_iMapMaxZ).Typ = c_iMapType_Wall
  675.             arrMap(m_iMapMinX, iLoopY%, m_iMapMaxZ).Color1 = cDeepPurple&
  676.            
  677.             arrMap(m_iMapMaxX, iLoopY%, m_iMapMinZ + 1).Typ = c_iMapType_Wall
  678.             arrMap(m_iMapMaxX, iLoopY%, m_iMapMinZ + 1).Color1 = cDarkRed&
  679.            
  680.             arrMap(m_iMapMaxX, iLoopY%, m_iMapMaxZ).Typ = c_iMapType_Wall
  681.             arrMap(m_iMapMaxX, iLoopY%, m_iMapMaxZ).Color1 = cGold&
  682.         Next iLoopY%
  683.        
  684.         ' -----------------------------------------------------------------------------
  685.         ' DRAW PIPES
  686.         If TRUE = TRUE Then
  687.             ' START POSITION
  688.             iX% = m_iMapMidX ' 30 ' RandomNumber(0, 32)
  689.             iY% = m_iMapMidY ' 28 ' RandomNumber(0, 32)
  690.             iZ% = m_iMapMidZ ' 1 ' 32
  691.            
  692.             ' LENGTH OF PIPES
  693.             iSegmentLength% = 8
  694.             iMaxLength% = 512
  695.            
  696.             ' START COLOR + DEFINE HOW COLOR CHANGES
  697.             iNextColor& = cRed&
  698.             iColorScheme% = 3 ' 0 = don't change, 2 = Rainbow18 #1, 10 = Rainbow18 #2, etc.
  699.            
  700.             ' INITIALIZE
  701.             bFirst = TRUE
  702.             iCount% = 0
  703.             iMove% = 0
  704.             bFinished = FALSE
  705.             Do
  706.                 iNextX% = iX%
  707.                 iNextY% = iY%
  708.                 iNextZ% = iZ%
  709.                
  710.                 ' CHANGE DIRECTION EVERY iSegmentLength% SPACES
  711.                 iMove% = iMove% + 1
  712.                 If iMove% > iSegmentLength% Then
  713.                     iMove% = 0
  714.                    
  715.                     ' PICK A DIRECTION
  716.                     If bFirst = TRUE Then
  717.                         ' MOVE UP FOR FIRST MOVE
  718.                         iDirection% = c_iDir_Up
  719.                         bFirst = FALSE
  720.                     Else
  721.                         ' PICK A RANDOM DIRECTION
  722.                         iDirection% = RandomNumber(c_iDir_Min, c_iDir_Max)
  723.                     End If
  724.                 End If
  725.                
  726.                 Select Case iDirection%
  727.                     Case c_iDir_Down:
  728.                         If iNextZ% > 0 Then
  729.                             iNextZ% = iNextZ% - 1
  730.                         End If
  731.                     Case c_iDir_Up:
  732.                         If iNextZ% < 32 Then
  733.                             iNextZ% = iNextZ% + 1
  734.                         End If
  735.                     Case c_iDir_Left:
  736.                         If iNextX% > 0 Then
  737.                             iNextX% = iNextX% - 1
  738.                         End If
  739.                     Case c_iDir_Right:
  740.                         If iNextX% < 32 Then
  741.                             iNextX% = iNextX% + 1
  742.                         End If
  743.                     Case c_iDir_Back:
  744.                         If iNextY% > 0 Then
  745.                             iNextY% = iNextY% - 1
  746.                         End If
  747.                     Case Else: ' c_iDir_Forward
  748.                         If iNextY% < 32 Then
  749.                             iNextY% = iNextY% + 1
  750.                         End If
  751.                 End Select
  752.                
  753.                 ' CHECK IF NEXT SPACE IS EMPTY
  754.                 If arrMap(iNextX%, iNextY%, iNextZ%).Typ = c_iMapType_Empty Then
  755.                     ' SPACE IS EMPTY
  756.                     ' DRAW HERE
  757.                    
  758.                     iCount% = iCount% + 1
  759.                     iX% = iNextX%
  760.                     iY% = iNextY%
  761.                     iZ% = iNextZ%
  762.                    
  763.                     ' GET NEXT COLOR AND DRAW BLOCK
  764.                     DoCycleColor iColorScheme%, iNextColor&
  765.                     arrMap(iX%, iY%, iZ%).Typ = c_iMapType_Wall
  766.                     arrMap(iX%, iY%, iZ%).Color1 = iNextColor&
  767.                    
  768.                     ' HAVE WE PLACED MAX # OF BLOCKS?
  769.                     If iCount% > iMaxLength% Then
  770.                         bFinished = TRUE
  771.                     End If
  772.                 Else
  773.                     ' SPACE IS OCCUPIED
  774.                     ' SEE IF WE HAVE ANY OPEN SPACES TO MOVE TO
  775.                     iOpen% = 0
  776.                     If iZ% > 0 Then
  777.                         If arrMap(iX%, iY%, iZ% - 1).Typ = c_iMapType_Empty Then
  778.                             iOpen% = iOpen% + 1
  779.                         End If
  780.                     End If
  781.                     If iZ% < 32 Then
  782.                         If arrMap(iX%, iY%, iZ% + 1).Typ = c_iMapType_Empty Then
  783.                             iOpen% = iOpen% + 1
  784.                         End If
  785.                     End If
  786.                     If iX% > 0 Then
  787.                         If arrMap(iX% - 1, iY%, iZ%).Typ = c_iMapType_Empty Then
  788.                             iOpen% = iOpen% + 1
  789.                         End If
  790.                     End If
  791.                     If iX% < 32 Then
  792.                         If arrMap(iX% + 1, iY%, iZ%).Typ = c_iMapType_Empty Then
  793.                             iOpen% = iOpen% + 1
  794.                         End If
  795.                     End If
  796.                     If iY% > 0 Then
  797.                         If arrMap(iX%, iY% - 1, iZ%).Typ = c_iMapType_Empty Then
  798.                             iOpen% = iOpen% + 1
  799.                         End If
  800.                     End If
  801.                     If iY% < 32 Then
  802.                         If arrMap(iX%, iY% + 1, iZ%).Typ = c_iMapType_Empty Then
  803.                             iOpen% = iOpen% + 1
  804.                         End If
  805.                     End If
  806.                    
  807.                     ' QUIT IF NO OPEN SPACES AVAILABLE
  808.                     If iOpen% = 0 Then
  809.                         ' NOWHERE TO GO, EXIT
  810.                         bFinished = TRUE
  811.                     End If
  812.                 End If
  813.                
  814.             Loop Until bFinished = TRUE
  815.         End If
  816.  
  817.         ' PLOT GRAPHICS TO SCREEN
  818.         DrawIsometricScreen arrMap()
  819.        
  820.         Input "Type q to quit? ", in$
  821.        
  822.         If LCase$(in$) = LCase$("q") Then
  823.             bQuit = TRUE
  824.         End If
  825.        
  826.     Loop Until bQuit = TRUE
  827.    
  828.     Screen 0
  829.    
  830.     IsometricDemo2 = sResult
  831. End Function ' IsometricDemo2
  832.  
  833. ' /////////////////////////////////////////////////////////////////////////////
  834.  
  835. Function IsometricDemo3$
  836.     Dim RoutineName As String: RoutineName = "IsometricDemo3"
  837.     Dim sResult As String: sResult = ""
  838.     Dim arrMap(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapBlockType
  839.     Dim iX%
  840.     Dim iY%
  841.     Dim iZ%
  842.     Dim iNewX%
  843.     Dim iNewY%
  844.     Dim iNewZ%
  845.     Dim iMyColor&
  846.     Dim iColorScheme%
  847.     Dim iDirection% ' direction player's nose is pointing
  848.     Dim bFound As Integer
  849.     Dim bDone As Integer
  850.     Dim in$
  851.     Dim iTotal% ' compute total available spaces
  852.     Dim iCount% ' count # of spaces searched
  853.     Dim bMoving As Integer
  854.     Dim iLastKey As Integer
  855.     Dim bMoved As Integer
  856.    
  857.     Dim iPosX1%
  858.     Dim iPosX2%
  859.     Dim iPosY1%
  860.     Dim iPosY2%
  861.     Dim iNextColor&
  862.     Dim bContinue As Integer
  863.     Dim iLoopX%
  864.     Dim iLoopY%
  865.     Dim iLoopZ%
  866.     Dim iLevelCount%
  867.     Dim iLevelSize%
  868.    
  869.     Dim iDrawX%
  870.     Dim iDrawY%
  871.    
  872.     ' =============================================================================
  873.     ' INITIALIZE
  874.     'Screen _NewImage(1024, 720, 32) : _ScreenMove _Middle
  875.     Screen _NewImage(1280, 1024, 32)
  876.    
  877.     ' -----------------------------------------------------------------------------
  878.     ' INITIALIZE MAP TO EMPTY
  879.     ClearIsometricMap arrMap()
  880.    
  881.     ' -----------------------------------------------------------------------------
  882.     ' DRAW FLOOR
  883.     For iLoopZ% = m_iMapMinZ To m_iMapMinZ
  884.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  885.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  886.                 arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iMapType_Floor_Tiled
  887.                 arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1 = cGray&
  888.                 arrMap(iLoopX%, iLoopY%, iLoopZ%).Color2 = cLightGray&
  889.             Next iLoopY%
  890.         Next iLoopX%
  891.     Next iLoopZ%
  892.  
  893.     ' -----------------------------------------------------------------------------
  894.     ' DRAW A TALL HOLLOW PYRAMID
  895.     If TRUE = TRUE Then
  896.         iX% = 5
  897.         iY% = 10
  898.         iZ% = 1
  899.         iLevelSize% = 4
  900.        
  901.         iPosX1% = iX%
  902.         iPosX2% = iX% + 7
  903.         iPosY1% = iY%
  904.         iPosY2% = iY% + 7
  905.         iNextColor& = cRed&
  906.         iColorScheme% = 1 ' 1 = Rainbow6 #1, 9 = Rainbow6 #2, etc.
  907.         iLevelCount% = 0
  908.        
  909.         bContinue = TRUE
  910.         Do
  911.             ' PLOT NEXT LEVEL
  912.             'For iLoopX% = iPosX1% To iPosX2%
  913.             '   For iLoopY% = iPosY1% To iPosY2%
  914.             '       arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iMapType_Wall
  915.             '       arrMap(iLoopX%, iLoopY%, iZ%).Color1 = iNextColor&
  916.             '   Next iLoopY%
  917.             'Next iLoopX%
  918.            
  919.             ' Draw front/back walls
  920.             For iLoopX% = iPosX1% To iPosX2%
  921.                 iLoopY% = iPosY1%
  922.                 arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iMapType_Wall
  923.                 arrMap(iLoopX%, iLoopY%, iZ%).Color1 = iNextColor&
  924.                 arrMap(iLoopX%, iLoopY%, iZ%).AlphaOverride = 255
  925.                
  926.                 iLoopY% = iPosY2%
  927.                 arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iMapType_Wall
  928.                 arrMap(iLoopX%, iLoopY%, iZ%).Color1 = iNextColor&
  929.                 arrMap(iLoopX%, iLoopY%, iZ%).AlphaOverride = 255
  930.             Next iLoopX%
  931.            
  932.             ' Draw left/right walls
  933.             For iLoopY% = iPosY1% To iPosY2%
  934.                 iLoopX% = iPosX1%
  935.                 arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iMapType_Wall
  936.                 arrMap(iLoopX%, iLoopY%, iZ%).Color1 = iNextColor&
  937.                 arrMap(iLoopX%, iLoopY%, iZ%).AlphaOverride = 255
  938.                
  939.                 iLoopX% = iPosX2%
  940.                 arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iMapType_Wall
  941.                 arrMap(iLoopX%, iLoopY%, iZ%).Color1 = iNextColor&
  942.                 arrMap(iLoopX%, iLoopY%, iZ%).AlphaOverride = 255
  943.             Next iLoopY%
  944.            
  945.             ' Add a door to middle of right wall
  946.             iX% = iPosX1% + ((iPosX2% - iPosX1%) \ 2)
  947.             arrMap(iX%, iPosY2%, iZ%).Typ = c_iMapType_Empty
  948.            
  949.             ' Add a door to middle of front wall
  950.             iY% = iPosY1% + ((iPosY2% - iPosY1%) \ 2)
  951.             arrMap(iPosX2%, iY%, iZ%).Typ = c_iMapType_Empty
  952.            
  953.             ' MOVE UP A LEVEL
  954.             iLevelCount% = iLevelCount% + 1
  955.             If iLevelCount% > iLevelSize% Then
  956.                 iLevelCount% = 0
  957.                 iPosX1% = iPosX1% + 1
  958.                 iPosX2% = iPosX2% - 1
  959.                 iPosY1% = iPosY1% + 1
  960.                 iPosY2% = iPosY2% - 1
  961.             End If
  962.            
  963.             ' QUIT AFTER WE REACH THE TOP
  964.             If (iPosX1% <= iPosX2%) And (iPosY1% <= iPosY2%) Then
  965.                 iZ% = iZ% + 1
  966.                 DoCycleColor iColorScheme%, iNextColor&
  967.                 If iZ% > m_iMapMaxZ Then
  968.                     bContinue = FALSE
  969.                 End If
  970.             Else
  971.                 bContinue = FALSE
  972.             End If
  973.            
  974.         Loop Until bContinue = FALSE
  975.     End If
  976.    
  977.     ' -----------------------------------------------------------------------------
  978.     ' DRAW FRAME AROUND ENTIRE SPACE (TOP)
  979.    
  980.     For iLoopX% = m_iMapMinX + 3 To m_iMapMaxX - 3
  981.         arrMap(iLoopX%, m_iMapMaxY - 3, m_iMapMaxZ).Typ = c_iMapType_Wall
  982.         arrMap(iLoopX%, m_iMapMaxY - 3, m_iMapMaxZ).Color1 = cPurple&
  983.        
  984.         arrMap(iLoopX%, m_iMapMinY + 3, m_iMapMaxZ).Typ = c_iMapType_Wall
  985.         arrMap(iLoopX%, m_iMapMinY + 3, m_iMapMaxZ).Color1 = cCyan&
  986.     Next iLoopX%
  987.    
  988.     For iLoopY% = m_iMapMinY + 3 To m_iMapMaxY - 3
  989.         arrMap(m_iMapMinX + 3, iLoopY%, m_iMapMaxZ).Typ = c_iMapType_Wall
  990.         arrMap(m_iMapMinX + 3, iLoopY%, m_iMapMaxZ).Color1 = cOrange&
  991.        
  992.         arrMap(m_iMapMaxX - 3, iLoopY%, m_iMapMaxZ).Typ = c_iMapType_Wall
  993.         arrMap(m_iMapMaxX - 3, iLoopY%, m_iMapMaxZ).Color1 = cLime&
  994.     Next iLoopY%
  995.    
  996.     ' -----------------------------------------------------------------------------
  997.     ' DRAW FRAME AROUND ENTIRE SPACE (MIDDLE)
  998.    
  999.     For iLoopX% = m_iMapMinX + 2 To m_iMapMaxX - 2
  1000.         arrMap(iLoopX%, m_iMapMaxY - 2, m_iMapMidZ).Typ = c_iMapType_Wall
  1001.         arrMap(iLoopX%, m_iMapMaxY - 2, m_iMapMidZ).Color1 = cDodgerBlue&
  1002.        
  1003.         arrMap(iLoopX%, m_iMapMinY + 2, m_iMapMidZ).Typ = c_iMapType_Wall
  1004.         arrMap(iLoopX%, m_iMapMinY + 2, m_iMapMidZ).Color1 = cDeepPurple&
  1005.     Next iLoopX%
  1006.    
  1007.     For iLoopY% = m_iMapMinY + 2 To m_iMapMaxY - 2
  1008.         arrMap(m_iMapMinX + 2, iLoopY%, m_iMapMidZ).Typ = c_iMapType_Wall
  1009.         arrMap(m_iMapMinX + 2, iLoopY%, m_iMapMidZ).Color1 = cDarkRed&
  1010.        
  1011.         arrMap(m_iMapMaxX - 2, iLoopY%, m_iMapMidZ).Typ = c_iMapType_Wall
  1012.         arrMap(m_iMapMaxX - 2, iLoopY%, m_iMapMidZ).Color1 = cGold&
  1013.     Next iLoopY%
  1014.    
  1015.     ' -----------------------------------------------------------------------------
  1016.     ' DRAW FRAME AROUND ENTIRE SPACE (BOTTOM)
  1017.    
  1018.     For iLoopX% = m_iMapMinX + 1 To m_iMapMaxX - 1
  1019.         arrMap(iLoopX%, m_iMapMaxY - 1, m_iMapMinZ + 1).Typ = c_iMapType_Wall
  1020.         arrMap(iLoopX%, m_iMapMaxY - 1, m_iMapMinZ + 1).Color1 = cSeaBlue&
  1021.        
  1022.         arrMap(iLoopX%, m_iMapMinY + 1, m_iMapMinZ + 1).Typ = c_iMapType_Wall
  1023.         arrMap(iLoopX%, m_iMapMinY + 1, m_iMapMinZ + 1).Color1 = cChartreuse&
  1024.     Next iLoopX%
  1025.    
  1026.     For iLoopY% = m_iMapMinY + 1 To m_iMapMaxY - 1
  1027.         arrMap(m_iMapMinX + 1, iLoopY%, m_iMapMinZ + 1).Typ = c_iMapType_Wall
  1028.         arrMap(m_iMapMinX + 1, iLoopY%, m_iMapMinZ + 1).Color1 = cOrangeRed&
  1029.        
  1030.         arrMap(m_iMapMaxX - 1, iLoopY%, m_iMapMinZ + 1).Typ = c_iMapType_Wall
  1031.         arrMap(m_iMapMaxX - 1, iLoopY%, m_iMapMinZ + 1).Color1 = cDeepSkyBlue&
  1032.     Next iLoopY%
  1033.    
  1034.     ' -----------------------------------------------------------------------------
  1035.     ' FIND START POSITION
  1036.     iX% = RandomNumber(m_iMapMinX, m_iMapMaxX)
  1037.     iY% = RandomNumber(m_iMapMinY, m_iMapMaxY)
  1038.     iZ% = 1 ' RandomNumber(m_iMapMinZ, m_iMapMaxZ)
  1039.    
  1040.     ' MAKE SURE IT'S EMPTY
  1041.     If arrMap(iX%, iY%, iZ%).Typ = c_iMapType_Empty Then
  1042.         bFound = TRUE
  1043.     Else
  1044.         ' IF NOT EMPTY THEN TRY TO FIND AN EMPTY SPOT
  1045.         iTotal% = ((m_iMapMaxX - m_iMapMinX) + 1) * ((m_iMapMaxY - m_iMapMinY) + 1) * ((m_iMapMaxZ - m_iMapMinZ) + 1)
  1046.         iCount% = 0
  1047.         bFound = FALSE
  1048.         Do
  1049.             iX% = iX% + 1
  1050.             If iX% > m_iMapMaxX Then
  1051.                 ' reset x and move to next y
  1052.                 iX% = m_iMapMinX
  1053.                 iY% = iY% + 1
  1054.                 If iY% > m_iMapMaxY Then
  1055.                     ' reset y and move to next z
  1056.                     iY% = m_iMapMinY
  1057.                     iZ% = iZ% + 1
  1058.                     If iZ% > m_iMapMaxZ Then
  1059.                         ' RESET Z AND SEE IF WE HAVE CHECKED EVERYTHING
  1060.                         iZ% = m_iMapMinZ
  1061.                         iCount% = iCount% + 1
  1062.                         If iCount% >= iTotal% Then
  1063.                             ' NONE FOUND, EXIT
  1064.                             Exit Do
  1065.                         End If
  1066.                     Else
  1067.                         iCount% = iCount% + 1
  1068.                     End If
  1069.                 Else
  1070.                     iCount% = iCount% + 1
  1071.                 End If
  1072.             Else
  1073.                 iCount% = iCount% + 1
  1074.             End If
  1075.             If arrMap(iX%, iY%, iZ%).Typ = c_iMapType_Empty Then
  1076.                 ' FOUND AN EMPTY SPACE, EXIT
  1077.                 bFound = TRUE
  1078.                 Exit Do
  1079.             End If
  1080.         Loop
  1081.     End If
  1082.    
  1083.     If bFound = TRUE Then
  1084.         ' PLACE PLAYER
  1085.         iMyColor& = cRed&
  1086.         iColorScheme% = 2
  1087.        
  1088.         ' PICK A DIRECTION (SIMPLE FOR NOW, LEFT OR RIGHT)
  1089.         If iX% <= m_iMapMidX Then
  1090.             iDirection% = c_iDir_Right
  1091.         Else
  1092.             iDirection% = c_iDir_Left
  1093.         End If
  1094.        
  1095.         ' RESET MOVEMENT VARIABLES
  1096.         bMoving = FALSE
  1097.         bMoved = FALSE
  1098.        
  1099.         ' RESET INPUT
  1100.         While _DeviceInput(1): Wend ' clear and update the keyboard buffer
  1101.         iLastKey = c_iKeyDown_Enter
  1102.        
  1103.         ' DRAW PLAYER
  1104.         arrMap(iX%, iY%, iZ%).Typ = c_iMapType_Player1 ' c_iMapType_Wall
  1105.         arrMap(iX%, iY%, iZ%).Color1 = iMyColor&
  1106.         arrMap(iX%, iY%, iZ%).AlphaOverride = 255
  1107.        
  1108.         ' =============================================================================
  1109.         ' MAIN LOOP
  1110.         bFinished = FALSE
  1111.         Do
  1112.             ' PLOT GRAPHICS TO SCREEN
  1113.             Cls ' is cls necessary?
  1114.             ComputeVisible arrMap(), iX%, iY%, iZ%
  1115.             DrawIsometricScreen arrMap()
  1116.            
  1117.             ' SHOW INSTRUCTIONS / COORDINATES ON SCREEN
  1118.             Locate 1, 1: Print "IsometricDemo3"
  1119.             Locate 3, 1: Print "CRSR RIGHT/LEFT MOVES X=" + cstr$(iX%)
  1120.             Locate 4, 1: Print "CRSR UP   /DOWN MOVES Y=" + cstr$(iY%)
  1121.             Locate 5, 1: Print "PAGE UP   /DOWN MOVES Z=" + cstr$(iZ%)
  1122.             Locate 7, 1: Print "SPACE TOGGLES CONTINUOUS MOVEMENT"
  1123.             Locate 9, 1: Print "PRESS <ESC> TO QUIT"
  1124.            
  1125.             ' SHOW 2D MINI MAP ON SCREEN
  1126.             For iLoopX% = m_iMapMinX To m_iMapMaxX
  1127.                 For iLoopY% = m_iMapMinY To m_iMapMaxY
  1128.                     iDrawX% = (iLoopX% * 4) + 20
  1129.                     iDrawY% = (iLoopY% * 4) + 200
  1130.                     If arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iMapType_Wall Then
  1131.                         DrawBox iDrawX%, iDrawY%, 4, arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1132.                        
  1133.                     ElseIf arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iMapType_Player1 Then
  1134.                         DrawBox iDrawX%, iDrawY%, 4, arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1135.                        
  1136.                     Else
  1137.                         DrawBox iDrawX%, iDrawY%, 4, cBlack&
  1138.                     End If
  1139.                 Next iLoopY%
  1140.             Next iLoopX%
  1141.            
  1142.             ' GET KEYBOARD INPUT
  1143.             If _KeyDown(c_iKeyDown_Up) Then
  1144.                 If iLastKey <> c_iKeyDown_Up Then
  1145.                     iLastKey = c_iKeyDown_Up
  1146.                     iDirection% = c_iDir_Back
  1147.                     bMoved = TRUE
  1148.                 End If
  1149.             ElseIf _KeyDown(c_iKeyDown_Down) Then
  1150.                 If iLastKey <> c_iKeyDown_Down Then
  1151.                     iLastKey = c_iKeyDown_Down
  1152.                     iDirection% = c_iDir_Forward
  1153.                     bMoved = TRUE
  1154.                 End If
  1155.             ElseIf _KeyDown(c_iKeyDown_Left) Then
  1156.                 If iLastKey <> c_iKeyDown_Left Then
  1157.                     iLastKey = c_iKeyDown_Left
  1158.                     iDirection% = c_iDir_Left
  1159.                     bMoved = TRUE
  1160.                 End If
  1161.             ElseIf _KeyDown(c_iKeyDown_Right) Then
  1162.                 If iLastKey <> c_iKeyDown_Right Then
  1163.                     iLastKey = c_iKeyDown_Right
  1164.                     iDirection% = c_iDir_Right
  1165.                     bMoved = TRUE
  1166.                 End If
  1167.             ElseIf _KeyDown(c_iKeyDown_PgUp) Then
  1168.                 If iLastKey <> c_iKeyDown_PgUp Then
  1169.                     iLastKey = c_iKeyDown_PgUp
  1170.                     iDirection% = c_iDir_Up
  1171.                     bMoved = TRUE
  1172.                 End If
  1173.             ElseIf _KeyDown(c_iKeyDown_PgDn) Then
  1174.                 If iLastKey <> c_iKeyDown_PgDn Then
  1175.                     iLastKey = c_iKeyDown_PgDn
  1176.                     iDirection% = c_iDir_Down
  1177.                     bMoved = TRUE
  1178.                 End If
  1179.             ElseIf _KeyDown(c_iKeyDown_Spacebar) Then
  1180.                 If iLastKey <> c_iKeyDown_Spacebar Then
  1181.                     iLastKey = c_iKeyDown_Spacebar
  1182.                     'bMoving = IIF(bMoving, False, True)
  1183.                     If bMoving = TRUE Then
  1184.                         bMoving = FALSE
  1185.                     Else
  1186.                         bMoving = TRUE
  1187.                     End If
  1188.                 End If
  1189.             ElseIf _KeyDown(c_iKeyDown_Esc) Then
  1190.                 Exit Do
  1191.             Else
  1192.                 iLastKey = -1
  1193.             End If
  1194.            
  1195.             ' --------------------------------------------------------------------------------
  1196.             ' ERASE OLD POSITION
  1197.             ' --------------------------------------------------------------------------------
  1198.             arrMap(iX%, iY%, iZ%).Typ = c_iMapType_Empty
  1199.             arrMap(iX%, iY%, iZ%).Color1 = cEmpty&
  1200.             arrMap(iX%, iY%, iZ%).AlphaOverride = 255
  1201.            
  1202.             ' --------------------------------------------------------------------------------
  1203.             ' MOVE PLAYER BASED ON DIRECTION
  1204.             ' --------------------------------------------------------------------------------
  1205.             'IF bMoved=TRUE THEN
  1206.             If bMoving = TRUE Or bMoved = TRUE Then
  1207.                 bMoved = FALSE
  1208.                
  1209.                 Select Case iDirection%
  1210.                     Case c_iDir_Down:
  1211.                         iNewX% = iX%
  1212.                         iNewY% = iY%
  1213.                         iNewZ% = iZ% - 1
  1214.                         If iNewZ% < m_iMapMinZ Then
  1215.                             iNewZ% = m_iMapMaxZ
  1216.                         End If
  1217.                         If arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iMapType_Empty Then
  1218.                             iDirection% = c_iDir_Up
  1219.                             iNewZ% = iZ%
  1220.                         End If
  1221.                        
  1222.                     Case c_iDir_Up:
  1223.                         iNewX% = iX%
  1224.                         iNewY% = iY%
  1225.                         iNewZ% = iZ% + 1
  1226.                         If iNewZ% > m_iMapMaxZ Then
  1227.                             iNewZ% = m_iMapMinZ
  1228.                         End If
  1229.                         If arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iMapType_Empty Then
  1230.                             iDirection% = c_iDir_Down
  1231.                             iNewZ% = iZ%
  1232.                         End If
  1233.                        
  1234.                     Case c_iDir_Left:
  1235.                         iNewX% = iX% - 1
  1236.                         iNewY% = iY%
  1237.                         iNewZ% = iZ%
  1238.                         If iNewX% < m_iMapMinX Then
  1239.                             iNewX% = m_iMapMaxX
  1240.                         End If
  1241.                         If arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iMapType_Empty Then
  1242.                             iDirection% = c_iDir_Right
  1243.                             iNewX% = iX%
  1244.                         End If
  1245.                        
  1246.                     Case c_iDir_Right:
  1247.                         iNewX% = iX% + 1
  1248.                         iNewY% = iY%
  1249.                         iNewZ% = iZ%
  1250.                         If iNewX% > m_iMapMaxX Then
  1251.                             iNewX% = m_iMapMinX
  1252.                         End If
  1253.                         If arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iMapType_Empty Then
  1254.                             iDirection% = c_iDir_Left
  1255.                             iNewX% = iX%
  1256.                         End If
  1257.                        
  1258.                     Case c_iDir_Back:
  1259.                         iNewX% = iX%
  1260.                         iNewY% = iY% - 1
  1261.                         iNewZ% = iZ%
  1262.                         If iNewY% < m_iMapMinY Then
  1263.                             iNewY% = m_iMapMaxY
  1264.                         End If
  1265.                         If arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iMapType_Empty Then
  1266.                             iDirection% = c_iDir_Forward
  1267.                             iNewY% = iY%
  1268.                         End If
  1269.                        
  1270.                     Case c_iDir_Forward:
  1271.                         iNewX% = iX%
  1272.                         iNewY% = iY% + 1
  1273.                         iNewZ% = iZ%
  1274.                         If iNewY% > m_iMapMaxY Then
  1275.                             iNewY% = m_iMapMinY
  1276.                         End If
  1277.                         If arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iMapType_Empty Then
  1278.                             iDirection% = c_iDir_Back
  1279.                             iNewY% = iY%
  1280.                         End If
  1281.                        
  1282.                     Case Else:
  1283.                         'iNewX% = iX%
  1284.                         'iNewY% = iY%
  1285.                         'iNewZ% = iZ%
  1286.                 End Select
  1287.                
  1288.                 ' SAVE NEW POSITION
  1289.                 iX% = iNewX%
  1290.                 iY% = iNewY%
  1291.                 iZ% = iNewZ%
  1292.             End If
  1293.            
  1294.             ' REDRAW AT CURRENT POSITION
  1295.             DoCycleColor iColorScheme%, iMyColor&
  1296.             arrMap(iX%, iY%, iZ%).Typ = c_iMapType_Player1 ' c_iMapType_Wall
  1297.             arrMap(iX%, iY%, iZ%).Color1 = iMyColor&
  1298.             arrMap(iX%, iY%, iZ%).AlphaOverride = 255
  1299.            
  1300.             _Limit 30
  1301.             _Display
  1302.        
  1303.         Loop
  1304.     Else
  1305.         sResult = "Could not find an empty space to start player."
  1306.     End If
  1307.    
  1308.     ' FINISH UP AND EXIT
  1309.     While _DeviceInput(1): Wend ' clear and update the keyboard buffer
  1310.     Screen 0
  1311.     IsometricDemo3$ = sResult
  1312. End Function ' IsometricDemo3
  1313.  
  1314. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1315. ' BEGIN GRAPHICS FUNCTIONS
  1316. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1317.  
  1318. ' =============================================================================
  1319. ' LET'S GET THE COORDINATES STRAIGHT!
  1320. ' Coordinates are arrMap(x,y,z)
  1321. '           ________________
  1322. '          /|e            /|e
  1323. '         / |            / |
  1324. '        /  |           /  |z-axis
  1325. '       /   |          /   |
  1326. '      /    /---------/----/
  1327. '     /    / a       /   b/
  1328. '    /    /         /    /
  1329. '   |--------------|    /
  1330. '   |f  /         g|   / y-axis
  1331. '   |  /           |  /
  1332. '   | /            | /
  1333. '   |/c           d|/
  1334. '   ----------------
  1335. '      x-axis
  1336. '
  1337. ' POINT    ( X, Y, Z)
  1338. ' a        ( 0, 0, 0)
  1339. ' b        (32, 0, 0)
  1340. ' c        ( 0,32, 0)
  1341. ' d        (32,32, 0)
  1342. ' e        ( 0, 0,32)
  1343. ' f        ( 0,32,32)
  1344. ' g        (32,32,32)
  1345. ' =============================================================================
  1346.  
  1347. ' /////////////////////////////////////////////////////////////////////////////
  1348. ' INITIALIZE MAP TO EMPTY
  1349.  
  1350. 'ClearIsometricMap arrMap()
  1351. Sub ClearIsometricMap (arrMap( m_iMapMinX To m_iMapMaxX , m_iMapMinY To m_iMapMaxY , m_iMapMinZ To m_iMapMaxZ) As MapBlockType)
  1352.     Dim RoutineName As String: RoutineName = "ClearIsometricMap"
  1353.     Dim iLoopX%
  1354.     Dim iLoopY%
  1355.     Dim iLoopZ%
  1356.    
  1357.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  1358.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  1359.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  1360.                 arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iMapType_Empty
  1361.                 arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1362.             Next iLoopY%
  1363.         Next iLoopX%
  1364.     Next iLoopZ%
  1365. End Sub ' ClearIsometricMap
  1366.  
  1367.  
  1368. ' /////////////////////////////////////////////////////////////////////////////
  1369. ' Determine which squares are visible in isometric map
  1370.  
  1371. ' arrMap(x,y,z) = 3D array map of world
  1372. ' iX% = player's X positon
  1373. ' iY% = player's Y position
  1374. ' iZ% = player's Z position
  1375.  
  1376. Sub ComputeVisible (arrMap( m_iMapMinX To m_iMapMaxX , m_iMapMinY To m_iMapMaxY , m_iMapMinZ To m_iMapMaxZ) As MapBlockType, iX%, iY%, iZ%)
  1377.     Dim iLoopX%
  1378.     Dim iLoopY%
  1379.     Dim iLoopZ%
  1380.    
  1381.     Dim iPX1%
  1382.     Dim iPY1%
  1383.     Dim iPZ1%
  1384.     Dim iPlayer2Dx As Integer
  1385.     Dim iPlayer2Dy As Integer
  1386.     Dim iBrick2Dx As Integer
  1387.     Dim iBrick2Dy As Integer
  1388.    
  1389.     ' CALCULATE PLAYER'S 2-D POSITION
  1390.     iPX1% = iX% * m_iGridSize + cGridOffsetX
  1391.     iPY1% = iY% * m_iGridSize + cGridOffsetY
  1392.     iPZ1% = iZ% * m_iGridSize + cGridOffsetZ
  1393.     iPlayer2Dx = CX2I(iPX1%, iPY1%) + cScreenOffsetX
  1394.     iPlayer2Dy = (CY2I(iPX1%, iPY1%) + cScreenOffsetY) - iPZ1%
  1395.     'fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, _RGB32(r, g, b, alpha&)
  1396.    
  1397.     For iLoopX% = m_iMapMinX To m_iMapMaxX
  1398.         For iLoopY% = m_iMapMinY To m_iMapMaxY
  1399.             For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  1400.                 ' If space has a brick
  1401.                 ' and its 2D (X,Y) is > Player's 2D (X,Y)
  1402.                 ' then make the brick transparent
  1403.                 If arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iMapType_Wall Then
  1404.                     ' CALCULATE BRICK'S 2-D POSITION
  1405.                     iPX1% = iLoopX% * m_iGridSize + cGridOffsetX
  1406.                     iPY1% = iLoopY% * m_iGridSize + cGridOffsetY
  1407.                     iPZ1% = iLoopZ% * m_iGridSize + cGridOffsetZ
  1408.                     iBrick2Dx = CX2I(iPX1%, iPY1%) + cScreenOffsetX
  1409.                     iBrick2Dy = (CY2I(iPX1%, iPY1%) + cScreenOffsetY) - iPZ1%
  1410.                     'fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, _RGB32(r, g, b, alpha&)
  1411.                    
  1412.                     'If iLoopZ% >= iZ% Then
  1413.                     'If iLoopX% >= iX% Then
  1414.                     If iLoopY% > iY% Then
  1415.                         If (iPlayer2Dy >= (iBrick2Dy - m_iGridSize)) And (iPlayer2Dy <= (iBrick2Dy + m_iGridSize)) Then
  1416.                             If (iPlayer2Dx >= (iBrick2Dx - m_iGridSize)) And (iPlayer2Dx <= (iBrick2Dx + m_iGridSize)) Then
  1417.                                 arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 86
  1418.                             Else
  1419.                                 arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1420.                             End If
  1421.                         Else
  1422.                             arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1423.                         End If
  1424.                     End If
  1425.                     'End If
  1426.                     'End If
  1427.                 Else
  1428.                     arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1429.                 End If
  1430.             Next iLoopZ%
  1431.         Next iLoopY%
  1432.     Next iLoopX%
  1433. End Sub ' ComputeVisible
  1434.  
  1435. ' /////////////////////////////////////////////////////////////////////////////
  1436. ' Draw the map in 3D Isometic Perspective
  1437.  
  1438. ' Parameters:
  1439. ' arrMap(x,y,z) = 3D array map of world
  1440. ' iX% = player's X positon
  1441. ' iY% = player's Y position
  1442. ' iZ% = player's Z position
  1443.  
  1444. 'DrawIsometricScreen arrMap()
  1445. Sub DrawIsometricScreen (arrMap( m_iMapMinX To m_iMapMaxX , m_iMapMinY To m_iMapMaxY , m_iMapMinZ To m_iMapMaxZ) As MapBlockType)
  1446.     Dim RoutineName As String: RoutineName = "DrawIsometricScreen"
  1447.     Dim bTile As Integer
  1448.     Dim iLoopX%
  1449.     Dim iLoopY%
  1450.     Dim iLoopZ%
  1451.     Dim iColor As _Unsigned Long
  1452.     Dim iPosX1%
  1453.     Dim iPosX2%
  1454.     Dim iPosY1%
  1455.     Dim iPosY2%
  1456.     Dim iPosZ1%
  1457.     Dim alpha&
  1458.    
  1459.     alpha& = 255
  1460.     bTile = FALSE
  1461.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  1462.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  1463.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  1464.                
  1465.                 ' CALCULATE POSITION
  1466.                 iPosZ1% = iLoopZ% * m_iGridSize + cGridOffsetZ
  1467.                 iPosX1% = iLoopX% * m_iGridSize + cGridOffsetX
  1468.                 iPosY1% = iLoopY% * m_iGridSize + cGridOffsetY
  1469.                 iPosX2% = iPosX1% + m_iGridSize
  1470.                 iPosY2% = iPosY1% + m_iGridSize
  1471.                
  1472.                 ' DETERMINE COLOR
  1473.                 If arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iMapType_Floor_Tiled Then
  1474.                     If bTile = TRUE Then
  1475.                         iColor = arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  1476.                         bTile = FALSE
  1477.                     Else
  1478.                         iColor = arrMap(iLoopX%, iLoopY%, iLoopZ%).Color2
  1479.                         bTile = TRUE
  1480.                     End If
  1481.                 ElseIf arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iMapType_Wall Then
  1482.                     iColor = arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  1483.                     alpha& = arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride
  1484.                    
  1485.                 ElseIf arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iMapType_Player1 Then
  1486.                     iColor = arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  1487.                     alpha& = 255
  1488.                    
  1489.                 ElseIf arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iMapType_Player2 Then
  1490.                     iColor = arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  1491.                     alpha& = 255
  1492.                    
  1493.                 ElseIf arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iMapType_Water Then
  1494.                     'TODO: transparent for water
  1495.                     iColor = cEmpty&
  1496.                     alpha& = 64
  1497.                    
  1498.                 ElseIf arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iMapType_Window Then
  1499.                     'TODO: transparent for windows
  1500.                     iColor = cEmpty&
  1501.                     alpha& = 64
  1502.                    
  1503.                 Else
  1504.                     iColor = cEmpty&
  1505.                 End If
  1506.                
  1507.                 ' PLOT NEXT BLOCK
  1508.                 If iColor <> cEmpty& Then
  1509.                     'IsoLine3D(x,      y,       x2,      y2,      z,       iHeight,     xoffset,        yoffset,        iColor As _Unsigned Long, alpha&)
  1510.                     IsoLine3D iPosX1%, iPosY1%, iPosX2%, iPosY2%, iPosZ1%, m_iGridSize, cScreenOffsetX, cScreenOffsetY, iColor, alpha&
  1511.                 End If
  1512.                
  1513.             Next iLoopY%
  1514.         Next iLoopX%
  1515.     Next iLoopZ%
  1516.    
  1517. End Sub ' DrawIsometricScreen
  1518.  
  1519. ' /////////////////////////////////////////////////////////////////////////////
  1520. ' RETURNS MAP AS TEXT
  1521.  
  1522. 'Input "See a text dump (y/n)? ", in$
  1523. 'If LCase$(in$) = LCase$("y") Then
  1524. '    Print MapToText$( arrMap() )
  1525. 'End If
  1526. Function MapToText$ (arrMap( m_iMapMinX To m_iMapMaxX , m_iMapMinY To m_iMapMaxY , m_iMapMinZ To m_iMapMaxZ) As MapBlockType)
  1527.     Dim RoutineName As String: RoutineName = "MapToText$"
  1528.     Dim sResult As String
  1529.     Dim iLoopX%
  1530.     Dim iLoopY%
  1531.     Dim iLoopZ%
  1532.     Dim iMinX%
  1533.     Dim iMaxX%
  1534.     Dim iMinY%
  1535.     Dim iMaxY%
  1536.     Dim iMinZ%
  1537.     Dim iMaxZ%
  1538.     Dim sLine As String
  1539.     Dim iType%
  1540.     Dim iColor1&
  1541.     Dim iColor2&
  1542.     Dim iColor3&
  1543.     Dim in$
  1544.  
  1545.     sResult = ""
  1546.  
  1547.     ' FIND USED BOUNDARIES OF MAP
  1548.     iMinX% = -1
  1549.     iMaxX% = -1
  1550.     iMinY% = -1
  1551.     iMaxY% = -1
  1552.     iMinZ% = -1
  1553.     iMaxZ% = -1
  1554.     For iLoopZ% = 0 To 32
  1555.         For iLoopX% = 0 To 32
  1556.             For iLoopY% = 0 To 32
  1557.                 iType% = arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ
  1558.                 If iType% <> c_iMapType_Empty And iType% <> c_iMapType_Floor_Tiled Then
  1559.                     If iMinX% = -1 Then
  1560.                         iMinX% = iLoopX%
  1561.                     End If
  1562.                     If iMinY% = -1 Then
  1563.                         iMinY% = iLoopY%
  1564.                     End If
  1565.                     If iMinZ% = -1 Then
  1566.                         iMinZ% = iLoopZ%
  1567.                     End If
  1568.                     If iLoopX% > iMaxX% Then
  1569.                         iMaxX% = iLoopX%
  1570.                     End If
  1571.                     If iLoopY% > iMaxY% Then
  1572.                         iMaxY% = iLoopY%
  1573.                     End If
  1574.                     If iLoopZ% > iMaxZ% Then
  1575.                         iMaxZ% = iLoopZ%
  1576.                     End If
  1577.                 End If
  1578.             Next iLoopY%
  1579.         Next iLoopX%
  1580.     Next iLoopZ%
  1581.  
  1582.     ' GENERATE OUTPUT
  1583.     For iLoopZ% = iMinZ% To iMaxZ%
  1584.         sResult = sResult + "-------------------------------------------------------------------------------" + Chr$(13)
  1585.         sResult = sResult + "Map Z=" + cstr$(iLoopZ%) + ":" + Chr$(13)
  1586.         sResult = sResult + "-------------------------------------------------------------------------------" + Chr$(13)
  1587.         For iLoopY% = iMinY% To iMaxY%
  1588.             sLine = ""
  1589.             For iLoopX% = iMinX% To iMaxX%
  1590.                 iType% = arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ
  1591.                 iColor1& = arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  1592.                 iColor2& = arrMap(iLoopX%, iLoopY%, iLoopZ%).Color2
  1593.                 iColor3& = arrMap(iLoopX%, iLoopY%, iLoopZ%).Color3
  1594.                
  1595.                 If iType% = c_iMapType_Empty Then
  1596.                     sLine = sLine + " "
  1597.                 Else
  1598.                     If iColor1& = cEmpty& Then
  1599.                         sLine = sLine + " "
  1600.                     Else
  1601.                         sLine = sLine + "#"
  1602.                     End If
  1603.                 End If
  1604.             Next iLoopX%
  1605.             sResult = sResult + sLine + Chr$(13)
  1606.         Next iLoopY%
  1607.  
  1608.         sResult = sResult + Chr$(13)
  1609.     Next iLoopZ%
  1610.  
  1611.     MapToText$ = sResult
  1612. End Function ' MapToText$
  1613.  
  1614. ' /////////////////////////////////////////////////////////////////////////////
  1615.  
  1616. Function CX2I (x As Long, y As Long) 'Convert Cartesian X To Isometic coordinates
  1617.     CX2I = x - y
  1618. End Function ' CX2I
  1619.  
  1620. ' /////////////////////////////////////////////////////////////////////////////
  1621.  
  1622. Function CY2I (x As Long, y As Long) 'Convert Cartesian Y To Isometic coordinates
  1623.     CY2I = (x + y) / 2
  1624. End Function ' CY2I
  1625.  
  1626. ' /////////////////////////////////////////////////////////////////////////////
  1627. ' since we're drawing a diamond and not a square box, we can't use Line BF.
  1628. ' We have to manually down the 4 points of the line.
  1629.  
  1630. Sub IsoLine (x, y, x2, y2, xoffset, yoffset, iColor As _Unsigned Long)
  1631.     Line (CX2I(x, y) + xoffset, CY2I(x, y) + yoffset)-(CX2I(x2, y) + xoffset, CY2I(x2, y) + yoffset), iColor
  1632.     Line -(CX2I(x2, y2) + xoffset, CY2I(x2, y2) + yoffset), iColor
  1633.     Line -(CX2I(x, y2) + xoffset, CY2I(x, y2) + yoffset), iColor
  1634.     Line -(CX2I(x, y) + xoffset, CY2I(x, y) + yoffset), iColor
  1635.     Paint (CX2I(x, y) + xoffset, CY2I(x, y) + 4), iColor 'and fill the diamond solid
  1636.     Line (CX2I(x, y) + xoffset, CY2I(x, y) + yoffset)-(CX2I(x2, y) + xoffset, CY2I(x2, y) + yoffset), &HFFFFFFFF
  1637.     Line -(CX2I(x2, y2) + xoffset, CY2I(x2, y2) + yoffset), &HFFFFFFFF
  1638.     Line -(CX2I(x, y2) + xoffset, CY2I(x, y2) + yoffset), &HFFFFFFFF
  1639.     Line -(CX2I(x, y) + xoffset, CY2I(x, y) + yoffset), &HFFFFFFFF
  1640. End Sub ' IsoLine
  1641.  
  1642. ' /////////////////////////////////////////////////////////////////////////////
  1643. ' Like IsoLine, we're going to have to draw our lines manually.
  1644. ' only in this case, we also need a Z coordinate to tell us how
  1645. ' THICK/TALL/HIGH to make our tile
  1646.  
  1647. ' MODIFIED by madscijr to draw a single block of height iHeight at Z axis
  1648. ' MODIFIED by madscijr to accept an alpha& value to control transparency (where 0=fully transparent, 255=opaque)
  1649.  
  1650. ''Sub IsoLine3D (x, y, x2, y2, z, xoffset, yoffset, iColor As _Unsigned Long)
  1651. 'Sub IsoLine3D (x, y, x2, y2, z, iHeight, xoffset, yoffset, iColor As _Unsigned Long)
  1652. Sub IsoLine3D (x, y, x2, y2, z, iHeight, xoffset, yoffset, iColor As _Unsigned Long, alpha&)
  1653.     Dim r As Integer
  1654.     Dim g As Integer
  1655.     Dim b As Integer
  1656.     'dim iNewColor As _Unsigned Long
  1657.    
  1658.     r = _Red32(iColor)
  1659.     g = _Green32(iColor)
  1660.     b = _Blue32(iColor)
  1661.    
  1662.     ' Let's just do all the math first this time.
  1663.     ' We need to turn those 4 normal points into 4 isometric points (x, y, x1, y1)
  1664.     TempX1 = CX2I(x, y) + xoffset
  1665.     TempY1 = CY2I(x, y) + yoffset
  1666.     TempX2 = CX2I(x2, y) + xoffset
  1667.     TempY2 = CY2I(x2, y) + yoffset
  1668.     TempX3 = CX2I(x2, y2) + xoffset
  1669.     TempY3 = CY2I(x2, y2) + yoffset
  1670.     TempX4 = CX2I(x, y2) + xoffset
  1671.     TempY4 = CY2I(x, y2) + yoffset
  1672.    
  1673.     ' The top
  1674.     'fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, iColor
  1675.     fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, _RGB32(r, g, b, alpha&)
  1676.    
  1677.     If z <> 0 Then
  1678.         ' TODO: maybe change which sides gets shaded depending on the direction of the light source?
  1679.        
  1680.         ' draw the left side, shaded 75%
  1681.         'fquad TempX4, TempY4 - z, TempX4, TempY4 - z + iHeight, TempX3, TempY3 - z + iHeight, TempX3, TempY3 - z, _RGB32(.75 * r, .75 * g, .75 * b)
  1682.         fquad TempX4, TempY4 - z, TempX4, TempY4 - z + iHeight, TempX3, TempY3 - z + iHeight, TempX3, TempY3 - z, _RGB32(.75 * r, .75 * g, .75 * b, alpha&)
  1683.        
  1684.         ' draw the right side,s haded 50%
  1685.         'fquad TempX3, TempY3 - z, TempX3, TempY3 - z + iHeight, TempX2, TempY2 - z + iHeight, TempX2, TempY2 - z, _RGB32(.5 * r, .5 * g, .5 * b)
  1686.         fquad TempX3, TempY3 - z, TempX3, TempY3 - z + iHeight, TempX2, TempY2 - z + iHeight, TempX2, TempY2 - z, _RGB32(.5 * r, .5 * g, .5 * b, alpha&)
  1687.     Else
  1688.         ' no need to draw any height, if there isn't any.
  1689.     End If
  1690. End Sub ' IsoLine3D
  1691.  
  1692. ' /////////////////////////////////////////////////////////////////////////////
  1693. ' found at abandoned, outdated and now likely malicious qb64 dot net website
  1694. ' don’t go there: http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index.php?topic=14425.0
  1695.  
  1696. Sub ftri (x1, y1, x2, y2, x3, y3, K As _Unsigned Long)
  1697.     Dim D As Long
  1698.     Dim a&
  1699.  
  1700.     D = _Dest
  1701.     a& = _NewImage(1, 1, 32)
  1702.     _Dest a&
  1703.     PSet (0, 0), K
  1704.     _Dest D
  1705.     _MapTriangle _Seamless(0, 0)-(0, 0)-(0, 0), a& To(x1, y1)-(x2, y2)-(x3, y3)
  1706.     _FreeImage a& ' <<< this is important!
  1707. End Sub ' ftri
  1708.  
  1709. ' /////////////////////////////////////////////////////////////////////////////
  1710. ' 2019-11-20 Steve saves some time with STATIC
  1711. ' and saves and restores last dest
  1712.  
  1713. Sub ftri1 (x1, y1, x2, y2, x3, y3, K As _Unsigned Long)
  1714.     Dim D As Long
  1715.     Static a&
  1716.  
  1717.     D = _Dest
  1718.     If a& = 0 Then
  1719.         a& = _NewImage(1, 1, 32)
  1720.     End If
  1721.     _Dest a&
  1722.     _DontBlend a&
  1723.     PSet (0, 0), K
  1724.     _Blend a&
  1725.     _Dest D
  1726.     _MapTriangle _Seamless(0, 0)-(0, 0)-(0, 0), a& To(x1, y1)-(x2, y2)-(x3, y3)
  1727. End Sub ' ftri1
  1728.  
  1729. ' /////////////////////////////////////////////////////////////////////////////
  1730. ' original fill quad that may be at fault using Steve's fTri version
  1731. ' need 4 non linear points (not all on 1 line) list them clockwise
  1732. ' so x2, y2 is opposite of x4, y4
  1733.  
  1734. Sub fquad1 (x1, y1, x2, y2, x3, y3, x4, y4, K As _Unsigned Long)
  1735.     ftri1 x1, y1, x2, y2, x4, y4, K
  1736.     ftri1 x3, y3, x2, y2, x4, y4, K
  1737. End Sub ' fquad1
  1738.  
  1739. ' /////////////////////////////////////////////////////////////////////////////
  1740. ' update 2019-12-16 needs orig fTri
  1741. ' need 4 non linear points (not all on 1 line)
  1742. ' list them clockwise so x2, y2 is opposite of x4, y4
  1743.  
  1744. Sub fquad (x1, y1, x2, y2, x3, y3, x4, y4, K As _Unsigned Long)
  1745.     ftri x1, y1, x2, y2, x3, y3, K
  1746.     ftri x3, y3, x4, y4, x1, y1, K
  1747. End Sub ' fquad
  1748.  
  1749. ' /////////////////////////////////////////////////////////////////////////////
  1750. ' DRAW A 2-D BOX
  1751.  
  1752. 'SUB DrawBox (iX%, iY%, iSize%, iColor%)
  1753. Sub DrawBox (iX%, iY%, iSize%, iColor&)
  1754.     Line (iX%, iY%)-(iX% + iSize%, iY% + iSize%), iColor&, BF ' Draw a solid box
  1755.     'LINE (iX%, iY%)-(iX% + iSize%, iY% + iSize%), iColor%, BF ' Draw a solid box
  1756.     'LINE (60, 60)-(130, 100), iColor%, B ' Draw a box outline
  1757. End Sub ' DrawBox
  1758.  
  1759. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1760. ' END GRAPHICS FUNCTIONS
  1761. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1762.  
  1763. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1764. ' BEGIN GENERAL PURPOSE FUNCTIONS
  1765. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1766.  
  1767. ' /////////////////////////////////////////////////////////////////////////////
  1768.  
  1769. Function cstr$ (myValue)
  1770.     'cstr$ = LTRIM$(RTRIM$(STR$(myValue)))
  1771.     cstr$ = _Trim$(Str$(myValue))
  1772. End Function ' cstr$
  1773.  
  1774. ' /////////////////////////////////////////////////////////////////////////////
  1775.  
  1776. Function cstrl$ (myValue As Long)
  1777.     cstrl$ = _Trim$(Str$(myValue))
  1778. End Function ' cstrl$
  1779.  
  1780. ' /////////////////////////////////////////////////////////////////////////////
  1781.  
  1782. Function cstrs$ (myValue As Single)
  1783.     ''cstr$ = LTRIM$(RTRIM$(STR$(myValue)))
  1784.     cstrs$ = _Trim$(Str$(myValue))
  1785. End Function ' cstrs$
  1786.  
  1787. ' /////////////////////////////////////////////////////////////////////////////
  1788.  
  1789. Function IIF (Condition, IfTrue, IfFalse)
  1790.     If Condition Then IIF = IfTrue Else IIF = IfFalse
  1791.  
  1792. ' /////////////////////////////////////////////////////////////////////////////
  1793.  
  1794. Function IIFSTR$ (Condition, IfTrue$, IfFalse$)
  1795.     If Condition Then IIFSTR$ = IfTrue$ Else IIFSTR$ = IfFalse$
  1796.  
  1797. ' /////////////////////////////////////////////////////////////////////////////
  1798. ' From: Bitwise Manipulations By Steven Roman
  1799. ' http://www.romanpress.com/Articles/Bitwise_R/Bitwise.htm
  1800.  
  1801. ' Returns the 8-bit binary representation
  1802. ' of an integer iInput where 0 <= iInput <= 255
  1803.  
  1804. Function GetBinary$ (iInput1 As Integer)
  1805.     Dim sResult As String
  1806.     Dim iLoop As Integer
  1807.     Dim iInput As Integer: iInput = iInput1
  1808.  
  1809.     sResult = ""
  1810.  
  1811.     If iInput >= 0 And iInput <= 255 Then
  1812.         For iLoop = 1 To 8
  1813.             sResult = LTrim$(RTrim$(Str$(iInput Mod 2))) + sResult
  1814.             iInput = iInput \ 2
  1815.             'If iLoop = 4 Then sResult = " " + sResult
  1816.         Next iLoop
  1817.     End If
  1818.  
  1819.     GetBinary$ = sResult
  1820. End Function ' GetBinary$
  1821.  
  1822. ' /////////////////////////////////////////////////////////////////////////////
  1823. ' wonderfully inefficient way to read if a bit is set
  1824. ' ival = GetBit256%(int we are comparing, int containing the bits we want to read)
  1825.  
  1826. ' See also: GetBit256%, SetBit256%
  1827.  
  1828. Function GetBit256% (iNum1 As Integer, iBit1 As Integer)
  1829.     Dim iResult As Integer
  1830.     Dim sNum As String
  1831.     Dim sBit As String
  1832.     Dim iLoop As Integer
  1833.     Dim bContinue As Integer
  1834.     'DIM iTemp AS INTEGER
  1835.     Dim iNum As Integer: iNum = iNum1
  1836.     Dim iBit As Integer: iBit = iBit1
  1837.  
  1838.     iResult = FALSE
  1839.     bContinue = TRUE
  1840.  
  1841.     If iNum < 256 And iBit <= 128 Then
  1842.         sNum = GetBinary$(iNum)
  1843.         sBit = GetBinary$(iBit)
  1844.         For iLoop = 1 To 8
  1845.             If Mid$(sBit, iLoop, 1) = "1" Then
  1846.                 'if any of the bits in iBit are false, return false
  1847.                 If Mid$(sNum, iLoop, 1) = "0" Then
  1848.                     iResult = FALSE
  1849.                     bContinue = FALSE
  1850.                     Exit For
  1851.                 End If
  1852.             End If
  1853.         Next iLoop
  1854.         If bContinue = TRUE Then
  1855.             iResult = TRUE
  1856.         End If
  1857.     End If
  1858.  
  1859.     GetBit256% = iResult
  1860. End Function ' GetBit256%
  1861.  
  1862. ' /////////////////////////////////////////////////////////////////////////////
  1863. ' From: Bitwise Manipulations By Steven Roman
  1864. ' http://www.romanpress.com/Articles/Bitwise_R/Bitwise.htm
  1865.  
  1866. ' Returns the integer that corresponds to a binary string of length 8
  1867.  
  1868. Function GetIntegerFromBinary% (sBinary1 As String)
  1869.     Dim iResult As Integer
  1870.     Dim iLoop As Integer
  1871.     Dim strBinary As String
  1872.     Dim sBinary As String: sBinary = sBinary1
  1873.  
  1874.     iResult = 0
  1875.     strBinary = Replace$(sBinary, " ", "") ' Remove any spaces
  1876.     For iLoop = 0 To Len(strBinary) - 1
  1877.         iResult = iResult + 2 ^ iLoop * Val(Mid$(strBinary, Len(strBinary) - iLoop, 1))
  1878.     Next iLoop
  1879.  
  1880.     GetIntegerFromBinary% = iResult
  1881. End Function ' GetIntegerFromBinary%
  1882.  
  1883. ' /////////////////////////////////////////////////////////////////////////////
  1884. ' By sMcNeill from https://www.qb64.org/forum/index.php?topic=896.0
  1885.  
  1886. Function IsNum% (text$)
  1887.     Dim a$
  1888.     Dim b$
  1889.     a$ = _Trim$(text$)
  1890.     b$ = _Trim$(Str$(Val(text$)))
  1891.     If a$ = b$ Then
  1892.         IsNum% = TRUE
  1893.     Else
  1894.         IsNum% = FALSE
  1895.     End If
  1896. End Function ' IsNum%
  1897.  
  1898. ' /////////////////////////////////////////////////////////////////////////////
  1899. ' Split and join strings
  1900. ' https://www.qb64.org/forum/index.php?topic=1073.0
  1901.  
  1902. 'Combine all elements of in$() into a single string with delimiter$ separating the elements.
  1903.  
  1904. Function join$ (in$(), delimiter$)
  1905.     result$ = in$(LBound(in$))
  1906.     For i = LBound(in$) + 1 To UBound(in$)
  1907.         result$ = result$ + delimiter$ + in$(i)
  1908.     Next i
  1909.     join$ = result$
  1910. End Function ' join$
  1911.  
  1912. ' /////////////////////////////////////////////////////////////////////////////
  1913. ' ABS was returning strange values with type LONG
  1914. ' so I created this which does not.
  1915.  
  1916. Function LongABS& (lngValue As Long)
  1917.     If Sgn(lngValue) = -1 Then
  1918.         LongABS& = 0 - lngValue
  1919.     Else
  1920.         LongABS& = lngValue
  1921.     End If
  1922. End Function ' LongABS&
  1923.  
  1924. ' /////////////////////////////////////////////////////////////////////////////
  1925. ' Returns blank if successful else returns error message.
  1926.  
  1927. Function PrintFile$ (sFileName As String, sText As String, bAppend As Integer)
  1928.     'x = 1: y = 2: z$ = "Three"
  1929.  
  1930.     Dim sError As String: sError = ""
  1931.  
  1932.     If Len(sError) = 0 Then
  1933.         If (bAppend = TRUE) Then
  1934.             If _FileExists(sFileName) Then
  1935.                 Open sFileName For Append As #1 ' opens an existing file for appending
  1936.             Else
  1937.                 sError = "Error in PrintFile$ : File not found. Cannot append."
  1938.             End If
  1939.         Else
  1940.             Open sFileName For Output As #1 ' opens and clears an existing file or creates new empty file
  1941.         End If
  1942.     End If
  1943.     If Len(sError) = 0 Then
  1944.         ' WRITE places text in quotes in the file
  1945.         'WRITE #1, x, y, z$
  1946.         'WRITE #1, sText
  1947.  
  1948.         ' PRINT does not put text inside quotes
  1949.         Print #1, sText
  1950.  
  1951.         Close #1
  1952.  
  1953.         'PRINT "File created with data. Press a key!"
  1954.         'K$ = INPUT$(1) 'press a key
  1955.  
  1956.         'OPEN sFileName FOR INPUT AS #2 ' opens a file to read it
  1957.         'INPUT #2, a, b, c$
  1958.         'CLOSE #2
  1959.  
  1960.         'PRINT a, b, c$
  1961.         'WRITE a, b, c$
  1962.     End If
  1963.  
  1964.     PrintFile$ = sError
  1965. End Function ' PrintFile$
  1966.  
  1967. ' /////////////////////////////////////////////////////////////////////////////
  1968. ' Generate random value between Min and Max.
  1969. Function RandomNumber% (Min%, Max%)
  1970.     Dim NumSpread%
  1971.  
  1972.     ' SET RANDOM SEED
  1973.     'Randomize ' Initialize random-number generator.
  1974.  
  1975.     ' GET RANDOM # Min%-Max%
  1976.     'RandomNumber = Int((Max * Rnd) + Min) ' generate number
  1977.  
  1978.     NumSpread% = (Max% - Min%) + 1
  1979.  
  1980.     RandomNumber% = Int(Rnd * NumSpread%) + Min% ' GET RANDOM # BETWEEN Max% AND Min%
  1981.  
  1982. End Function ' RandomNumber%
  1983.  
  1984. ' /////////////////////////////////////////////////////////////////////////////
  1985.  
  1986. Sub RandomNumberTest
  1987.     Dim iCols As Integer: iCols = 10
  1988.     Dim iRows As Integer: iRows = 20
  1989.     Dim iLoop As Integer
  1990.     Dim iX As Integer
  1991.     Dim iY As Integer
  1992.     Dim sError As String
  1993.     Dim sFileName As String
  1994.     Dim sText As String
  1995.     Dim bAppend As Integer
  1996.     Dim iMin As Integer
  1997.     Dim iMax As Integer
  1998.     Dim iNum As Integer
  1999.     Dim iErrorCount As Integer
  2000.     Dim sInput$
  2001.  
  2002.     sFileName = "c:\temp\maze_test_1.txt"
  2003.     sText = "Count" + Chr$(9) + "Min" + Chr$(9) + "Max" + Chr$(9) + "Random"
  2004.     bAppend = FALSE
  2005.     sError = PrintFile$(sFileName, sText, bAppend)
  2006.     If Len(sError) = 0 Then
  2007.         bAppend = TRUE
  2008.         iErrorCount = 0
  2009.  
  2010.         iMin = 0
  2011.         iMax = iCols - 1
  2012.         For iLoop = 1 To 100
  2013.             iNum = RandomNumber(iMin, iMax)
  2014.             sText = Str$(iLoop) + Chr$(9) + Str$(iMin) + Chr$(9) + Str$(iMax) + Chr$(9) + Str$(iNum)
  2015.             sError = PrintFile$(sFileName, sText, bAppend)
  2016.             If Len(sError) > 0 Then
  2017.                 iErrorCount = iErrorCount + 1
  2018.                 Print Str$(iLoop) + ". ERROR"
  2019.                 Print "    " + "iMin=" + Str$(iMin)
  2020.                 Print "    " + "iMax=" + Str$(iMax)
  2021.                 Print "    " + "iNum=" + Str$(iNum)
  2022.                 Print "    " + "Could not write to file " + Chr$(34) + sFileName + Chr$(34) + "."
  2023.                 Print "    " + sError
  2024.             End If
  2025.         Next iLoop
  2026.  
  2027.         iMin = 0
  2028.         iMax = iRows - 1
  2029.         For iLoop = 1 To 100
  2030.             iNum = RandomNumber(iMin, iMax)
  2031.             sText = Str$(iLoop) + Chr$(9) + Str$(iMin) + Chr$(9) + Str$(iMax) + Chr$(9) + Str$(iNum)
  2032.             sError = PrintFile$(sFileName, sText, bAppend)
  2033.             If Len(sError) > 0 Then
  2034.                 iErrorCount = iErrorCount + 1
  2035.                 Print Str$(iLoop) + ". ERROR"
  2036.                 Print "    " + "iMin=" + Str$(iMin)
  2037.                 Print "    " + "iMax=" + Str$(iMax)
  2038.                 Print "    " + "iNum=" + Str$(iNum)
  2039.                 Print "    " + "Could not write to file " + Chr$(34) + sFileName + Chr$(34) + "."
  2040.                 Print "    " + sError
  2041.             End If
  2042.         Next iLoop
  2043.  
  2044.         Print "Finished generating numbers. Errors: " + Str$(iErrorCount)
  2045.     Else
  2046.         Print "Error creating file " + Chr$(34) + sFileName + Chr$(34) + "."
  2047.         Print sError
  2048.     End If
  2049.  
  2050.     Input "Press <ENTER> to continue", sInput$
  2051. End Sub ' RandomNumberTest
  2052.  
  2053. ' /////////////////////////////////////////////////////////////////////////////
  2054. ' FROM: String Manipulation
  2055. ' http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index_topic_5964-0/
  2056. '
  2057. 'SUMMARY:
  2058. '   Purpose:  A library of custom functions that transform strings.
  2059. '   Author:   Dustinian Camburides (dustinian@gmail.com)
  2060. '   Platform: QB64 (www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there])
  2061. '   Revision: 1.6
  2062. '   Updated:  5/28/2012
  2063.  
  2064. 'SUMMARY:
  2065. '[Replace$] replaces all instances of the [Find] sub-string with the [Add] sub-string within the [Text] string.
  2066. 'INPUT:
  2067. 'Text: The input string; the text that's being manipulated.
  2068. 'Find: The specified sub-string; the string sought within the [Text] string.
  2069. 'Add: The sub-string that's being added to the [Text] string.
  2070.  
  2071. Function Replace$ (Text1 As String, Find1 As String, Add1 As String)
  2072.     ' VARIABLES:
  2073.     Dim Text2 As String
  2074.     Dim Find2 As String
  2075.     Dim Add2 As String
  2076.     Dim lngLocation As Long ' The address of the [Find] substring within the [Text] string.
  2077.     Dim strBefore As String ' The characters before the string to be replaced.
  2078.     Dim strAfter As String ' The characters after the string to be replaced.
  2079.  
  2080.     ' INITIALIZE:
  2081.     ' MAKE COPIESSO THE ORIGINAL IS NOT MODIFIED (LIKE ByVal IN VBA)
  2082.     Text2 = Text1
  2083.     Find2 = Find1
  2084.     Add2 = Add1
  2085.  
  2086.     lngLocation = InStr(1, Text2, Find2)
  2087.  
  2088.     ' PROCESSING:
  2089.     ' While [Find2] appears in [Text2]...
  2090.     While lngLocation
  2091.         ' Extract all Text2 before the [Find2] substring:
  2092.         strBefore = Left$(Text2, lngLocation - 1)
  2093.  
  2094.         ' Extract all text after the [Find2] substring:
  2095.         strAfter = Right$(Text2, ((Len(Text2) - (lngLocation + Len(Find2) - 1))))
  2096.  
  2097.         ' Return the substring:
  2098.         Text2 = strBefore + Add2 + strAfter
  2099.  
  2100.         ' Locate the next instance of [Find2]:
  2101.         lngLocation = InStr(1, Text2, Find2)
  2102.  
  2103.         ' Next instance of [Find2]...
  2104.     Wend
  2105.  
  2106.     ' OUTPUT:
  2107.     Replace$ = Text2
  2108. End Function ' Replace$
  2109.  
  2110. ' /////////////////////////////////////////////////////////////////////////////
  2111. ' fantastically inefficient way to set a bit
  2112.  
  2113. ' example use: arrMaze(iX, iY) = SetBit256%(arrMaze(iX, iY), cS, FALSE)
  2114.  
  2115. ' See also: GetBit256%, SetBit256%
  2116.  
  2117. ' newint=SetBit256%(oldint, int containing the bits we want to set, value to set them to)
  2118. Function SetBit256% (iNum1 As Integer, iBit1 As Integer, bVal1 As Integer)
  2119.     Dim sNum As String
  2120.     Dim sBit As String
  2121.     Dim sVal As String
  2122.     Dim iLoop As Integer
  2123.     Dim strResult As String
  2124.     Dim iResult As Integer
  2125.     Dim iNum As Integer: iNum = iNum1
  2126.     Dim iBit As Integer: iBit = iBit1
  2127.     Dim bVal As Integer: bVal = bVal1
  2128.  
  2129.     If iNum < 256 And iBit <= 128 Then
  2130.         sNum = GetBinary$(iNum)
  2131.         sBit = GetBinary$(iBit)
  2132.         If bVal = TRUE Then
  2133.             sVal = "1"
  2134.         Else
  2135.             sVal = "0"
  2136.         End If
  2137.         strResult = ""
  2138.         For iLoop = 1 To 8
  2139.             If Mid$(sBit, iLoop, 1) = "1" Then
  2140.                 strResult = strResult + sVal
  2141.             Else
  2142.                 strResult = strResult + Mid$(sNum, iLoop, 1)
  2143.             End If
  2144.         Next iLoop
  2145.         iResult = GetIntegerFromBinary%(strResult)
  2146.     Else
  2147.         iResult = iNum
  2148.     End If
  2149.  
  2150.     SetBit256% = iResult
  2151. End Function ' SetBit256%
  2152.  
  2153. ' /////////////////////////////////////////////////////////////////////////////
  2154. ' Split and join strings
  2155. ' https://www.qb64.org/forum/index.php?topic=1073.0
  2156. '
  2157. ' FROM luke, QB64 Developer
  2158. ' Date: February 15, 2019, 04:11:07 AM »
  2159. '
  2160. ' Given a string of words separated by spaces (or any other character),
  2161. ' splits it into an array of the words. I've no doubt many people have
  2162. ' written a version of this over the years and no doubt there's a million
  2163. ' ways to do it, but I thought I'd put mine here so we have at least one
  2164. ' version. There's also a join function that does the opposite
  2165. ' array -> single string.
  2166. '
  2167. ' Code is hopefully reasonably self explanatory with comments and a little demo.
  2168. ' Note, this is akin to Python/JavaScript split/join, PHP explode/implode.
  2169.  
  2170. 'Split in$ into pieces, chopping at every occurrence of delimiter$. Multiple consecutive occurrences
  2171. 'of delimiter$ are treated as a single instance. The chopped pieces are stored in result$().
  2172. '
  2173. 'delimiter$ must be one character long.
  2174. 'result$() must have been REDIMmed previously.
  2175.  
  2176. Sub split (in$, delimiter$, result$())
  2177.     ReDim result$(-1)
  2178.     start = 1
  2179.     Do
  2180.         While Mid$(in$, start, 1) = delimiter$
  2181.             start = start + 1
  2182.             If start > Len(in$) Then Exit Sub
  2183.         Wend
  2184.         finish = InStr(start, in$, delimiter$)
  2185.         If finish = 0 Then finish = Len(in$) + 1
  2186.         ReDim _Preserve result$(0 To UBound(result$) + 1)
  2187.         result$(UBound(result$)) = Mid$(in$, start, finish - start)
  2188.         start = finish + 1
  2189.     Loop While start <= Len(in$)
  2190. End Sub ' split
  2191.  
  2192. ' /////////////////////////////////////////////////////////////////////////////
  2193.  
  2194. Sub SplitTest
  2195.  
  2196.     Dim in$
  2197.     Dim delim$
  2198.     ReDim arrTest$(0)
  2199.     Dim iLoop%
  2200.  
  2201.     delim$ = Chr$(10)
  2202.     in$ = "this" + delim$ + "is" + delim$ + "a" + delim$ + "test"
  2203.     Print "in$ = " + Chr$(34) + in$ + Chr$(34)
  2204.     Print "delim$ = " + Chr$(34) + delimeter$ + Chr$(34)
  2205.     split in$, delim$, arrTest$()
  2206.  
  2207.     For iLoop% = LBound(arrTest$) To UBound(arrTest$)
  2208.         Print "arrTest$(" + LTrim$(RTrim$(Str$(iLoop%))) + ") = " + Chr$(34) + arrTest$(iLoop%) + Chr$(34)
  2209.     Next iLoop%
  2210.     Print
  2211.     Print "Split test finished."
  2212. End Sub ' SplitTest
  2213.  
  2214. ' /////////////////////////////////////////////////////////////////////////////
  2215.  
  2216. Sub WaitForEnter
  2217.     Dim in$
  2218.     Input "Press <ENTER> to continue", in$
  2219. End Sub ' WaitForEnter
  2220.  
  2221. ' /////////////////////////////////////////////////////////////////////////////
  2222. ' WaitForKey "Press <ESC> to continue", 27, 0
  2223. ' WaitForKey "Press <ENTER> to begin;", 13, 0
  2224. ' waitforkey "", 65, 5
  2225.  
  2226. Sub WaitForKey (prompt$, KeyCode&, DelaySeconds%)
  2227.     ' SHOW PROMPT (IF SPECIFIED)
  2228.     If Len(prompt$) > 0 Then
  2229.         If Right$(prompt$, 1) <> ";" Then
  2230.             Print prompt$
  2231.         Else
  2232.             Print Right$(prompt$, Len(prompt$) - 1);
  2233.         End If
  2234.     End If
  2235.  
  2236.     ' WAIT FOR KEY
  2237.     Do: Loop Until _KeyDown(KeyCode&) ' leave loop when specified key pressed
  2238.  
  2239.     ' PAUSE AFTER (IF SPECIFIED)
  2240.     If DelaySeconds% < 1 Then
  2241.         _KeyClear: '_DELAY 1
  2242.     Else
  2243.         _KeyClear: _Delay DelaySeconds%
  2244.     End If
  2245. End Sub ' WaitForKey
  2246.  
  2247. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2248. ' END GENERAL PURPOSE FUNCTIONS
  2249. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2250.  
  2251. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2252. ' BEGIN COLOR ROUTINES
  2253. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2254.  
  2255. ' /////////////////////////////////////////////////////////////////////////////
  2256. ' Receives:
  2257. ' cycleColor = determines how foreColor, backColor are modified
  2258. ' foreColor  = the foreground color
  2259. ' backColor  = the background color (if needed)
  2260.  
  2261. ' /////////////////////////////////////////////////////////////////////////////
  2262. ' DoCycleColor colorScheme%, myColor&
  2263.  
  2264. ' colorScheme = color scheme (value is alternated on subsequent calls)
  2265. ' myColor     = the current color (value is incremented/decremented on subsequent calls)
  2266.  
  2267. ' colorScheme values:
  2268. '  1 Rainbow6 #1
  2269. '  9 Rainbow6 #2
  2270. '  2 Rainbow18 #1
  2271. ' 10 Rainbow18 #2
  2272. '  3 Grayscale #1
  2273. ' 11 Grayscale #2
  2274. '  4 Grayscale #1
  2275. ' 12 Grayscale #2
  2276.  
  2277. Sub DoCycleColor (colorScheme As Integer, myColor As Long)
  2278.     ' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
  2279.     ' CYCLE FORE COLOR
  2280.  
  2281.     ' 1, 5, 9 = simple rainbow
  2282.     If colorScheme = 1 Or colorScheme = 9 Then
  2283.         Select Case myColor
  2284.             Case cRed&:
  2285.                 myColor = cOrange&
  2286.             Case cOrange&:
  2287.                 myColor = cYellow&
  2288.             Case cYellow&:
  2289.                 myColor = cGreen&
  2290.             Case cGreen&:
  2291.                 myColor = cBlue&
  2292.             Case cBlue&:
  2293.                 myColor = cPurple&
  2294.             Case Else:
  2295.                 myColor = cRed&
  2296.         End Select
  2297.  
  2298.         ' 2, 6, 10 = complex rainbow
  2299.     ElseIf colorScheme = 2 Or colorScheme = 10 Then
  2300.         Select Case myColor
  2301.             Case cRed&:
  2302.                 myColor = cOrangeRed&
  2303.             Case cOrangeRed&:
  2304.                 myColor = cDarkOrange&
  2305.             Case cDarkOrange&:
  2306.                 myColor = cOrange&
  2307.             Case cOrange&:
  2308.                 myColor = cGold&
  2309.             Case cGold&:
  2310.                 myColor = cYellow&
  2311.             Case cYellow&:
  2312.                 myColor = cChartreuse&
  2313.             Case cChartreuse&:
  2314.                 myColor = cLime&
  2315.             Case cLime&:
  2316.                 myColor = cMediumSpringGreen&
  2317.             Case cMediumSpringGreen&:
  2318.                 myColor = cCyan&
  2319.             Case cCyan&:
  2320.                 myColor = cDeepSkyBlue&
  2321.             Case cDeepSkyBlue&:
  2322.                 myColor = cDodgerBlue&
  2323.             Case cDodgerBlue&:
  2324.                 myColor = cSeaBlue&
  2325.             Case cSeaBlue&:
  2326.                 myColor = cBlue&
  2327.             Case cBlue&:
  2328.                 myColor = cBluePurple&
  2329.             Case cBluePurple&:
  2330.                 myColor = cDeepPurple&
  2331.             Case cDeepPurple&:
  2332.                 myColor = cPurple&
  2333.             Case cPurple&:
  2334.                 myColor = cPurpleRed&
  2335.             Case Else:
  2336.                 myColor = cRed&
  2337.         End Select
  2338.  
  2339.         ' 3, 7, 11 = grayscale, ascending
  2340.     ElseIf colorScheme = 3 Or colorScheme = 11 Then
  2341.         Select Case myColor
  2342.             Case cBlack&:
  2343.                 myColor = cDarkGray&
  2344.             Case cDarkGray&:
  2345.                 myColor = cDimGray&
  2346.             Case cDimGray&:
  2347.                 myColor = cGray&
  2348.             Case cGray&:
  2349.                 myColor = cLightGray&
  2350.             Case cLightGray&:
  2351.                 myColor = cSilver&
  2352.             Case cSilver&:
  2353.                 myColor = cWhite&
  2354.             Case Else:
  2355.                 'myColor = cBlack&
  2356.                 myColor = cSilver&
  2357.  
  2358.                 ' go in the other direction!
  2359.                 If colorScheme = 3 Then
  2360.                     colorScheme = 4
  2361.                 Else
  2362.                     colorScheme = 12
  2363.                 End If
  2364.  
  2365.         End Select
  2366.  
  2367.         ' 4, 8, 12 = grayscale, descending
  2368.     ElseIf colorScheme = 4 Or colorScheme = 12 Then
  2369.         Select Case myColor
  2370.             Case cWhite&:
  2371.                 myColor = cSilver&
  2372.             Case cSilver&:
  2373.                 myColor = cLightGray&
  2374.             Case cLightGray&:
  2375.                 myColor = cGray&
  2376.             Case cGray&:
  2377.                 myColor = cDimGray&
  2378.             Case cDimGray&:
  2379.                 myColor = cDarkGray&
  2380.             Case cDarkGray&:
  2381.                 myColor = cBlack&
  2382.             Case Else:
  2383.                 myColor = cDarkGray&
  2384.  
  2385.                 ' go in the other direction!
  2386.                 If colorScheme = 4 Then
  2387.                     colorScheme = 3
  2388.                 Else
  2389.                     colorScheme = 11
  2390.                 End If
  2391.         End Select
  2392.  
  2393.     End If
  2394.    
  2395. End Sub ' DoCycleColor
  2396.  
  2397. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2398. ' END COLOR ROUTINES
  2399. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2400.  
  2401. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2402. ' BEGIN COLOR FUNCTIONS
  2403. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2404.  
  2405. ' NOTE: these are mostly negative numbers
  2406. '       and have to be forced to positive
  2407. '       when stored in the dictionary
  2408. '       (only cEmpty& should be negative)
  2409.  
  2410. Function cRed& ()
  2411.     cRed& = _RGB32(255, 0, 0)
  2412.  
  2413. Function cOrangeRed& ()
  2414.     cOrangeRed& = _RGB32(255, 69, 0)
  2415. End Function ' cOrangeRed&
  2416.  
  2417. Function cDarkOrange& ()
  2418.     cDarkOrange& = _RGB32(255, 140, 0)
  2419. End Function ' cDarkOrange&
  2420.  
  2421. Function cOrange& ()
  2422.     cOrange& = _RGB32(255, 165, 0)
  2423. End Function ' cOrange&
  2424.  
  2425. Function cGold& ()
  2426.     cGold& = _RGB32(255, 215, 0)
  2427. End Function ' cGold&
  2428.  
  2429. Function cYellow& ()
  2430.     cYellow& = _RGB32(255, 255, 0)
  2431. End Function ' cYellow&
  2432.  
  2433. Function cChartreuse& ()
  2434.     cChartreuse& = _RGB32(127, 255, 0)
  2435. End Function ' cChartreuse&
  2436.  
  2437. Function cLime& ()
  2438.     cLime& = _RGB32(0, 255, 0)
  2439. End Function ' cLime&
  2440.  
  2441. Function cMediumSpringGreen& ()
  2442.     cMediumSpringGreen& = _RGB32(0, 250, 154)
  2443. End Function ' cMediumSpringGreen&
  2444.  
  2445. Function cCyan& ()
  2446.     cCyan& = _RGB32(0, 255, 255)
  2447. End Function ' cCyan&
  2448.  
  2449. Function cDeepSkyBlue& ()
  2450.     cDeepSkyBlue& = _RGB32(0, 191, 255)
  2451. End Function ' cDeepSkyBlue&
  2452.  
  2453. Function cDodgerBlue& ()
  2454.     cDodgerBlue& = _RGB32(30, 144, 255)
  2455. End Function ' cDodgerBlue&
  2456.  
  2457. Function cSeaBlue& ()
  2458.     cSeaBlue& = _RGB32(0, 64, 255)
  2459. End Function ' cSeaBlue&
  2460.  
  2461. Function cBlue& ()
  2462.     cBlue& = _RGB32(0, 0, 255)
  2463. End Function ' cBlue&
  2464.  
  2465. Function cBluePurple& ()
  2466.     cBluePurple& = _RGB32(64, 0, 255)
  2467. End Function ' cBluePurple&
  2468.  
  2469. Function cDeepPurple& ()
  2470.     cDeepPurple& = _RGB32(96, 0, 255)
  2471. End Function ' cDeepPurple&
  2472.  
  2473. Function cPurple& ()
  2474.     cPurple& = _RGB32(128, 0, 255)
  2475. End Function ' cPurple&
  2476.  
  2477. Function cPurpleRed& ()
  2478.     cPurpleRed& = _RGB32(128, 0, 192)
  2479. End Function ' cPurpleRed&
  2480.  
  2481. Function cDarkRed& ()
  2482.     cDarkRed& = _RGB32(160, 0, 64)
  2483. End Function ' cDarkRed&
  2484.  
  2485. Function cBrickRed& ()
  2486.     cBrickRed& = _RGB32(192, 0, 32)
  2487. End Function ' cBrickRed&
  2488.  
  2489. Function cDarkGreen& ()
  2490.     cDarkGreen& = _RGB32(0, 100, 0)
  2491. End Function ' cDarkGreen&
  2492.  
  2493. Function cGreen& ()
  2494.     cGreen& = _RGB32(0, 128, 0)
  2495. End Function ' cGreen&
  2496.  
  2497. Function cOliveDrab& ()
  2498.     cOliveDrab& = _RGB32(107, 142, 35)
  2499. End Function ' cOliveDrab&
  2500.  
  2501. Function cLightPink& ()
  2502.     cLightPink& = _RGB32(255, 182, 193)
  2503. End Function ' cLightPink&
  2504.  
  2505. Function cHotPink& ()
  2506.     cHotPink& = _RGB32(255, 105, 180)
  2507. End Function ' cHotPink&
  2508.  
  2509. Function cDeepPink& ()
  2510.     cDeepPink& = _RGB32(255, 20, 147)
  2511. End Function ' cDeepPink&
  2512.  
  2513. Function cMagenta& ()
  2514.     cMagenta& = _RGB32(255, 0, 255)
  2515. End Function ' cMagenta&
  2516.  
  2517. Function cBlack& ()
  2518.     cBlack& = _RGB32(0, 0, 0)
  2519. End Function ' cBlack&
  2520.  
  2521. Function cDimGray& ()
  2522.     cDimGray& = _RGB32(105, 105, 105)
  2523. End Function ' cDimGray&
  2524.  
  2525. Function cGray& ()
  2526.     cGray& = _RGB32(128, 128, 128)
  2527. End Function ' cGray&
  2528.  
  2529. Function cDarkGray& ()
  2530.     cDarkGray& = _RGB32(169, 169, 169)
  2531. End Function ' cDarkGray&
  2532.  
  2533. Function cSilver& ()
  2534.     cSilver& = _RGB32(192, 192, 192)
  2535. End Function ' cSilver&
  2536.  
  2537. Function cLightGray& ()
  2538.     cLightGray& = _RGB32(211, 211, 211)
  2539. End Function ' cLightGray&
  2540.  
  2541. Function cGainsboro& ()
  2542.     cGainsboro& = _RGB32(220, 220, 220)
  2543. End Function ' cGainsboro&
  2544.  
  2545. Function cWhiteSmoke& ()
  2546.     cWhiteSmoke& = _RGB32(245, 245, 245)
  2547. End Function ' cWhiteSmoke&
  2548.  
  2549. Function cWhite& ()
  2550.     cWhite& = _RGB32(255, 255, 255)
  2551. End Function ' cWhite&
  2552.  
  2553. Function cDarkBrown& ()
  2554.     cDarkBrown& = _RGB32(128, 64, 0)
  2555. End Function ' cDarkBrown&
  2556.  
  2557. Function cLightBrown& ()
  2558.     cLightBrown& = _RGB32(196, 96, 0)
  2559. End Function ' cLightBrown&
  2560.  
  2561. Function cKhaki& ()
  2562.     cKhaki& = _RGB32(240, 230, 140)
  2563. End Function ' cKhaki&
  2564.  
  2565. Function cEmpty& ()
  2566.     cEmpty& = -1
  2567. End Function ' cEmpty&
  2568.  
  2569. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2570. ' END COLOR FUNCTIONS
  2571. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2572.  

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Isometric Demo re-revisited (getting better!)
« Reply #1 on: December 02, 2021, 11:31:10 am »
That's coming along nicely!

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
Re: Isometric Demo re-revisited (getting better!)
« Reply #2 on: December 02, 2021, 01:41:40 pm »
That's coming along nicely!

Heh, thanks. I've never really dabbled in anything like 3D before, and I've been finding just getting it to work the way I want opens up so many questions.
I am constantly reminded of how much I don't know, but I'm learning, often from just trial and error.
For instance I must have gone through 5 or 6 different methods to determine what bricks are in front of the player to make transparent.
Also it's made easier by searching the QB64 help and forums, and it doesn't hurt that QB is a friendly and easy language.