Author Topic: need help with mouse in qb program  (Read 6453 times)

0 Members and 1 Guest are viewing this topic.

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: need help with mouse in qb program
« Reply #15 on: September 04, 2019, 11:07:16 am »
Here is CircleFill source code and example: https://www.qb64.org/forum/index.php?topic=1069.0

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: need help with mouse in qb program
« Reply #16 on: September 04, 2019, 11:10:32 am »
Hi Petr, Hi Tuc47

I am confused what worked? Petr did you erase the code that was red lining? How the heck did you substitute for that mouse routine so fast?!? wow


Also for speed put all images in containers and call up with _PUTIMAGE

« Last Edit: September 04, 2019, 11:12:00 am by bplus »

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: need help with mouse in qb program
« Reply #17 on: September 04, 2019, 11:18:43 am »
Hi BPlus,

The original code before tuc47 changed it in the attachment (the first in this thread) did not contain the QB4.5 mouse call. It was therefore much easier for me to navigate the program and find the operator from the keyboard to which I attached QB64 mouse commands. Although the .SCO file was missing there, but I looked what program wanted and I created it.

So version which i post works. Run the game and shoot using mouse to meteors. Original code allows this from keyboard only.
« Last Edit: September 04, 2019, 11:20:10 am by Petr »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: need help with mouse in qb program
« Reply #18 on: September 04, 2019, 11:21:22 am »
Nice work Petr! wow!

To tuc47

_PUTIMAGE, putting images in containers... that was all new to me when I first came to QB64

But man! it is nice!

Offline tuc47

  • Newbie
  • Posts: 12
    • View Profile
Re: need help with mouse in qb program
« Reply #19 on: September 04, 2019, 11:22:43 am »
Thanks the mouse does work but I have no idea how to speed it up.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: need help with mouse in qb program
« Reply #20 on: September 04, 2019, 11:24:37 am »
We are saying all the drawing might be slowing it down.

But might be timers and delays in there????

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: need help with mouse in qb program
« Reply #21 on: September 04, 2019, 11:45:58 am »
If sound statements in sub Explode are commented, is program speed bigger. If this speed is enought, QB64 know MP3 sound files or OGG or WAV sound files to use.
So try this version (needed attached files)

Code: QB64: [Select]
  1. '
  2. '                               1QSPACE.BAS
  3. '
  4. '         Copyright (C) 1990 Microsoft Corporation. All Rights Reserved.
  5. '
  6. ' Your mission in QSpace is to defend your orbiting starbases from enemy
  7. ' attack.  Protect them by firing your own interceptor missiles to destroy
  8. ' the incoming missiles.
  9. '
  10. ' To run this game, press Shift+F5.
  11. '
  12. ' To exit this program, press Alt, F, X.
  13. '
  14. ' To get help on a BASIC keyword, move the cursor to the keyword and press
  15. ' F1 or click the right mouse button.
  16. '
  17. ' To view suggestions on changing this game, press Page Down.
  18. '
  19. '
  20. '                             Suggested Changes
  21. '                             -----------------
  22. '
  23. ' There are many ways that you can modify this BASIC game.  The CONST
  24. ' statements below these comments and the DATA statements at the end
  25. ' of this screen can be modified to change the following:
  26. '
  27. '    Enemy missile speed at the start of the game
  28. '    Songs played during this game
  29. '    Color of the game pieces (EGA or VGA systems only)
  30. '    Speed of the targeting crosshair
  31. '    Number of missiles falling at the start of the game
  32. '    Size of missile explosions
  33. '    Duration of the explosions
  34. '    GAME OVER messages
  35. '
  36. ' On the right side of each CONST statement, there is a comment that tells
  37. ' you what it does and how big or small you can set the value.  Above the
  38. ' DATA statements, there are comments that tell you the format of the
  39. ' information stored there.
  40. '
  41. ' On your own, you can also add exciting sound and visual effects or make
  42. ' any other changes that your imagination can dream up.  By reading the
  43. ' Learn BASIC Now book, you'll learn the techniques that will enable you
  44. ' to fully customize this game and to create games of your own.
  45. '
  46. ' If the game won't run after you have changed it, you can exit without
  47. ' saving your changes by pressing Alt, F, X and choosing NO.
  48. '
  49. ' If you do want to save your changes, press Alt, F, A and enter a filename
  50. ' for saving your version of the program.  Before saving your changes,
  51. ' however, make sure the program still works by running the program and
  52. ' verifying that your changes produce the desired results.  Also, always
  53. ' be sure to keep a backup of the original program.
  54. DEFINT A-Z
  55. ' These CONST statements define things in the game that you can control.
  56. CONST GAMEBKGROUNDS7 = 0 ' Screen background color in screen mode 7. Can't be any of the other game colors.  Usually is black (0).
  57. CONST INITIALDELAY = .3 ' Initial value of the Incoming missile delay.  Increase the number to make the Incoming missiles slower; decrease to make them faster.  After odd-numbered waves, the IncomingDelay gets 33% shorter.
  58. CONST INITNUMSTARBASES = 1 ' Initial number of starbases.  This sets the starting value of the MaxStarbases variable.  Range is 1 to 4.
  59. CONST INITNUMMISSILES = 3 ' Number of incoming missiles when the game starts.  This is just the start - the number of missiles increases as you complete more waves.  Range 1 to 6.
  60. CONST TARGETSPEED = 15 ' How fast and far the target moves.  Range 4 to 30.
  61. CONST EXPLOSIONDELAY = .05 ' Rate that explosions grow.  Range .05 to .25.
  62. CONST EXPLRADIUS = 75 ' How big the explosion gets before it stops and is erased.  Range 5 to 75.
  63. CONST NEXPLRADIUS = 35
  64. CONST PLANETS7 = 9 ' Planet color in screen mode 7.
  65. CONST BASECOLORS7 = 7 ' Starbase color in screen mode 7. Can't be the same as GAMEBKGROUNDS7.
  66. CONST ENEMYCOLORS7 = 3 ' Enemy missile color in screen mode 7.  Can't be the same as GAMEBKGROUNDS7.
  67. CONST INTERCEPTCOLORS7 = 2 ' Interceptor missile color in screen mode 7.  Can't be the same as GAMEBKGROUNDS7.
  68. CONST EXPLCOLORS7 = 12 ' Explosion color in screen mode 7. Can't be the same as GAMEBKGROUNDS7.
  69. CONST TARGETCOLORS7 = 2 ' Target crosshair color for screen mode 7.  Can't be the same as GAMEBKGROUNDS7.
  70. CONST FASTESTMISSILE = .01 ' Lowest time delay between enemy missile movements.
  71. CONST RATIOINTERCEPTTOINCOMING = 10 ' How fast your interceptor missiles move compared to enemy missiles.  At 5, interceptors move at least 5 times faster than enemy missiles.  Range 1 to 20.
  72. ' The following sound constants are used by the PLAY command to
  73. ' produce music during the game.  To change the sounds you hear, change
  74. ' these constants.  Refer to the online help for PLAY for the correct format.
  75. ' To completely remove sound from the game set the constants equal to null.
  76. ' For example:  GAMESTARTSONG = ""
  77. CONST GAMESTARTSONG = "MBT150L4O2CD-CL8A-FAECD-L4A-F" ' Played when program starts. No limits.
  78. CONST WAVEOVERSONG = "MB O2 T240 L4 N40 N44 N48 N55 N48 L2 N53" ' Played at the end of each wave. No limits.
  79. CONST GAMEOVERSONG = "MB O1 T240 L2 g- g- L1 a" ' Played when the game is over. No limits.
  80.  
  81. ' The following CONST statements should not be changed like the ones above
  82. ' because the program relies on them being this value.
  83. CONST TRUE = -1 ' Microsoft QuickBASIC uses -1 to mean TRUE.
  84. CONST FALSE = 0 ' 0 means FALSE.
  85. CONST XSCALE = 320 ' Width of the screen.
  86. CONST YSCALE = 200 ' Height of the screen.
  87. CONST MAXY = YSCALE - 11 ' Highest vertical position that a missile can be.
  88. CONST MINY = 11 ' Lowest position an incoming missile can be can be.
  89. CONST MINX = 11 ' Left-most position an incoming missile can be.
  90. CONST MAXX = XSCALE - 11 ' Right-most position that an Incoming missile can be.
  91. CONST PAUSEGAME = 80 ' Key that pauses game.
  92. CONST QUITGAME = 81 ' Key that quits game.
  93. CONST ZKEY = 44 ' Key that fires the left missle.
  94. CONST XKEY = 45 ' Key that fires the right missle.
  95. CONST FACTOR = 250 ' Used to determine the radius of the starbases.  Increase to make the starbases smaller; decrease to make the starbases larger.
  96. CONST PI = 3.14 ' Value of the mathematical constant PI.  Used in determining the position of the starbases orbiting the planet.
  97. CONST PLANETRADIUS = XSCALE * .62 ' The radius of the planet that the starbases orbit.
  98. CONST GAMEBKGROUNDS1 = 0 ' Screen background in SCREEN 1.
  99. CONST PLANETS1 = 2 ' Planet color in SCREEN 1.
  100. CONST BASECOLORS1 = 1 ' Starbase color in SCREEN 1.
  101. CONST ENEMYCOLORS1 = 3 ' Enemy missile color in SCREEN 1.
  102. CONST INTERCEPTCOLORS1 = 3 ' Interceptor missile color in SCREEN 1.
  103. CONST EXPLCOLORS1 = 2 ' Explosion color in SCREEN 1.
  104. CONST TARGETCOLORS1 = 9 ' Target crosshair color for SCREEN 1
  105. CONST RESOLUTION = 100 ' Controls how accurately a line is drawn.
  106.  
  107. ' SUB and FUNCTION declarations
  108. DECLARE SUB Center (Text$, Row)
  109. DECLARE SUB DestroyStarbase (Z)
  110. DECLARE SUB DisplayIntro ()
  111. DECLARE SUB DisplayGameTitle ()
  112. DECLARE SUB DisplayChanges ()
  113. DECLARE SUB EraseMissileTrail (MNum)
  114. DECLARE SUB Explode (Chosen, x, Y, WMissiles)
  115. DECLARE SUB GameOver ()
  116. DECLARE SUB HorizontalScroll (M$, Row)
  117. DECLARE SUB InitScreen ()
  118. DECLARE SUB InitFirebases ()
  119. DECLARE SUB Keys (TurnKeysOn)
  120. DECLARE SUB KeyPause ()
  121. DECLARE SUB LaunchMissile (Chosen, XStart, YStart, XFinish, YFinish)
  122. DECLARE SUB NewMissile ()
  123. DECLARE SUB NewStarbase ()
  124. DECLARE SUB NewInterceptor (x, Y)
  125. DECLARE SUB StopMissile (Chosen, WMissiles)
  126. DECLARE SUB UpdateMissiles (Start, Finish, WMissiles, NumOfTimes, WColor)
  127. DECLARE SUB UpdateExplosions ()
  128. DECLARE SUB UpdateTarget ()
  129. DECLARE SUB UpdateScore ()
  130. DECLARE SUB WaveComplete ()
  131.  
  132. ' Structure definitions.
  133. TYPE Missile
  134.     x AS INTEGER ' Current X (horizontal) position.
  135.     Y AS INTEGER ' Current Y (vertical) position.
  136.     XStart AS INTEGER ' Horizontal missile start position.
  137.     YStart AS INTEGER ' Vertical missile start position.
  138.     XOffset AS INTEGER ' # of X pixels to move each time the UpdateMissile subprogram is called.
  139.     YOffset AS INTEGER ' # of Y pixels to move each time the UpdateMissile subprogram is called.
  140.     Active AS INTEGER ' 0 = not active, 1 = in flight, 2 = frozen (while it explodes)
  141.     XFinish AS INTEGER ' X of the missile's target.
  142.     YFinish AS INTEGER ' Y of the missile's target.
  143.     MaxCount AS INTEGER ' Number of moves in the missile's primary direction until the missile moves in the secondary direction.
  144.     Count AS INTEGER ' Number of moves in the missile's primary direction.
  145.     YMajor AS INTEGER ' TRUE if the missile moves more vertically then horizontally.  FALSE otherwise.
  146.  
  147. TYPE GenericPos ' General-purpose data type for moving objects.  Used many places in QSpace.
  148.     x AS INTEGER ' X position.
  149.     Y AS INTEGER ' Y position.
  150.     Active AS INTEGER ' FALSE (0) = Not active (destroyed, etc.), TRUE (-1) = Active.
  151.     OldX AS INTEGER ' Last X position.  Used to make it possible to restore a previous position if the new one would be off the screen.
  152.     OldY AS INTEGER ' Last Y position.  Used to make it possible to restore a previous position if the new one would be off the screen.
  153.  
  154. TYPE xplode ' Data type for explosions.
  155.     x AS INTEGER ' X position.
  156.     Y AS INTEGER ' Y position.
  157.     Active AS INTEGER ' Explosion status.  FALSE (0) = No explosion, Greater than 0 = Radius of explosion.
  158.     MissileNum AS INTEGER ' Number of the missile that was destroyed to cause this explosion.  Needed to erase missile path after explosion is over.
  159.     MType AS INTEGER ' Type of the missile that exploded.  1 = incoming enemy missile, 2 = interceptor missile.
  160.  
  161. CLEAR , , 5120 ' Set up a large stack for input processing
  162.  
  163. ' DIM SHARED indicates that the following variable is available to all
  164. ' subprograms.  Without this statement, a variable used in one subprogram
  165. ' cannot be used by another subprogram or the main program.
  166. DIM SHARED NumMissiles AS INTEGER ' Maximum number of incoming missiles.  Initially set to InitNumMissiles.
  167. DIM SHARED MaxStarbases AS INTEGER ' Maximum number of starbases.  Initially set to InitNumStarbases.
  168. DIM SHARED Incoming(1 TO 10) AS Missile ' Array used to track of all missiles, both incoming and interceptors.  Incoming missiles are numbered from 1 to 6; interceptors from 7 to 10.
  169. DIM SHARED Starbase(1 TO 4) AS GenericPos ' Array used to keep track of the starbases.  Game begins with 3 starbases but up to 4 starbases can exist depending on the score.  New bases added by the WaveComplete subprogram.
  170. DIM SHARED ContinueGame AS INTEGER ' A flag variable to track the status of the game.  1 = Game in progress, -1 = Begin new game, 0 = End game.
  171. DIM SHARED Target AS GenericPos ' Target crosshair.  The .active element is not used.
  172. DIM SHARED NumIntercepts AS INTEGER ' Number of interceptors flying.  No more than 4 can exist at any one time.
  173. DIM SHARED Score AS LONG ' Score.
  174. DIM SHARED Hscore AS LONG ' High score
  175. DIM SHARED Wave AS LONG ' Number of the current attack wave.
  176. DIM SHARED WaveCount AS LONG ' Number of missiles already launched in the current attack wave.
  177. DIM SHARED NextIncoming AS SINGLE ' Interval, in seconds from current time, to move the incoming missiles again.
  178. DIM SHARED NextExplosion AS SINGLE ' Delay until next explosion begins.
  179. DIM SHARED Explosion(1 TO 10) AS xplode ' Array that keeps track of the explosions.  Since no more than 10 missiles can be flying at once, no more than 10 simultaneous explosions are possible.
  180. DIM SHARED IncomingDelay AS SINGLE ' Delay between incoming missile movements.
  181. DIM SHARED MissilesFlying AS INTEGER ' Number of incoming missiles currently flying.
  182. DIM SHARED BasesLeft AS INTEGER ' Number of starbases left.  Used for scoring and in determining when the game is over.
  183. DIM SHARED TotalIncoming AS LONG ' Total number of incoming missiles that have been destroyed.  Used for the statistics at the end of the game.
  184. DIM SHARED TotalInterceptors AS LONG ' Total number of interceptors launched.  Used for the statistics at the end of the game.
  185. DIM SHARED NextNewBase AS LONG ' Score when a bonus new base will be awarded.
  186. DIM SHARED NumExplosions AS INTEGER ' Number of explosions in progress.
  187. DIM SHARED PlanetColor AS INTEGER ' Color of the planet.
  188. DIM SHARED EnemyColor AS INTEGER ' Color of the enemy missiles.
  189. DIM SHARED InterceptColor AS INTEGER ' Color of interceptor missiles.
  190. DIM SHARED ExplColor AS INTEGER ' Color of the explosions.
  191. DIM SHARED BaseColor AS INTEGER ' Primary color of the starbase.
  192. DIM SHARED GameBkGround AS INTEGER ' Color of the game background.
  193. DIM SHARED TargetColor AS INTEGER ' Color of the target crosshair.
  194. DIM SHARED ScreenMode AS INTEGER ' Number of the screen mode we are running in.
  195. DIM SHARED ScreenWidth AS INTEGER ' Width of the screen. Used in various screen output functions.
  196. DIM SHARED ExplodeSound AS LONG
  197.  
  198. ExplodeSound = _SNDOPEN("expl.mp3")
  199.  
  200. DIM KeyFlags AS INTEGER ' Internal state of the keyboard flags when game starts.  Hold the state so it can be restored when the games ends.
  201. DIM BadMode AS INTEGER ' Store the status of a valid screen mode.
  202.  
  203. ON ERROR GOTO ScreenError ' Set up a place to jump to if an error occurs in the program.
  204. BadMode = FALSE
  205. ScreenMode = 7
  206. SCREEN ScreenMode ' Attempt to go into SCREEN 7 (EGA screen).
  207. IF BadMode = TRUE THEN ' If this attempt failed.
  208.     ScreenMode = 1
  209.     BadMode = FALSE
  210.     SCREEN ScreenMode ' Attempt to go into SCREEN 1 (CGA screen).
  211. ON ERROR GOTO 0 ' Turn off error handling for now.
  212.  
  213. IF BadMode THEN ' If no graphics adapter.
  214.     CLS
  215.     LOCATE 10, 13: PRINT "CGA, EGA Color, or VGA graphics required to run QSPACE.BAS"
  216.     RANDOMIZE TIMER ' Ensure that a new random number sequence is generated.
  217.     DisplayIntro ' Display the name of the game, control keys, etc.
  218.  
  219.     DEF SEG = 0 ' Set the current segment to the low memory area.
  220.     KeyFlags = PEEK(1047) ' Read the location that stores the keyboard flag.
  221.     POKE 1047, &H0 ' Force them off.
  222.     DEF SEG ' Restore the default segment.
  223.  
  224.     DO ' For multiple games.
  225.         RESTORE ' BASIC command to allow DATA statements to be reused.  Necessary for multiple games.
  226.         ScreenWidth = 40 ' Set screen width of the two screens supported - 1 and 7.
  227.         IncomingDelay = INITIALDELAY ' Set initial incoming missile IncomingDelay to the value of the InitialDelay constant.
  228.         Wave = 1 ' Set wave number to 1 (first wave).
  229.         WaveCount = 0 ' Set number of missiles in the first wave to 0.  After the first wave, WaveCount is reset by the WaveComplete subprogram.
  230.         Score = 0 ' Set score to 0 to begin the game.
  231.         InitScreen ' Initialize the screen, including drawing the planet.
  232.         NumMissiles = INITNUMMISSILES ' Set maximum number of missiles flying simultaneously in each wave to the value of the InitNumMissiles constant.
  233.         MissilesFlying = 0 ' Set the number of missiles currently flying to 0.  Like WaveCount, this is cleared after subsequent waves by the WaveComplete subprogram.
  234.         NumIntercepts = 0 ' Set the number of interceptors currently flying.
  235.         NumExplosions = 0 ' Set the number of explosions currently happening.
  236.         ContinueGame = TRUE ' ContinueGame = TRUE means that a game is in progress.
  237.         NextIncoming = TIMER ' Time when incoming missiles will again fire.  Setting NextIncoming equal to the timer insures that the incoming missiles will begin moving immediately.
  238.         NextExplosion = TIMER ' Time when explosions will be updated again.   Setting NextExplosion equal to the timer ensures that the explosions will begin immediately.
  239.         TotalIncoming = 0 ' Set total number of destroyed incoming missiles.  Missiles are counted as destroyed if hit by interceptor missiles, hit by the explosion of another incoming missile, or stopped by hitting their targets.
  240.         TotalInterceptors = 0 ' Set total number of interceptors launched.
  241.         BasesLeft = 0 ' Set the number of bases remaining.  Necessary because the NewBase subprogram used below adds 1 to the current number of bases remaining.
  242.         MaxStarbases = INITNUMSTARBASES ' Set maximum number of starbases equal to the value of the InitNumStarbases constant.
  243.         NextNewBase = 25000 ' Set initial point at which a bonus starbase is awarded. After that, new starbases are awarded based on a formula in the WaveComplete subprogram.
  244.  
  245.         ERASE Starbase, Incoming, Explosion ' Set all elements of the entire Starbase, Incoming, and Explosion arrays to 0.
  246.  
  247.         FOR i = 1 TO MaxStarbases ' Loop to create the number of starbases called for in the MaxStarbases variable.
  248.             NewStarbase ' Create a new starbase
  249.         NEXT i
  250.  
  251.         InitFirebases ' Draw the firebases.
  252.  
  253.         FOR i = 1 TO NumMissiles ' Start the incoming missiles flying.
  254.             NewMissile
  255.         NEXT i
  256.  
  257.         ' The KEY n and ON KEY statements below enable QSpace to move the
  258.         ' target crosshair the moment a key is pressed.  After the
  259.         ' KEY (X) ON statement, anytime key (X) is pressed, QSpace stops
  260.         ' what it was doing and moves the crosshair.  After the crosshair
  261.         ' moves, QSpace goes back to where it left off.  This method allows
  262.         ' BASIC to process keys instantly and without explicitly checking
  263.         ' the keyboard.
  264.         KEY 15, CHR$(0) + CHR$(XKEY) ' Right missle the x key
  265.         KEY 16, CHR$(0) + CHR$(ZKEY) ' Left missle  the z key
  266.         KEY 17, CHR$(128) + CHR$(72) ' Extended Up key for player 1.
  267.         KEY 18, CHR$(128) + CHR$(75) ' Extended Left key for player 1.
  268.         KEY 19, CHR$(128) + CHR$(77) ' Extended Right key for player 1.
  269.         KEY 20, CHR$(128) + CHR$(80) ' Extended Down key for player 1.
  270.  
  271.         ON KEY(11) GOSUB MoveCrossHairUp ' Up key.
  272.         ON KEY(12) GOSUB MoveCrossHairLeft ' Left key.
  273.         ON KEY(13) GOSUB MoveCrossHairRight ' Right key.
  274.         ON KEY(14) GOSUB MoveCrossHairDown ' Down key.
  275.         ON KEY(15) GOSUB FireLeftMissle ' Fire the left missle.
  276.         ON KEY(16) GOSUB FireRightMissle ' Fire the right missle.
  277.         ON KEY(17) GOSUB MoveCrossHairUp ' Process Up key.
  278.         ON KEY(18) GOSUB MoveCrossHairLeft ' Process Left key.
  279.         ON KEY(19) GOSUB MoveCrossHairRight ' the Right key.
  280.         ON KEY(20) GOSUB MoveCrossHairDown ' the Down key.
  281.         Keys TRUE ' Enable key event processing.
  282.         _MOUSEHIDE
  283.         DO WHILE ContinueGame = TRUE ' ContinueGame is set to TRUE at the start of each game.  When the game is over, ContinueGame is set to either FALSE (do not play again) or 1 (play again).
  284.  
  285.             IF TIMER > MouseTime THEN
  286.                 WHILE _MOUSEINPUT
  287.                     IF omx > _MOUSEX THEN omx = _MOUSEX: GOSUB MoveCrossHairLeft
  288.                     IF omx < _MOUSEX THEN omx = _MOUSEX: GOSUB MoveCrossHairRight
  289.                     IF omy > _MOUSEY THEN omy = _MOUSEY: GOSUB MoveCrossHairUp
  290.                     IF omy < _MOUSEY THEN omy = _MOUSEY: GOSUB MoveCrossHairDown
  291.                     IF _MOUSEBUTTON(1) THEN GOSUB FireRightMissle
  292.                     IF _MOUSEBUTTON(2) THEN GOSUB FireLeftMissle
  293.                 WEND
  294.                 MouseTime = TIMER + .3
  295.             END IF
  296.  
  297.             IF TIMER >= NextIncoming THEN ' If enough time has elapsed since the enemy incoming missiles last moved,
  298.                 NextIncoming = TIMER + IncomingDelay ' Calculate when to move the incoming missiles again.
  299.                 UpdateMissiles 1, NumMissiles, 1, 1, EnemyColor ' Move the incoming missiles one step.  The 1 means move incoming missiles, a 2 would mean move interceptors; EnemyColor is the color of the incoming missiles -- usually cyan (3).
  300.             END IF
  301.  
  302.             IF NumExplosions > 0 THEN ' Update explosions if there are any.
  303.                 IF TIMER >= NextExplosion THEN ' If enough time has elapsed since the explosions were last updated,
  304.                     NextExplosion = TIMER + EXPLOSIONDELAY ' calculate when to update the explosions again.
  305.                     UpdateExplosions ' Increase the size of any explosions.
  306.                 END IF
  307.             END IF
  308.  
  309.             IF NumIntercepts > 0 THEN ' Update interceptors if any are in the air.
  310.                 UpdateMissiles 7, 10, 2, RATIOINTERCEPTTOINCOMING, InterceptColor
  311.             END IF
  312.  
  313.             K$ = INKEY$ ' Get a key press.
  314.             IF LEN(K$) > 0 THEN ' LEN(K$) will be 0 if no key was pressed.
  315.                 SELECT CASE ASC(UCASE$(K$)) ' Prepare to compare the ASCII value of the key press (done with the ASC function).  UCASE$ forces upper-case.
  316.                     CASE PAUSEGAME ' Key to pause game.
  317.                         SOUND 1100, .75 ' Tone at 1100 hertz for 75 clock ticks.
  318.                         Center " * Paused * ", 12 ' Display message on the screen.
  319.                         DO: LOOP UNTIL INKEY$ <> "" ' Wait until player presses any key.
  320.                         Center SPACE$(12), 12
  321.  
  322.                     CASE QUITGAME ' Key to quit game.
  323.                         SOUND 1700, 1 ' Tone at 1700 hertz for 1 clock tick.
  324.                         SOUND 1100, .75 ' Tone at 1100 hertz for .75 clock tick.
  325.                         Center " Really quit? (Y/N) ", 12 ' Make sure player really wants to quit.
  326.                         DO ' Wait until player presses a key.
  327.                             A$ = UCASE$(INKEY$)
  328.                         LOOP UNTIL A$ <> ""
  329.                         IF A$ = "Y" THEN ContinueGame = FALSE ' If so, set the main loop variable to FALSE to end main program level loop.
  330.                         Center SPACE$(20), 12 ' Clear the message line.
  331.  
  332.                 END SELECT
  333.             END IF
  334.  
  335.         LOOP ' Do again until the game is over.
  336.  
  337.     LOOP WHILE ContinueGame <> FALSE ' At GameOver, the ContinueGame variable is set to either 1 or FALSE (0) depending on whether the player wants to try again.  If 1, then the game restarts.
  338.  
  339.     DisplayChanges ' Display the suggested changes.
  340.  
  341.     DEF SEG = 0 ' Restore the previous flag settings.
  342.     POKE 1047, KeyFlags
  343.     DEF SEG
  344.  
  345.  
  346. END ' End of the main program code.
  347.  
  348. MoveCrossHairUp:
  349. Target.Y = Target.Y - TARGETSPEED
  350. UpdateTarget
  351.  
  352. MoveCrossHairDown:
  353. Target.Y = Target.Y + TARGETSPEED
  354. UpdateTarget
  355.  
  356. MoveCrossHairLeft:
  357. Target.x = Target.x - TARGETSPEED
  358. UpdateTarget
  359.  
  360. MoveCrossHairRight:
  361. Target.x = Target.x + TARGETSPEED
  362. UpdateTarget
  363.  
  364. FireLeftMissle:
  365. Keys FALSE ' Turn all keys off.
  366. NewInterceptor MAXX - 1, MAXY - 1 ' Launch interceptor missile.
  367. Keys TRUE ' Turn the keys back on.
  368.  
  369. FireRightMissle:
  370. Keys FALSE ' Turn all keys off.
  371. NewInterceptor MINX + 1, MAXY - 1 ' Launch interceptor missile.
  372. Keys TRUE ' Turn keys back on.
  373.  
  374. ' All of the data for GameOver messages.  These can also be changed but the
  375. ' format must be the same.  For example, the first line has a 5: that says how
  376. ' many lines of data will come afterwards, and the next lines are made of two
  377. ' parts: what the rank is (such as "Cadet") and the comments to go along with it.
  378. ' You can add a new line by following the format the others have and adding
  379. ' one to the number at the top.  The last line has already been created so you
  380. ' can just change the 5 to a 6 for to add that message.
  381.  
  382. DATA 5: ' The number of messages.
  383. DATA "Cadet","Not good.  Everything destroyed.": ' Lowest possible rank.
  384. DATA "Ensign","You saved a few people.": ' Better rank.
  385. DATA "Lieutenant","Your parents will be proud.": ' Better rank.
  386. DATA "Commander","Medal of Honor!": ' Better rank.
  387. DATA "Admiral","If only we had more like you!": ' Top rank.
  388. DATA "Top Gun","You can guard our starbases anytime!!": ' The ultimate.
  389.  
  390. ScreenError: ' QSpace uses this error handler to determine the highest available video mode.
  391. BadMode% = TRUE
  392.  
  393. '----------------------------------------------------------------------------
  394. ' Center
  395. '
  396. '    Centers the given text string on the indicated row.
  397. '
  398. '                       PARAMETERS:     text$   - The text to center
  399. '                                       row     - The screen row to print on
  400. '----------------------------------------------------------------------------
  401. SUB Center (Text$, Row)
  402.  
  403.     LOCATE Row, (ScreenWidth - LEN(Text$)) \ 2 + 1
  404.     PRINT Text$;
  405.  
  406.  
  407. '----------------------------------------------------------------------------
  408. 'DestroyStarbase
  409. '
  410. '    Declares a given base number as destroyed and determine the
  411. '    number of star bases remaining.  If that number is zero then
  412. '    call the GameOver routine. This subprogram does not do the
  413. '    visual explosion of the starbase.
  414. '
  415. '           PARAMETERS:     BNum - Number of the starbase to destroy.
  416. '----------------------------------------------------------------------------
  417. SUB DestroyStarbase (BNum)
  418.  
  419.     Starbase(BNum).Active = FALSE ' Set the passed starbase number to 0.
  420.     BasesLeft = 0 ' Assume there are no starbases left.
  421.  
  422.     FOR i = 1 TO MaxStarbases ' Perform one more than the initial number of starbases.
  423.         BasesLeft = BasesLeft - Starbase(i).Active ' If not 0, increase by one.
  424.         IF Starbase(i).Active = TRUE THEN MaxStarbases = i ' Keep counting until you've counted the number of starbases left.
  425.     NEXT i
  426.  
  427.     IF BasesLeft = 0 THEN ' If there are no starbases left,
  428.         GameOver ' call the GameOver SUB.
  429.     END IF
  430.    
  431.  
  432. '----------------------------------------------------------------------------
  433. ' DisplayChanges
  434. '
  435. '    Displays list of changes that the player can easily make.
  436. '
  437. '           PARAMETERS:     None
  438. '----------------------------------------------------------------------------
  439. SUB DisplayChanges
  440.     SYSTEM
  441.  
  442. '----------------------------------------------------------------------------
  443. ' DisplayGameTitle
  444. '
  445. '    Displays title of the game.
  446. '
  447. '           PARAMETERS:     None
  448. '----------------------------------------------------------------------------
  449. SUB DisplayGameTitle
  450.  
  451.     SCREEN 0 ' Set Screen mode 0.
  452.     WIDTH 80, 25 ' Set width to 80, height to 25.
  453.     COLOR 4, 0 ' Set colors for red on black.
  454.     CLS ' Clear the screen.
  455.     ScreenWidth = 80 ' Set screen width variable to match current width.
  456.  
  457.     ' Draw outline around screen with extended ASCII characters.
  458.     LOCATE 1, 2
  459.     PRINT CHR$(201); STRING$(76, 205); CHR$(187); ' Draw top border.
  460.     FOR i% = 2 TO 24
  461.         LOCATE i%, 2
  462.         PRINT CHR$(186); TAB(79); CHR$(186); ' Draw left and right borders.
  463.     NEXT i%
  464.     LOCATE 25, 2
  465.     PRINT CHR$(200); STRING$(76, 205); CHR$(188); ' Draw bottom border.
  466.  
  467.     OPEN "I", #1, "1QSPACE.SCO": INPUT #1, name$, Hscore: CLOSE #1
  468.     LOCATE 7, 35: PRINT name$
  469.     LOCATE 9, 20: PRINT USING "HAS THE HIGH SCORE OF ###,###,###"; Hscore
  470.      
  471.     ' Print game title centered at top of screen.
  472.     COLOR 0, 4 ' Set colors to black on red.
  473.     Center "     Steve's     ", 1 ' Center game title on lines
  474.     Center "    Q S P A C E    ", 2 ' 1 and 2.
  475.     Center "   Press any key to continue   ", 25 ' Center prompt on line 25.
  476.     COLOR 7, 0 ' Set colors to white on black.
  477.  
  478.  
  479. '----------------------------------------------------------------------------
  480. ' DisplayIntro
  481. '
  482. '    Explains the object of the game and show how to play.
  483. '
  484. '           PARAMETERS:     None
  485. '----------------------------------------------------------------------------
  486. SUB DisplayIntro
  487.    
  488.     DisplayGameTitle ' Display game title.
  489.  
  490.     COLOR 4
  491.     Center STRING$(74, 196), 15 ' Put horizontal red line on screen.
  492.     COLOR 7
  493.     Center " Game Controls ", 15 ' Display game controls.
  494.     Center "General        Missile Launchers               Target site    ", 17
  495.     Center "                                             (Up)", 19
  496.     Center "P - Pause      Z - Fire left launcher                 " + CHR$(24) + "          ", 20
  497.     Center "Q - Quit       X - Fire right launcher       (Left) " + CHR$(27) + "   " + CHR$(26) + " (Right)", 21
  498.     Center "                                            " + CHR$(25), 22
  499.     Center "                                             (Down)", 23
  500.  
  501.     PLAY GAMESTARTSONG ' Play intro melody.
  502.  
  503.     DO ' Wait for keypress to continue
  504.         kbd$ = UCASE$(INKEY$)
  505.     LOOP WHILE kbd$ = ""
  506.     IF kbd$ = "Q" THEN ' Allow player to quit now
  507.         CLS
  508.         LOCATE 10, 30: PRINT "Really quit? (Y/N)";
  509.         DO
  510.             kbd$ = UCASE$(INKEY$)
  511.         LOOP WHILE kbd$ = ""
  512.         IF kbd$ = "Y" THEN
  513.             CLS
  514.             END
  515.         END IF
  516.     END IF
  517.  
  518.    
  519.  
  520. '----------------------------------------------------------------------------
  521. ' EraseMissileTrail
  522. '
  523. '    Erases the trail of both enemy and interceptor missiles once
  524. '    they have exploded. This subprogram erases one of many
  525. '    possible missile trails temporarily stored in the Incoming() array.
  526. '
  527. '           PARAMETERS:     MNum - Missile line number to erase.
  528. '----------------------------------------------------------------------------
  529. SUB EraseMissileTrail (MNum)
  530.  
  531.     MaxCount = Incoming(MNum).MaxCount ' Set temporary variable to the number of moves in the primary direction made before a move in the secondary direction.
  532.     Count = MaxCount ' Temp variable that keeps track of how many times the trail has been followed since the last move in the secondary direction.
  533.     IF Incoming(MNum).YMajor THEN ' For best speed, use different routines for missiles that move mainly vertically (YMajor = TRUE) and those that move mainly horizontally (YMajor = FALSE).
  534.         x = Incoming(MNum).XStart ' Initial X position.
  535.         XOff = Incoming(MNum).XOffset ' Temp variable for the X offset.
  536.         FOR Y = Incoming(MNum).YStart TO Incoming(MNum).Y STEP SGN(Incoming(MNum).YOffset) ' Loop through all Y positions.
  537.             PSET (x, Y), GameBkGround ' Erase the dot.
  538.             Count = Count - RESOLUTION ' Decrease COUNT.  RESOLUTION controls how accurate this algorithm is (the higher the more accurate).
  539.             IF Count <= 0 THEN ' Don't move in the X direction until Y has moved enough for COUNT to drop to 0 or below.
  540.                 x = x + XOff ' Move in the X direction.
  541.                 Count = Count + MaxCount ' Reset counter.
  542.             END IF
  543.         NEXT
  544.     ELSE ' Missile moves more horizontally than vertically.
  545.         Y = Incoming(MNum).YStart ' Initial Y position.
  546.         YOff = Incoming(MNum).YOffset ' Temp variable for the Y offset.
  547.         FOR x = Incoming(MNum).XStart TO Incoming(MNum).x STEP SGN(Incoming(MNum).XOffset) ' Loop through all X positions.
  548.             PSET (x, Y), GameBkGround ' Erase the dot.
  549.             Count = Count - RESOLUTION ' Decrease COUNT.
  550.             IF Count <= 0 THEN ' Has trail moved enough in the X direction to move in the X direction?
  551.                 Y = Y + YOff ' Yes.  Move in the Y direction.
  552.                 Count = Count + MaxCount ' Reset counter.
  553.             END IF
  554.         NEXT
  555.     END IF
  556.  
  557.  
  558. '----------------------------------------------------------------------------
  559. ' Explode
  560. '
  561. '    Generates the explosion sound and set up an Explosion array
  562. '    element to use when drawing the visual explosion.
  563. '
  564. '       PARAMETERS:     MNum       - Missile number that caused the explosion.
  565. '                       WMissiles  - Type of missile being exploded (enemy or interceptor).
  566. '----------------------------------------------------------------------------
  567. SUB Explode (MNum, x, Y, WMissiles)
  568.     IF Incoming(MNum).Active <> TRUE THEN EXIT SUB ' Makes sure that the same missile is not exploded twice.
  569.     '    PLAY "MB" ' Play (M)usic in the (B)ackground.
  570.     '    SOUND 50, 2 ' Tone at 50 hertz for 2 clock ticks (clock tick = .054 seconds).
  571.     '    PLAY "MB"
  572.     '    SOUND 40, 8 ' Tone at 40 hertz for 8 clock ticks.
  573.  
  574.     _SNDPLAY ExplodeSound&
  575.     DO ' DO loop to determine the highest number of currently active explosions.
  576.         XNum = XNum + 1 ' Increase the counter.
  577.     LOOP UNTIL Explosion(XNum).Active = FALSE ' When this loop is done XNum will contain the number of a valid array offset to use for the new explosion.
  578.  
  579.     Explosion(XNum).Active = 1 ' Set the active status to 1.
  580.     Explosion(XNum).x = x ' Set X and Y values to the current incoming
  581.     Explosion(XNum).Y = Y '  missile's X and Y values.
  582.     Explosion(XNum).MissileNum = MNum ' Set to the missile number that was passed in as an argument.
  583.     Explosion(XNum).MType = WMissiles ' Set to the missile type that was passed in as an argument.
  584.     Incoming(MNum).Active = 2 ' Set the specific incoming missile's active status to 2.
  585.     NumExplosions = NumExplosions + 1 ' Increase the number of global explosions to add this one.
  586.     NextExplosion = TIMER ' Ensure explosion begins immediately.
  587.  
  588.  
  589. '----------------------------------------------------------------------------
  590. ' GameOver
  591. '
  592. '    Displays the full-screen explosion, read the GAME OVER
  593. '    messages, and display the score and statistics.
  594. '    Also asks the player if he/she wants to play again.
  595. '
  596. '                   PARAMETERS:     None
  597. '----------------------------------------------------------------------------
  598. SUB GameOver
  599.  
  600.     DIM MessageCount AS LONG ' Create the variables used for score, etc.
  601.     DIM MaxMessages AS LONG
  602.     DIM MaxScore AS LONG
  603.  
  604.     Keys FALSE ' Turn off the control keys.
  605.     PLAY GAMEOVERSONG ' Play the game end melody.
  606.     SOUND 38, 36 ' Tone at 38 hertz for 36 clock ticks.
  607.     FOR i = 1 TO XSCALE * .666 STEP 2 ' Draw an expanding explosion screen.
  608.         CIRCLE (XSCALE / 2, YSCALE / 2), i, ExplColor
  609.     NEXT i
  610.  
  611.     IF ScreenMode = 7 THEN
  612.         COLOR 15, ExplColor ' Display the ending score and wave for SCREEN 7.
  613.     ELSE
  614.         COLOR 0 ' Display for SCREEN 1.
  615.     END IF
  616.     LOCATE 1, 3: PRINT USING "Score: ###,###,###"; Score
  617.     LOCATE 1, ScreenWidth - 10: PRINT USING "Wave: ###"; Wave
  618.     OPEN "I", #1, "1QSPACE.SCO": INPUT #1, name$, Hscore: CLOSE #1
  619.     IF Score > Hscore THEN OPEN "O", #1, "1QSPACE.SCO": LOCATE 13, 1: PRINT " YOU HAVE BEATEN THE HIGH SCORE "
  620.     IF Score > Hscore THEN LOCATE 15, 1: INPUT "TYPE IN YOUR FIRST NAME"; name$: PRINT #1, name$: PRINT #1, Score: CLOSE #1: PRINT
  621.     IF Score > Hscore THEN LOCATE 13, 1: PRINT "                                   ": LOCATE 15, 1: PRINT "                                          "
  622.     IF Score > Hscore THEN LOCATE 15, 15: PRINT name$
  623.     IF Score > Hscore THEN LOCATE 18, 1: PRINT USING "HAS THE HIGH SCORE OF ###,###,###"; Score
  624.      
  625.    
  626.     LOCATE 3, 1
  627.     PRINT "Game statistics:" ' Print the player's game statistics.
  628.     LOCATE 5, 1
  629.     PRINT "Number of missiles destroyed:" + STR$(TotalIncoming)
  630.     LOCATE 7, 1
  631.     PRINT "Number of interceptors launched:" + STR$(TotalInterceptors)
  632.  
  633.     READ MaxMessages ' Read all the message choices from the DATA statements.
  634.  
  635.     DO ' DO loop to read the Rank$ and Message$ for display.  This loop will end when the MaxScore is greater than or equal to the player's Score.
  636.         READ Rank$, Message$ ' READ two elements from the next DATA statement.
  637.         MaxScore = MaxScore + 10000& + 20000& * MessageCount
  638.         MessageCount = MessageCount + 1 ' Increase message count.
  639.     LOOP WHILE MaxScore < Score AND MessageCount < MaxMessages
  640.     LOCATE 9, 1
  641.     PRINT Message$ ' Display Message$ in the center of line 15.
  642.     LOCATE 11, 1
  643.     PRINT "Rank:  " + Rank$, ' Display the matching rank on line 16.
  644.    
  645.     LOCATE 23, 1
  646.     PRINT "Would you like to try again? (Y/N)" ' Ask if player wants to play again.
  647.  
  648.     DO: LOOP UNTIL INKEY$ = "" ' Clears the keyboard input buffer.
  649.  
  650.     DO ' Wait for a 'y' or 'n' keypress.
  651.         A$ = UCASE$(INKEY$)
  652.     LOOP WHILE A$ <> "Y" AND A$ <> "N"
  653.  
  654.     IF A$ = "Y" THEN RUN "1qsapce" '  Player wants to start playing again.
  655.     IF A$ <> "Y" THEN ContinueGame = FALSE ' Player wants to end the game.
  656.    
  657.  
  658. '----------------------------------------------------------------------------
  659. ' HorizontalScroll
  660. '
  661. '    Displays a string moving across the screen at a given line.
  662. '    Assumes a 40 column display.
  663. '
  664. '                   PARAMETERS:     M$  - String to be displayed.
  665. '                                   Row - Screen row where string is displayed.
  666. '
  667. '----------------------------------------------------------------------------
  668. SUB HorizontalScroll (M$, Row)
  669.  
  670.     M$ = SPACE$(ScreenWidth + 2) + M$ ' Add ending spaces for display.
  671.     FOR i = 1 TO LEN(M$) - 1 ' Loop through the message in M$.
  672.         LOCATE Row, 1 ' Position the message on passed Row value.
  673.         PRINT MID$(M$, LEN(M$) - i, ScreenWidth - 1) ' Uses the MID$() function to print a ScreenWidth-1 character piece of the entire message.  The piece is determined by the value of X.
  674.         UpdateTarget ' Redraw the target crosshair in case the scrolling letters overwrite it.
  675.         Delay! = TIMER + .05 ' Delay the printing of each letter by .1 second.
  676.         DO WHILE TIMER < Delay!: LOOP
  677.     NEXT i
  678.  
  679.  
  680. '----------------------------------------------------------------------------
  681. ' InitFirebases
  682. '
  683. '    Draws two firebases at the lower left and right corners of the
  684. '    screen and fills them with color.
  685. '
  686. '                   PARAMETERS:     None
  687. '----------------------------------------------------------------------------
  688. SUB InitFirebases
  689.    
  690.     ' Draw the left missile launcher.
  691.     LINE (0, YSCALE - 6)-(10, YSCALE - 11), 14 ' Draw each side of the triangle.
  692.     LINE (0, YSCALE - 6)-(5, YSCALE - 1), 14
  693.     LINE (10, YSCALE - 11)-(5, YSCALE - 1), 14
  694.     PAINT (5, YSCALE - 6), 4, 14 ' Fill the triangle with color 4.
  695.    
  696.     ' Draw the right missile launcher.
  697.     LINE (XSCALE - 1, YSCALE - 6)-(XSCALE - 11, YSCALE - 11), 14
  698.     LINE (XSCALE - 11, YSCALE - 11)-(XSCALE - 6, YSCALE - 1), 14
  699.     LINE (XSCALE - 6, YSCALE - 1)-(XSCALE - 1, YSCALE - 6), 14
  700.     PAINT (XSCALE - 6, YSCALE - 6), 4, 14 ' Fill the triangle with color 4.
  701.  
  702.  
  703. '----------------------------------------------------------------------------
  704. ' InitScreen
  705. '
  706. '    Initializes the game. Clears the screen, draws the game pieces,
  707. '    and displays score and wave numbers.
  708. '
  709. '                   PARAMETERS:     None
  710. '----------------------------------------------------------------------------
  711. SUB InitScreen
  712.    
  713.     SCREEN 0 ' Clear the screen for each game.
  714.     SCREEN ScreenMode ' Change to the most appropriate screen mode.
  715.     SELECT CASE ScreenMode
  716.         CASE 7 ' Set colors for color screen.
  717.             PlanetColor = PLANETS7
  718.             EnemyColor = ENEMYCOLORS7
  719.             InterceptColor = INTERCEPTCOLORS7
  720.             ExplColor = EXPLCOLORS7
  721.             BaseColor = BASECOLORS7
  722.             GameBkGround = GAMEBKGROUNDS7
  723.             TargetColor = TARGETCOLORS7
  724.         CASE ELSE
  725.             PlanetColor = PLANETS1 ' Set colors for mono screen.
  726.             EnemyColor = ENEMYCOLORS1
  727.             InterceptColor = INTERCEPTCOLORS1
  728.             ExplColor = EXPLCOLORS1
  729.             BaseColor = BASECOLORS1
  730.             GameBkGround = GAMEBKGROUNDS1
  731.             TargetColor = TARGETCOLORS1
  732.     END SELECT
  733.    
  734.     COLOR , GameBkGround ' Change the background color.
  735.  
  736.     Target.x = XSCALE / 2 ' Setup first X position.
  737.     Target.Y = YSCALE / 2 + 5 ' Setup first Y position.
  738.     Target.OldX = Target.x ' Setup old target position as the current one.
  739.     Target.OldY = Target.Y
  740.     UpdateTarget ' Draw the initial target crosshair.
  741.  
  742.     DO: LOOP UNTIL INKEY$ = "" ' Clear keyboard input buffer.
  743.                        
  744.     UpdateScore ' Display the initial score and wave number.
  745.     ' Draw the planet edge here and fill the planet with PlanetColor.
  746.     CIRCLE (XSCALE / 2, YSCALE + 135), PLANETRADIUS, PlanetColor
  747.     PAINT (XSCALE / 2, YSCALE - 1), PlanetColor
  748.  
  749.  
  750. '----------------------------------------------------------------------------
  751. ' KeyPause
  752. '
  753. '    Suspends key event processing.  This is different than
  754. '    a KEY (X) OFF command because KEY (X) STOP stores key
  755. '    events and will fire them when KEY (X) ON is used.
  756. '
  757. '                   PARAMETERS:     None.
  758. '----------------------------------------------------------------------------
  759. SUB KeyPause
  760.     FOR i = 11 TO 20 ' Loop through all defined keys.
  761.         KEY(i) STOP
  762.     NEXT i
  763.  
  764. '----------------------------------------------------------------------------
  765. ' Keys
  766. '
  767. '    Turns key event processing on or off.
  768. '
  769. '      PARAMETERS:     TurnKeysOn - If it's TRUE then enable, otherwise
  770. '                      disable
  771. '----------------------------------------------------------------------------
  772. SUB Keys (TurnKeysOn)
  773.  
  774.     FOR i = 11 TO 20 ' Loop through all defined keys.
  775.         IF TurnKeysOn THEN
  776.             KEY(i) ON
  777.         ELSE
  778.             KEY(i) OFF
  779.         END IF
  780.     NEXT i
  781.  
  782.  
  783. '----------------------------------------------------------------------------
  784. ' LaunchMissile
  785. '
  786. '    Launches an interceptor or an enemy missile.
  787. '
  788. '     PARAMETERS:     Chosen  - Missile number to launch.
  789. '                     XStart  - X (horizontal) position of where the missile begins.
  790. '                     YStart  - Y (vertical) position of where the missile begins.
  791. '                     XFinish - X position of where the missile is aimed.
  792. '                     YFinish - Y position of where the missile is aimed.
  793. '----------------------------------------------------------------------------
  794. SUB LaunchMissile (Chosen, XStart, YStart, XFinish, YFinish)
  795.  
  796.     Incoming(Chosen).Active = TRUE ' Set the active status to TRUE.
  797.     Incoming(Chosen).XStart = XStart ' Set the initial X position.
  798.     Incoming(Chosen).YStart = YStart ' Set initial Y position.
  799.     Incoming(Chosen).XFinish = XFinish ' Set the missile's X
  800.     Incoming(Chosen).YFinish = YFinish '  and Y destination location.
  801.     Incoming(Chosen).x = XStart ' Set the missile's current X
  802.     Incoming(Chosen).Y = YStart '  and Y to the start.
  803.    
  804.     ' The code below determines which direction, either X or Y, is the
  805.     ' missile's primary direction.  Every time UpdateMissiles is called, the
  806.     ' missile will move in the primary direction.  MaxCount determines how many
  807.     ' primary moves are made before a secondary move is made but MaXCount is
  808.     ' not the actual number of moves since it is multiplied by RESOLUTION to
  809.     ' allow fast integer math to be used instead of slower floating-point.
  810.     ' Every time UpdateMissiles is called, Count is decreased by RESOLUTION.
  811.     ' When Count is less than 0, MaxCount added to Count and the missile moves
  812.     ' in the secondary direction.
  813.     XDistance = XFinish - XStart
  814.     YDistance = YFinish - YStart
  815.     Incoming(Chosen).XOffset = SGN(XDistance) ' Forces X and Y offsets that
  816.     Incoming(Chosen).YOffset = SGN(YDistance) '  are always -1, 0, or 1.
  817.  
  818.     IF ABS(XDistance) >= ABS(YDistance) THEN ' Missile moves more horizontally than vertically.
  819.         Incoming(Chosen).MaxCount = INT(ABS(XDistance) / (ABS(YDistance) + 1) * RESOLUTION) ' Determines how many horizontal moves to make before moving vertically.  RESOLUTION is used to round the value so fast integer math can be used.
  820.         Incoming(Chosen).YMajor = FALSE ' Sets flag to tell UpdateMissiles that primary direction is not Y.
  821.     ELSE ' Missile moves more vertically than horizontally.
  822.         Incoming(Chosen).MaxCount = INT(ABS(YDistance) / (ABS(XDistance) + 1) * RESOLUTION) ' Determines how many vertical moves to make before moving horizontally.
  823.         Incoming(Chosen).YMajor = TRUE ' Sets flag to tell UpdateMissiles that primary direction is Y.
  824.     END IF
  825.     Incoming(Chosen).Count = Incoming(Chosen).MaxCount ' Sets the number of times the missile has moved in the primary direction.
  826.  
  827. '----------------------------------------------------------------------------
  828. ' NewInterceptor
  829. '
  830. '    Determines if there is room for another interceptor, and if so,
  831. '    sets up another Incoming element and draw the crosshairs for a
  832. '    permanent target point.
  833. '
  834. '     PARAMETERS:     StartX - The X screen position to beginning of the missile trail.
  835. '                     StartY - The Y screen position to beginning of the missile trail.
  836. '----------------------------------------------------------------------------
  837. SUB NewInterceptor (StartX AS INTEGER, StartY AS INTEGER)
  838.  
  839.     IF NumIntercepts < 4 THEN ' Allow only 4 interceptor explosions on the screen at once.
  840.         NumIntercepts = NumIntercepts + 1 ' Increase total number of intercepts by one.
  841.         TotalInterceptors = TotalInterceptors + 1 ' Increase the number of total interceptors.
  842.      
  843.         Chosen = 7 ' Start at an offset of 7 because the Incoming array handles both enemy and player missiles.
  844.         DO UNTIL Incoming(Chosen).Active = FALSE ' DO loop to find the first unused Incoming element.
  845.             Chosen = Chosen + 1 ' Increase offset by one.
  846.         LOOP
  847.    
  848.         KeyPause ' Disable key event processing.
  849.         TargetX = Target.x ' Store the current crosshair x location
  850.         TargetY = Target.Y '  and y location, in case the crosshair moves while this subprogram is running.
  851.         Keys TRUE ' Enable key event processing.
  852.  
  853.         ' Draw the stationary crosshairs on the screen so we can see where the missile is heading.
  854.         LINE (TargetX - 5, TargetY - 5)-(TargetX + 5, TargetY + 5), TargetColor
  855.         LINE (TargetX + 5, TargetY - 5)-(TargetX - 5, TargetY + 5), TargetColor
  856.            
  857.         LaunchMissile Chosen, StartX, StartY, TargetX, TargetY
  858.     END IF
  859.  
  860.  
  861. '----------------------------------------------------------------------------
  862. ' NewMissile
  863. '
  864. '    Develops the boundaries and parameters for a new enemy missile
  865. '    to be fired. When completed, another enemy missile will be
  866. '    setup for drawing on the screen.
  867. '
  868. '           PARAMETERS:     None
  869. '----------------------------------------------------------------------------
  870. SUB NewMissile
  871.  
  872.     ' If WaveCount is more than the maximum enemy missile wave or ContinueGame isn't correct.
  873.     IF WaveCount = 10 + Wave * 2 OR ContinueGame <> TRUE THEN EXIT SUB
  874.      
  875.     WaveCount = WaveCount + 1 ' Increase WaveCount by one.
  876.     TotalIncoming = TotalIncoming + 1 ' Increase the total incoming count by one.
  877.     MissilesFlying = MissilesFlying + 1 ' Increase the count of missiles flying.
  878.    
  879.     DO ' DO loop to select which starbase is the target.
  880.         Targ = INT(RND(1) * MaxStarbases) + 1 ' Randomly select until we select one that is currently active.
  881.     LOOP UNTIL Starbase(Targ).Active = TRUE
  882.  
  883.     Chosen = 1 ' Select first available missile.
  884.     DO WHILE Incoming(Chosen).Active <> FALSE ' DO loop to determine the next available Incoming element.
  885.         Chosen = Chosen + 1 ' Increment offset by one.
  886.     LOOP
  887.  
  888.     XStart = INT(RND(1) * XSCALE - 1) + 1 ' Randomly select where to start.
  889.     YStart = 12
  890.     XFinish = Starbase(Targ).x ' Work variables to hold the selected starbase's X and Y position.
  891.     YFinish = Starbase(Targ).Y
  892.  
  893.     LaunchMissile Chosen, XStart, YStart, XFinish, YFinish
  894.  
  895.  
  896. '----------------------------------------------------------------------------
  897. ' NewStarbase
  898. '
  899. '    Determines a new starbase position and draws it in orbit around
  900. '    the planet.
  901. '
  902. '           PARAMETERS:     None
  903. '----------------------------------------------------------------------------
  904. SUB NewStarbase
  905.  
  906.     Chosen = 1 ' Setup initial starbase offset.
  907.     DO WHILE Starbase(Chosen).Active = TRUE ' DO until we find one that hasn't been initialized.
  908.         Chosen = Chosen + 1 ' Increase the offset by one.
  909.  
  910.     LOOP
  911.     BasesLeft = BasesLeft + 1 ' Increase the number of active bases by one.
  912.     DO ' DO loop to determine if the randomly chosen starbase is within range.
  913.         Angle! = RND(1) * 2 * PI ' Randomly select position along planet edge.
  914.         Y = SIN(Angle!) * PLANETRADIUS + YSCALE + 155 ' Set X and Y based on that angle.
  915.         x = COS(Angle!) * PLANETRADIUS + XSCALE / 2
  916.         TooClose = FALSE ' Assume that the new starbase is not too close to another one.
  917.  
  918.         FOR i = 1 TO MaxStarbases ' Loop to make sure there isn't a conflict with an existing starbase.
  919.             ' If starbase is close then set TooClose to TRUE.
  920.             IF ABS(Starbase(i).x - x) < 20 AND Starbase(i).Active = TRUE THEN TooClose = TRUE
  921.         NEXT i
  922.     LOOP WHILE Y > YSCALE - 11 OR TooClose = TRUE
  923.  
  924.     Starbase(Chosen).x = x ' Setup the chosen starbases X and Y coordinates.
  925.     Starbase(Chosen).Y = Y
  926.     Starbase(Chosen).Active = TRUE ' Set starbase active status to TRUE.
  927.     ' Draw the base in orbit around the planet.
  928.     CIRCLE (Starbase(Chosen).x, Starbase(Chosen).Y), 7, BaseColor, , , .3
  929.     PAINT (Starbase(Chosen).x, Starbase(Chosen).Y), BaseColor
  930.     LINE (Starbase(Chosen).x - XSCALE / FACTOR, Starbase(Chosen).Y - XSCALE / FACTOR)-(Starbase(Chosen).x + XSCALE / FACTOR, Starbase(Chosen).Y + XSCALE / FACTOR), 4, BF
  931.     PSET (Starbase(Chosen).x, Starbase(Chosen).Y - 3), 14
  932.     PSET (Starbase(Chosen).x, Starbase(Chosen).Y + 3), 14
  933.  
  934.  
  935. '----------------------------------------------------------------------------
  936. ' StopMissile
  937. '
  938. '    Stops the MNum missile and adjusts all global values that this
  939. '    operation affects.
  940. '
  941. '           PARAMETERS:     MNum      - Missile number to stop
  942. '                           WMissiles - Which type of missile: 1 = Incoming, 2 = Interceptor
  943. '----------------------------------------------------------------------------
  944. SUB StopMissile (MNum, WMissiles)
  945.  
  946.     EraseMissileTrail MNum ' Erase the given missile's trail.
  947.     Incoming(MNum).Active = FALSE ' Set incoming active status to FALSE.
  948.  
  949.     IF WMissiles = 1 THEN
  950.         UpdateScore ' Update the current score.
  951.         MissilesFlying = MissilesFlying - 1 ' Reduce the number of missiles currently flying.
  952.         ' If all of the enemy missiles for this wave have already flown, call WaveComplete subprogram.
  953.         IF WaveCount = 10 + 2 * Wave AND MissilesFlying = 0 THEN WaveComplete
  954.         NewMissile ' Start a new enemy missile flying.
  955.     ELSE
  956.         NumIntercepts = NumIntercepts - 1 ' Decrease the number of intercepted missiles.
  957.         XFinish = Incoming(MNum).XFinish ' Setup work variables for the finish point of the missile.
  958.         YFinish = Incoming(MNum).YFinish
  959.         ' Overwrite the target X with background.
  960.         LINE (XFinish - 5, YFinish - 5)-(XFinish + 5, YFinish + 5), GameBkGround
  961.         LINE (XFinish + 5, YFinish - 5)-(XFinish - 5, YFinish + 5), GameBkGround
  962.     END IF
  963.  
  964.  
  965. '----------------------------------------------------------------------------
  966. ' UpdateExplosions
  967. '
  968. '    Updates all currently active explosions in the Explosions array.
  969. '
  970. '           PARAMETERS:     None
  971. '----------------------------------------------------------------------------
  972. SUB UpdateExplosions
  973.  
  974.     FOR XNum = 1 TO 10 ' Loop for the number of possible concurrent explosions.
  975.         W = Explosion(XNum).Active ' Set work variable for active status of explosion element.
  976.         IF W > 0 THEN ' If this explosion is active.
  977.             x = Explosion(XNum).x ' Set work variables to explosion X and Y coordinates.
  978.             Y = Explosion(XNum).Y
  979.  
  980.             IF W > EXPLRADIUS THEN ' If explosion status (radius) is greater than the max radius.
  981.                 FOR T = 1 TO EXPLRADIUS ' Draw expanding circles with the background color to erase everything!
  982.                     CIRCLE (x, Y), T, GameBkGround
  983.                 NEXT T
  984.            
  985.                 ' Stop the missile that caused the explosion.
  986.                 StopMissile Explosion(XNum).MissileNum, Explosion(XNum).MType
  987.  
  988.                 FOR i = 1 TO MaxStarbases ' Loop through all starbases. If starbase is active and within the exploding missile's range, destroy starbase.
  989.                     IF Starbase(i).Active = TRUE AND ((x - Starbase(i).x) ^ 2 + (Y - Starbase(i).Y) ^ 2) ^ .5 - NEXPLRADIUS < -2 THEN DestroyStarbase i
  990.                 NEXT i
  991.          
  992.                 UpdateTarget ' Redraw the target crosshair.
  993.                 Explosion(XNum).Active = FALSE ' Set this explosion's active status to FALSE.
  994.             ELSE
  995.                 Explosion(XNum).Active = W + 1 ' Increase the status (radius) of current explosion.
  996.                 CIRCLE (x, Y), W, ExplColor ' Draw another circle to increase the explosion visually.
  997.                 UpdateTarget ' Redraw the target crosshair.
  998.             END IF
  999.         END IF
  1000.     NEXT XNum
  1001.  
  1002.  
  1003. '----------------------------------------------------------------------------
  1004. ' UpdateMissiles
  1005. '
  1006. '    Updates one of the two types of missiles by drawing the missile
  1007. '    one pixel more in its direction of travel.
  1008. '
  1009. '           PARAMETERS:     Start      - Where in the Incoming array to begin looking
  1010. '                           Finish     - Where to stop looking
  1011. '                           WMissiles  - Missile type to update (enemy or defense)
  1012. '                           NumOfTimes - Number of times to update the missiles
  1013. '                           ColorToUse - Color to use for the updated line
  1014. '
  1015. ' Note:  Start and Finish are not technically necessary since they can be
  1016. '        resolved from WMissiles.  Passing Start and Finish is faster than
  1017. '        determining them each time UpdateMissiles is called, however.
  1018. '----------------------------------------------------------------------------
  1019. SUB UpdateMissiles (Start, Finish, WMissiles, NumOfTimes, ColorToUse)
  1020.  
  1021.     FOR Chosen = Start TO Finish ' Loop through the possible missiles.
  1022.         IF Incoming(Chosen).Active = TRUE THEN ' If this incoming missile is active...
  1023.             x = Incoming(Chosen).x ' Use temporary local
  1024.             Y = Incoming(Chosen).Y '  variables for best speed.
  1025.             YOffset = Incoming(Chosen).YOffset
  1026.             XOffset = Incoming(Chosen).XOffset
  1027.             Count = Incoming(Chosen).Count
  1028.             MaxCount = Incoming(Chosen).MaxCount
  1029.             XFinish = Incoming(Chosen).XFinish
  1030.             YFinish = Incoming(Chosen).YFinish
  1031.        
  1032.             ' For maximum speed, use different routines for missiles that
  1033.             ' move mainly horizontally than for ones that move mainly
  1034.             ' vertically.
  1035.             IF Incoming(Chosen).YMajor THEN ' If missile is mainly vertical
  1036.                 FOR i = 1 TO NumOfTimes ' Do NumOfTimes
  1037.                     C = POINT(x, Y) ' Read the color of the point.
  1038.                     PSET (x, Y), ColorToUse ' Add a new point to the trail.
  1039.                     Count = Count - RESOLUTION ' Decrease the Count.
  1040.                     Y = Y + YOffset ' Move vertically.
  1041.            
  1042.                     IF Count <= 0 THEN ' Time for the horizontal move?
  1043.                         x = x + XOffset ' Yes.  Move horizontally.
  1044.                         Count = Count + MaxCount ' Prepare Count for the next horizontal movement.
  1045.                     END IF
  1046.            
  1047.                     ' Explode the missile if it hits another explosion, a base,
  1048.                     '  or reaches its target Y.
  1049.                     IF (C = ExplColor) OR (C = BaseColor) OR Y = YFinish THEN Explode Chosen, x, Y, WMissiles ' Explode the chosen missile given the current missile type
  1050.                 NEXT i
  1051.             ELSE ' Mainly horizontal
  1052.                 FOR i = 1 TO NumOfTimes ' Do NumOfTimes
  1053.                     C = POINT(x, Y) ' Read the color of the point.
  1054.                     PSET (x, Y), ColorToUse ' Add a new point to the trail.
  1055.                     Count = Count - RESOLUTION ' Decrease the Count.
  1056.                     x = x + XOffset ' Move horizontally.
  1057.            
  1058.                     IF Count <= 0 THEN ' Time for the vertical move?
  1059.                         Y = Y + YOffset ' Yes.  Move vertically.
  1060.                         Count = Count + MaxCount ' Prepare Count for the next vertical movement.
  1061.                     END IF
  1062.            
  1063.                     ' Explode the missile if it hits another explosion, a base,
  1064.                     '  or reaches its target X.
  1065.                     IF (C = ExplColor) OR (C = BaseColor) OR x = XFinish THEN Explode Chosen, x, Y, WMissiles '  Explode the chosen missile given the current missile type
  1066.                 NEXT i
  1067.             END IF
  1068.        
  1069.             ' Copy the temporary local variables back to the SHARED variables.
  1070.             Incoming(Chosen).Count = Count
  1071.             Incoming(Chosen).x = x
  1072.             Incoming(Chosen).Y = Y
  1073.        
  1074.         END IF
  1075.     NEXT Chosen
  1076.  
  1077.  
  1078. '----------------------------------------------------------------------------
  1079. ' UpdateScore
  1080. '
  1081. '    Calculates new score, then performs a formatted print of the
  1082. '    Score and Wave values.
  1083. '
  1084. '           PARAMETERS:     None
  1085. '----------------------------------------------------------------------------
  1086. SUB UpdateScore
  1087.  
  1088.     ' Calculate the new score.
  1089.     Score = Score + 10 * MissilesFlying * BasesLeft * Wave
  1090.  
  1091.     ' Locate and do a formatted print of the current score and wave numbers.
  1092.     LOCATE 1, 3: PRINT USING "Score: ###,###,###"; Score
  1093.     LOCATE 1, ScreenWidth - 10: PRINT USING "Wave: ###"; Wave
  1094.  
  1095.  
  1096. '----------------------------------------------------------------------------
  1097. ' UpdateTarget
  1098. '
  1099. '    Checks to see if the coordinates for the target are within the
  1100. '    boundaries and adjusts, if necessary.  Erases the old target
  1101. '    crosshair and draws the new target crosshair in its new
  1102. '    position.
  1103. '
  1104. '           PARAMETERS:     None
  1105. '----------------------------------------------------------------------------
  1106. SUB UpdateTarget
  1107.  
  1108.     ' If target goes off the screen horizontally, restore old horizontal position.
  1109.     IF Target.x > XSCALE - 5 OR Target.x < 5 THEN Target.x = Target.OldX
  1110.  
  1111.     ' Target cannot move above the SCORE line or below the top of the planet.
  1112.     IF Target.Y > YSCALE - 53 OR Target.Y < 15 THEN Target.Y = Target.OldY
  1113.  
  1114.     ' If the target is in a different position than when it was last updated.
  1115.     IF Target.x <> Target.OldX OR Target.Y <> Target.OldY THEN ' Erase the old target.
  1116.         LINE (Target.OldX, Target.OldY + 5)-(Target.OldX, Target.OldY - 5), 0
  1117.         LINE (Target.OldX - 5, Target.OldY)-(Target.OldX + 5, Target.OldY), 0
  1118.         Target.OldX = Target.x ' Make the old X and Y values equal to the current ones.
  1119.         Target.OldY = Target.Y
  1120.     END IF
  1121.  
  1122.     ' Draw new target crosshair in the new X and Y position.
  1123.     LINE (Target.x, Target.Y + 5)-(Target.x, Target.Y - 5), 14
  1124.     LINE (Target.x - 5, Target.Y)-(Target.x + 5, Target.Y), 14
  1125.  
  1126.  
  1127. '----------------------------------------------------------------------------
  1128. ' WaveComplete
  1129. '
  1130. '    Handles the screen output when a wave has been completed. Also
  1131. '    sets up information for the next wave.
  1132. '
  1133. '           PARAMETERS:     None
  1134. '----------------------------------------------------------------------------
  1135. SUB WaveComplete
  1136.    
  1137.     KEY(15) OFF ' Disable the Pause key.
  1138.     KEY(16) OFF ' Disable the Quit key.
  1139.    
  1140.     WaveCount = 0 ' Reset the WaveCount variable that holds home many missiles have been launched in the current wave.
  1141.     WaveInterceptCount = 0 ' Reset the counter for the number of interceptors launched in the wave.
  1142.     Score = Score + (Wave * 1000) ' Calculate bonus points.
  1143.     Wave = Wave + 1 ' Increment to the next wave.
  1144.     PLAY WAVEOVERSONG ' Play the wave-end melody.
  1145.  
  1146.     ' Move the Wave Over, etc. message across the screen.
  1147.     M$ = STR$(1000 * (Wave - 1)) + " point bonus!" + SPACE$(20) + "Wave" + STR$(Wave - 1) + " Complete!"
  1148.     HorizontalScroll M$, 10
  1149.     FOR XNum = 1 TO 10 ' Loop through the 10 possible explosions.
  1150.         IF Explosion(XNum).Active > 0 THEN ' If exploding now, explosion(mnum%).active will be greater than 0 (the radius of the explosion).
  1151.             x! = Explosion(XNum).x ' Get the X coordinate of the explosion.
  1152.             Y! = Explosion(XNum).Y ' Get the Y coordinate of the explosion.
  1153.        
  1154.             FOR T = 1 TO NEXPLRADIUS ' Draw expanding circles with the background color to erase everything.
  1155.                 CIRCLE (x!, Y!), T, GameBkGround
  1156.             NEXT T
  1157.        
  1158.             StopMissile Explosion(XNum).MissileNum, Explosion(XNum).MType
  1159.          
  1160.             FOR i = 1 TO MaxStarbases ' Loop through all starbases. If starbase is active and within the exploding missile's range, destroy starbase.
  1161.                 IF Starbase(i).Active = TRUE AND ((x! - Starbase(i).x) ^ 2 + (Y! - Starbase(i).Y) ^ 2) ^ .5 - NEXPLRADIUS < -2 THEN DestroyStarbase i
  1162.             NEXT i
  1163.      
  1164.             UpdateTarget ' Redraw the target crosshair.
  1165.             Explosion(XNum).Active = FALSE ' Reset the active flag so explosion can be re-used.
  1166.      
  1167.         END IF
  1168.     NEXT XNum
  1169.  
  1170.     FOR i = 1 TO 10 ' Loop through all missiles (both interceptor and enemy).
  1171.         IF Incoming(i).Active <> 0 THEN ' If it's flying or frozen,
  1172.             EraseMissileTrail i ' erase it.
  1173.             IF i > 6 THEN ' If it is an interceptor missile:
  1174.                 XFinish = Incoming(i).XFinish ' Store X coordinate of the missile's final target.
  1175.                 YFinish = Incoming(i).YFinish ' Get Y coordinate.
  1176.                 ' Erase the target at this line.
  1177.                 LINE (XFinish - 5, YFinish - 5)-(XFinish + 5, YFinish + 5), GamBkGround ' Erase the target X.
  1178.                 LINE (XFinish + 5, YFinish - 5)-(XFinish - 5, YFinish + 5), GameBkGround
  1179.             END IF
  1180.  
  1181.         END IF
  1182.         Incoming(i).Active = FALSE ' Reset the active flag so missile can be re-used.
  1183.     NEXT i
  1184.  
  1185.     ' If score is high enough score, add another starbase if there's room.
  1186.     IF Score > NextNewBase THEN
  1187.         ' Move the Wave Over, etc. message across the screen.
  1188.         M$ = STR$(10000 * Wave) + " Extra point bonus!"
  1189.         HorizontalScroll M$, 10
  1190.         Score = Score + (Wave * 10000) ' Calculate bonus points.
  1191.         NextNewBase = NextNewBase + 75000 ' Determine when next new starbase will possibly be awarded.
  1192.     END IF
  1193.     CLS
  1194.     ' Determine how to make the next wave more difficult.
  1195.     IF NumMissiles > 6 THEN NumMissiles = 6
  1196.     IF NumMissiles < 6 THEN NumMissiles = NumMissiles + 1 ' If an even number wave, increase the # of missiles unless the maximum (6) has already been reached.
  1197.     IncomingDelay = IncomingDelay * .66667 ' Otherwise, make the incoming missiles 33% faster unless already at maximum speed.
  1198.     IF IncomingDelay < FASTESTMISSILE THEN IncomingDelay = FASTESTMISSILE
  1199.  
  1200.  
  1201.     UpdateScore ' Show new score and wave.
  1202.  
  1203.     FOR i = 1 TO NumMissiles - 1 ' Create the new missiles (one more will be added by the StopMissile subprogram when WaveComplete is finished).
  1204.         NewMissile
  1205.     NEXT i
  1206.  
  1207.     NumIntercepts = 0 ' Reset the number of interceptors.
  1208.     NumExplosions = 0 ' Reset the number of explosions.
  1209.     LINE (1, MINY)-(XSCALE, YSCALE - 51), 0, BF ' Erase this area and cover with black.
  1210.    
  1211.     DO: LOOP UNTIL INKEY$ = "" ' Clear keyboard input buffer.
  1212.     Keys TRUE ' Enable key event processing.
  1213.  
  1214.     FOR GGG = 135 TO 165 'Redraw  planet
  1215.         CIRCLE (XSCALE / 2, YSCALE + GGG), PLANETRADIUS, PlanetColor
  1216.     NEXT GGG
  1217.  
  1218.     InitFirebases
  1219.     Chosen = 1 ' Setup initial starbase offset.
  1220.  
  1221.     ' Draw the base in orbit around the planet.
  1222.     CIRCLE (Starbase(Chosen).x, Starbase(Chosen).Y), 7, BaseColor, , , .3
  1223.     PAINT (Starbase(Chosen).x, Starbase(Chosen).Y), BaseColor
  1224.     LINE (Starbase(Chosen).x - XSCALE / FACTOR, Starbase(Chosen).Y - XSCALE / FACTOR)-(Starbase(Chosen).x + XSCALE / FACTOR, Starbase(Chosen).Y + XSCALE / FACTOR), 4, BF
  1225.     PSET (Starbase(Chosen).x, Starbase(Chosen).Y - 3), 14
  1226.     PSET (Starbase(Chosen).x, Starbase(Chosen).Y + 3), 14
  1227.  
  1228.  


Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: need help with mouse in qb program
« Reply #22 on: September 04, 2019, 11:52:42 am »
I thought sound played independent of code, which makes it hard to sync graphics, but Petr you are the sound guy I think!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: need help with mouse in qb program
« Reply #23 on: September 04, 2019, 12:00:26 pm »
Try the last version and tell me your opinion. I'm not a great sound expert. Expert is _SNDRAW author, not me.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: need help with mouse in qb program
« Reply #24 on: September 04, 2019, 12:06:01 pm »
I will after lunch and errands, thanks Petr!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: need help with mouse in qb program
« Reply #25 on: September 04, 2019, 12:12:33 pm »
Yeah, time shift! I almost forgot. Enjoy your meal! I'll go to dinner in a minute. The internet is a wonderful thing. And this game is great!

Offline tuc47

  • Newbie
  • Posts: 12
    • View Profile
Re: need help with mouse in qb program
« Reply #26 on: September 04, 2019, 12:13:28 pm »
it does work but the original verson was faster but I can not get it to run.
is there a way I can set the starbase to a specif  location?

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: need help with mouse in qb program
« Reply #27 on: September 04, 2019, 12:37:04 pm »
Star base location is generated randomly on the planet radius. See to SUB NewStarBase:    Angle! = RND(1) * 2 * PI ' Randomly select position along planet edge.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: need help with mouse in qb program
« Reply #28 on: September 04, 2019, 12:50:56 pm »
So set it with a specific angle 0 to 2*pi, pi/2 = 90, pi =180, 3*pi/2 = 270

Angle! = _PI* something

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: need help with mouse in qb program
« Reply #29 on: September 04, 2019, 01:08:19 pm »
Hi Petr and tuc47,

Tried Petr's code and the mouse is all over with slightest jiggle, PLUS anywhere I shoot everything blows up.

Nice for points, just pull the trigger but where is skill involved? Nice explosion sound though :D