QB64.org Forum

Samples Gallery & Reference => Games => Topic started by: bplus on March 06, 2020, 11:40:54 am

Title: QB64 Simon by TerryRitchie
Post by: bplus on March 06, 2020, 11:40:54 am
QB64 Simon

Author: @TerryRitchie
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=2263
Version: 1.0 written March, 2015
Tags: [Retro] [Sim]

Description:
An exact replica of the Simon game from the 1980's (with added QB64 bee graphic).
Game play can be done with keyboard, mouse, or both. Press F1 for a help screen.


Source:
Code: QB64: [Select]
  1. '*
  2. '*                                    ------------------
  3. '*                                    --- QB64 Simon ---
  4. '*                                    ------------------
  5. '*
  6. '*                                     By Terry Ritchie
  7. '*
  8. '*                       Written from March 22nd to March 28th, 2015
  9. '*                                       Version 1.0
  10. '*
  11.  
  12. '--------------------------------
  13. '- VARIABLE DECLARATION SECTION -
  14. '--------------------------------
  15.  
  16. CONST FALSE = 0 '        boolean: false indicator
  17. CONST TRUE = NOT FALSE ' boolean: true indicator
  18. CONST MOUSE% = 200 '     call PADPRESS with mouse button
  19.  
  20. DIM Pad&(3, 1) '         color pads: 0,x=BLUE, 1,x=RED, 2,x=GREEN, 3,x=YELLOW
  21. DIM PadXY%(3, 1) '       x,y locations of color pads
  22. DIM Tone&(4) '           game sounds: 0=BLUE, 1=RED, 2=GREEN, 3=YELLOW, 4=LOSE
  23. DIM Simon& '             simon graphics image
  24. DIM SimonHelp& '         simon help screen
  25. DIM Keys&(3, 1) '        keyboard key images 0=Q, 1=W, 2=S, 3=A
  26. DIM Bslider& '           blue slider switch image
  27. DIM Rslider& '           red slider switch image
  28. DIM OnOff& '             on/off slider switch
  29. DIM KeysXY%(3, 1) '      location of keyboard key images on play screen
  30. DIM GameOver% '          boolean: true when game has ended
  31. DIM Game% '              the position the blue slider switch is in (0-2)
  32. DIM Skill% '             the position the red slider switch is in (0-3)
  33. DIM GameDir% '           the direction blue slider switch will move (1, -1)
  34. DIM SkillDir% '          the direction red slider switch will move (1, -1)
  35. DIM Longest$ '           the longest tune correctly played by a player
  36. DIM Last$ '              the last tune played by the player
  37. DIM Count% '             generic counter
  38. DIM KeyPress$ '          any keys pressed by the player
  39. DIM Pcolor~&(3) '        color pad base colors: 0=BLUE, 1=RED, 2=GREEN, 3=YELLOW
  40.  
  41. '----------------
  42. '- MAIN PROGRAM -
  43. '----------------
  44.  
  45. INITIALIZE '                                                       prepare graphics, sounds and variables
  46. SCREEN _NEWIMAGE(640, 640, 32) '                                   create game screen
  47. _TITLE "QB64 SIMON" '                                              give game screen a title
  48. _SCREENMOVE _MIDDLE '                                              move game screen to middle of desktop
  49. _DELAY .5 '                                                        light delay to move to middle of screen
  50. CLS '                                                              remove black transparency
  51. DO '                                                               BEGIN MAIN GAME LOOP
  52.     GameOver% = FALSE '                                            reset game over flag
  53.     PRESSPAD 0, 0 '                                                reset game board
  54.     _DISPLAY
  55.     DO '                                                           BEGIN PLAY GAME LOOP
  56.         _LIMIT 120 '                                               limit to 120 loops per second
  57.         WHILE _MOUSEINPUT: WEND '                                  get to last mouse event
  58.         IF _MOUSEBUTTON(1) THEN '                                  did player click left mouse button?
  59.             IF POINTER%(232 + Game% * 10, 323, 289 + Game% * 10, 345) THEN ' test blue slider area?
  60.                 IF Game% = 0 OR Game% = 2 THEN '                   yes, is blue slider at its limit?
  61.                     GameDir% = -GameDir% '                         yes, reverse blue slider direction
  62.                 END IF
  63.                 Game% = Game% + GameDir% '                         change game level
  64.                 PRESSPAD 0, .125 '                                 display change on screen
  65.                 WAIT4RELEASE
  66.             ELSEIF POINTER%(319 + Skill% * 10, 323, 375 + Skill% * 10, 345) THEN ' test red slider area?
  67.                 IF Skill% = 0 OR Skill% = 3 THEN '                 yes, is red slider at its limit?
  68.                     SkillDir% = -SkillDir% '                       yes, reverse red slider direction
  69.                 END IF
  70.                 Skill% = Skill% + SkillDir% '                      change skill level
  71.                 PRESSPAD 1, .125 '                                 display change on screen
  72.                 WAIT4RELEASE
  73.             ELSEIF POINTER%(254, 371, 271, 388) THEN '             test last button area?
  74.                 WAIT4RELEASE
  75.                 FOR Count% = 1 TO LEN(Last$) '                     cycle through last tune string
  76.                     PRESSPAD VAL(MID$(Last$, Count%, 1)), .5 '     play each individual tone
  77.                     _DELAY .125 '                                  pause for 1/8 second
  78.                 NEXT Count%
  79.             ELSEIF POINTER%(371, 371, 388, 388) THEN '             test longest button area?
  80.                 Count% = 0 '                                       yes, reset 1/120 counter
  81.                 DO '                                               BEGIN MOUSE RELEASE LOOP
  82.                     _LIMIT 120 '                                   don't hog CPU while looping
  83.                     WHILE _MOUSEINPUT: WEND '                      get to last mouse event
  84.                     Count% = Count% + 1 '                          increment 1/120 second counter
  85.                     IF Count% > 360 THEN '                         have 3 seconds elapsed?
  86.                         FOR Count% = 0 TO 3 '                      yes, cycle through all four color pads
  87.                             PRESSPAD Count%, .125 '                light pad and play tone quickly
  88.                         NEXT Count%
  89.                         Longest$ = "" '                            reset longest tune string
  90.                         SIMONFILE 2 '                              delete simon.sav file
  91.                     END IF
  92.                 LOOP UNTIL NOT _MOUSEBUTTON(1) '                   END MOUSE RELEASE LOOP when left button released
  93.                 FOR Count% = 1 TO LEN(Longest$) '                  cycle through longest tune string
  94.                     PRESSPAD VAL(MID$(Longest$, Count%, 1)), .5 '  play each individual tone
  95.                     _DELAY .125 '                                  pause 1/8 second
  96.                 NEXT Count%
  97.             ELSEIF POINTER%(314, 371, 331, 388) THEN '             test start button area?
  98.                 _DELAY .5 '                                        1/2 second delay before game start
  99.                 PLAYGAME '                                         play game
  100.             ELSEIF POINTER%(321, 408, 332, 419) THEN '             test power button slider area?
  101.                 ENDGAME '                                          yes, end the game
  102.             END IF
  103.         END IF
  104.         KeyPress$ = INKEY$ '                                       get any key player may have pressed
  105.         IF KeyPress$ = CHR$(0) + CHR$(59) THEN '                   did player press the F1 key?
  106.             DISPLAYHELP '                                          yes, display help screen to player
  107.         END IF
  108.     LOOP UNTIL GameOver% '                                         END PLAY GAME LOOP
  109. LOOP '                                                             MAIN GAME LOOP end
  110.  
  111. '--------------------
  112. '- END MAIN PROGRAM -
  113. '--------------------
  114.  
  115. '---------------------------
  116. '- SUBROUTINES & FUNCTIONS -
  117. '---------------------------
  118.  
  119. '----------------------------------------------------------------------------------------------------------------------
  120. '                                                                                                           DISPLAYHELP
  121. SUB DISPLAYHELP ()
  122.  
  123.     '---------------------------------------
  124.     '- Display the help screen to the player
  125.     '---------------------------------------
  126.  
  127.     SHARED SimonHelp& ' simon help screen
  128.  
  129.     _PUTIMAGE (0, 0), SimonHelp& '                display help screen
  130.     _DISPLAY '                                    update screen with change
  131.     DO '                                          BEGIN KEY/MOUSE LOOP
  132.         _LIMIT 120 '                              don't hog the CPU
  133.         WHILE _MOUSEINPUT: WEND '                 get latest mouse events
  134.     LOOP UNTIL INKEY$ <> "" OR _MOUSEBUTTON(1) '  END KEY/MOUSE LOOP when left button clicked or key pressed
  135.     PRESSPAD 0, 0 '                               restore game screen
  136.  
  137.  
  138. '----------------------------------------------------------------------------------------------------------------------
  139. '                                                                                                          WAIT4RELEASE
  140. SUB WAIT4RELEASE ()
  141.  
  142.     '--------------------------------------------
  143.     '- Waits for left mouse button to be released
  144.     '--------------------------------------------
  145.  
  146.     DO '                             BEGIN MOUSE RELEASE LOOP
  147.         _LIMIT 120 '                 don't hog the CPU
  148.         WHILE _MOUSEINPUT: WEND '    get to last mouse event
  149.     LOOP UNTIL NOT _MOUSEBUTTON(1) ' END MOUSE RELEASE LOOP when left button released
  150.  
  151.  
  152. '----------------------------------------------------------------------------------------------------------------------
  153. '                                                                                                             SIMONFILE
  154. SUB SIMONFILE (Task%)
  155.  
  156.     '------------------------------------------
  157.     '- Loads, updates, or deletes the save file
  158.     '-
  159.     '- Task%: 0 - load file
  160.     '-        1 - update file
  161.     '-        2 - delete file
  162.     '------------------------------------------
  163.  
  164.     SHARED Longest$ ' the longest tune correctly played by a player
  165.  
  166.     SELECT CASE Task% '                            load, update, or delete?
  167.         CASE 0 '                                   load file
  168.             IF _FILEEXISTS("simon.sav") THEN '     does the save file exist?
  169.                 OPEN "simon.sav" FOR INPUT AS #1 ' yes, open the file for reading
  170.                 LINE INPUT #1, Longest$ '          get the longest tune ever played
  171.                 CLOSE #1 '                         close the file
  172.             END IF
  173.         CASE 1 '                                   update file
  174.             OPEN "simon.sav" FOR OUTPUT AS #1 '    open the file for output
  175.             PRINT #1, Longest$ '                   write the longest tune ever played
  176.             CLOSE #1 '                             close the file
  177.         CASE 2 '                                   delete file
  178.             IF _FILEEXISTS("simon.sav") THEN '     does the save file exist?
  179.                 KILL "simon.sav" '                 yes, delete it
  180.             END IF
  181.     END SELECT
  182.  
  183.  
  184. '----------------------------------------------------------------------------------------------------------------------
  185. '                                                                                                              POINTER%
  186. FUNCTION POINTER% (x1%, y1%, x2%, y2%)
  187.  
  188.     '------------------------------------------------------------------------------
  189.     '- Returns TRUE if the mouse pointer falls within x1%,y1% - x2%,y2% coordinates
  190.     '-
  191.     '- x1%: upper left  hand corner x coordinate of box area
  192.     '- y1%: upper left  hand corner y coordinate of box area
  193.     '- x2%: lower right hand corner x coordinate of box area
  194.     '- y2%: lower right hand corner y coordinate of box area
  195.     '------------------------------------------------------------------------------
  196.  
  197.     DIM mx% ' current mouse pointer x coordinate
  198.     DIM my% ' current mouse pointer y coordinate
  199.  
  200.     POINTER% = FALSE '                assume pointer does not fall within coordinates
  201.     WHILE _MOUSEINPUT: WEND '         get latest mouse event
  202.     mx% = _MOUSEX '                   get current mouse pointer x coordinate
  203.     my% = _MOUSEY '                   get current mouse pointer y coordinate
  204.     IF mx% >= x1% THEN '              could pointer be within x coordinates?
  205.         IF mx% <= x2% THEN '          yes, is pointer within x coordinates?
  206.             IF my% >= y1% THEN '      yes, could pointer be within y coordinates?
  207.                 IF my% <= y2% THEN '  yes, is pointer within y coordinates?
  208.                     POINTER% = TRUE ' yes, report back that pointer falls within coordinates
  209.                 END IF
  210.             END IF
  211.         END IF
  212.     END IF
  213.  
  214.  
  215. '----------------------------------------------------------------------------------------------------------------------
  216. '                                                                                                              PLAYGAME
  217. SUB PLAYGAME ()
  218.  
  219.     '-----------------------
  220.     '- Plays a game of simon
  221.     '-----------------------
  222.  
  223.     SHARED GameOver% ' boolean: true when game has ended
  224.     SHARED Game% '     the position the blue slider switch is in (0-2)
  225.     SHARED Skill% '    the position the red slider switch is in (0-3)
  226.     SHARED Longest$ '  the longest tune correctly played by a player
  227.     SHARED Last$ '     the last tune played by the player
  228.  
  229.     DIM Tune$ '        string of random tunes generated during game play
  230.     DIM KeyPress& '    contains value of any key pressed
  231.     DIM PlaySpeed! '   speed that simon plays notes
  232.     DIM Count% '       generic counter
  233.     DIM Notes% '       player note counter
  234.     DIM PadPress% '    value of colored pad pressed by player
  235.     DIM Plongest$ '    current player's longest tune
  236.     DIM Win% '         number of correct tones to win
  237.  
  238.     '-------------
  239.     '- MAIN CODE -
  240.     '-------------
  241.  
  242.     PRESSPAD 0, 0 '                                                 reset game screen
  243.     PlaySpeed! = 1 '                                                reset game speed
  244.     Win% = 12 + Skill% * 6 '                                        calculate number of tones to win
  245.     Tune$ = "" '                                                    reset random tune string
  246.     DO '                                                            BEGIN PLAY GAME LOOP
  247.         FOR Count% = 1 TO Game% + 1 '                               number of notes to add
  248.             Tune$ = Tune$ + LTRIM$(RTRIM$(STR$(INT(RND(1) * 4)))) ' add a random tone
  249.             IF LEN(Tune$) MOD 3 = 0 THEN '                          divisible evenly by 3?
  250.                 PlaySpeed! = PlaySpeed! - .125 '                    yes, increase speed of play
  251.                 IF PlaySpeed! < .125 THEN PlaySpeed! = .125 '       keep play speed at certain minimum
  252.             END IF
  253.         NEXT Count%
  254.         FOR Count% = 1 TO LEN(Tune$) '                              cycle through the tones
  255.             PRESSPAD VAL(MID$(Tune$, Count%, 1)), PlaySpeed! '      play the tone
  256.             _DELAY PlaySpeed! / 4 '                                 pause between tones
  257.         NEXT Count%
  258.         Notes% = 0 '                                                reset player note count
  259.         DO '                                                        BEGIN PLAY ROUND LOOP
  260.             DO '                                                    BEGIN BUFFER CLEAR LOOP
  261.                 _LIMIT 120 '                                        don't hog CPU
  262.                 KeyPress& = _KEYHIT '                               get keypress from keyboard buffer
  263.             LOOP WHILE KeyPress& '                                  END BUFFER CLEAR LOOP when buffer clear
  264.             Notes% = Notes% + 1 '                                   increment player note count
  265.             PadPress% = PLAYERINPUT% '                              get player's next color pad press
  266.             IF PadPress% <> VAL(MID$(Tune$, Notes%, 1)) THEN '      did the player press the right color pad?
  267.                 GameOver% = TRUE '                                  no, set game over flag
  268.                 PRESSPAD 4, 2 '                                     play loser sound and light up simon
  269.             END IF
  270.         LOOP UNTIL Notes% = LEN(Tune$) OR GameOver% '               END PLAY ROUND LOOP when player success or game over
  271.         IF NOT GameOver% THEN Plongest$ = Tune$ '                   remember last attempt as player's longest
  272.         IF Notes% = Win% THEN '                                     did player win?
  273.             GameOver% = TRUE '                                      yes, set game over
  274.             FOR Win% = 1 TO 6 '                                     cycle 6 times
  275.                 FOR Count% = 0 TO 3 '                               cycle through all color pads
  276.                     PRESSPAD Count%, .125 '                         press color pad
  277.                 NEXT Count%
  278.             NEXT Win%
  279.         END IF
  280.         _DELAY PlaySpeed! * 2 '                                     slight delay between rounds
  281.     LOOP UNTIL GameOver% '                                          END PLAY GAME LOOP when game over
  282.     Last$ = Tune$ '                                                 remember the entire last tune played
  283.     IF LEN(Plongest$) > LEN(Longest$) THEN '                        did player set a new longest record?
  284.         Longest$ = Plongest$ '                                      yes, remember the new longest tune
  285.         SIMONFILE 1 '                                               update simon.sav with new longest tune
  286.     END IF
  287.  
  288.  
  289. '----------------------------------------------------------------------------------------------------------------------
  290. '                                                                                                          PLAYERINPUT%
  291. FUNCTION PLAYERINPUT% ()
  292.  
  293.     ' -----------------------------------------------------------------------
  294.     ' Waits for player input then returns the color pad pressed by the player
  295.     ' -----------------------------------------------------------------------
  296.  
  297.     SHARED Pcolor~&() ' color pad base colors: 0=BLUE, 1=RED, 2=GREEN, 3=YELLOW
  298.  
  299.     DIM PadPress% '     the color pad that was pressed
  300.     DIM KeyPress& '     a key the player has pressed
  301.     DIM mx% '           current mouse pointer x coordinate
  302.     DIM my% '           current mouse pointer y coordinate
  303.     DIM Clr~& '         color of pixel clicked on
  304.  
  305.     PadPress% = -1 '                                                      reset pad press indicator
  306.     DO '                                                                  BEGIN INPUT LOOP
  307.         _LIMIT 120 '                                                      don't hog the CPU
  308.         KeyPress& = _KEYHIT '                                             get the latest key status
  309.         WHILE _MOUSEINPUT: WEND '                                         get the latest mouse status
  310.         IF KeyPress& THEN '                                               was a key pressed?
  311.             SELECT CASE KeyPress& '                                       yes, which one?
  312.                 CASE 81, 113 '                                            Q or q key
  313.                     PRESSPAD 0, KeyPress& '                               press blue pad on simon
  314.                     PadPress% = 0 '                                       remember blue pad pressed
  315.                 CASE 87, 119 '                                            W or w key
  316.                     PRESSPAD 1, KeyPress& '                               press red pad on simon
  317.                     PadPress% = 1 '                                       remember red pad pressed
  318.                 CASE 83, 115 '                                            S or s key
  319.                     PRESSPAD 2, KeyPress& '                               press green pad on simon
  320.                     PadPress% = 2 '                                       remember green pad pressed
  321.                 CASE 65, 97 '                                             A or a key
  322.                     PRESSPAD 3, KeyPress& '                               press yellow pad on simon
  323.                     PadPress% = 3 '                                       remember yellow pad pressed
  324.             END SELECT
  325.         ELSEIF _MOUSEBUTTON(1) THEN '                                     no, was the left mouse button clicked?
  326.             mx% = _MOUSEX '                                               yes, get x location of mouse pointer
  327.             my% = _MOUSEY '                                               get y location of mouse pointer
  328.             Clr~& = POINT(mx%, my%)
  329.             IF mx% < 320 AND my% < 320 AND Clr~& = Pcolor~&(0) THEN '     pointer in blue area?
  330.                 PRESSPAD 0, MOUSE% '                                      yes, press blue pad on simon
  331.                 PadPress% = 0 '                                           remember blue pad pressed
  332.             ELSEIF mx% > 319 AND my% < 320 AND Clr~& = Pcolor~&(1) THEN ' no, pointer in red area?
  333.                 PRESSPAD 1, MOUSE% '                                      yes, press red pad on simon
  334.                 PadPress% = 1 '                                           remember red pad pressed
  335.             ELSEIF mx% > 319 AND my% > 319 AND Clr~& = Pcolor~&(2) THEN ' no, pointer in green area?
  336.                 PRESSPAD 2, MOUSE% '                                      yes, press green pad on simon
  337.                 PadPress% = 2 '                                           remember green pad pressed
  338.             ELSEIF mx% < 320 AND my% > 319 AND Clr~& = Pcolor~&(3) THEN ' no, pointer in yellow area?
  339.                 PRESSPAD 3, MOUSE% '                                      yes, press yellow pad on simon
  340.                 PadPress% = 3 '                                           remember yellow pad pressed
  341.             END IF
  342.         END IF
  343.     LOOP UNTIL PadPress% <> -1 '                                          END INPUT LOOP when simon pad pressed
  344.     PLAYERINPUT% = PadPress% '                                            return the pad that was pressed
  345.  
  346.  
  347. '----------------------------------------------------------------------------------------------------------------------
  348. '                                                                                                              PRESSPAD
  349. SUB PRESSPAD (PadNum%, Behavior!)
  350.  
  351.     ' -----------------------------------------------------------------------------------------
  352.     ' Simulates pressing a colored pad by lighting it up and playing its corresponding sound
  353.     '
  354.     ' PadNum%   - The colored pad to press: 0=BLUE, 1=RED, 2=GREEN, 3=YELLOW, 4=ALL
  355.     ' Behavior! - If value is less than 5 then sound plays for this duration
  356.     '           - If value is less than 120 then sound plays until scancode of key is released
  357.     '           - if value > 120 then sound plays until left mouse button is released
  358.     '           - if value is zero then game board is redrawn only
  359.     ' -----------------------------------------------------------------------------------------
  360.  
  361.     SHARED Tone&() '   game sounds
  362.     SHARED Pad&() '    color pads: 0,x=BLUE, 1,x=RED, 2,x=GREEN, 3,x=YELLOW
  363.     SHARED PadXY%() '  x,y locations of color pads
  364.     SHARED Simon& '    simon graphics image
  365.     SHARED Keys&() '   keyboard key images 0=Q, 1=W, 2=S, 3=A
  366.     SHARED KeysXY%() ' location of keyboard key images
  367.     SHARED Bslider& '  blue slider switch image
  368.     SHARED Rslider& '  red slider switch image
  369.     SHARED OnOff& '    on/off slider switch
  370.     SHARED Game% '     the position the blue slider switch is in (0-2)
  371.     SHARED Skill% '    the position the red slider switch is in (0-3)
  372.  
  373.     DIM KeyPress& '    key press value
  374.     DIM KeyStatus% '   0=no key animation, 1=key animation
  375.  
  376.     '-------------
  377.     '- MAIN CODE -
  378.     '-------------
  379.  
  380.     KeyStatus% = 1 '                                                                           assume key animation
  381.     IF Behavior! THEN '                                                                        just a board redraw?
  382.         IF Behavior! = MOUSE% OR Behavior! < 5 THEN '                                          turn key animation off?
  383.             KeyStatus% = 0 '                                                                   yes, turn animation off
  384.         END IF
  385.         IF PadNum% <> 4 THEN '                                                                 single color pad selected?
  386.             _PUTIMAGE (PadXY%(PadNum%, 0), PadXY%(PadNum%, 1)), Pad&(PadNum%, 1) '             yes, light color pad
  387.             _PUTIMAGE (KeysXY%(PadNum%, 0), KeysXY%(PadNum%, 1)), Keys&(PadNum%, KeyStatus%) ' animate key if needed
  388.         ELSE '                                                                                 no, all color pads selected
  389.             FOR Count% = 0 TO 3 '                                                              cycle through all color pads
  390.                 _PUTIMAGE (PadXY%(Count%, 0), PadXY%(Count%, 1)), Pad&(Count%, 1) '            light color pad
  391.                 _PUTIMAGE (KeysXY%(Count%, 0), KeysXY%(Count%, 1)), Keys&(Count%, 0) '         set keys to raised position
  392.             NEXT Count%
  393.         END IF
  394.         _PUTIMAGE (200, 200), Simon& '                                                         place round simon image
  395.         _PUTIMAGE (232 + Game% * 10, 323), Bslider& '                                          place blue slider
  396.         _PUTIMAGE (319 + Skill% * 10, 323), Rslider& '                                         place red slider
  397.         _PUTIMAGE (321, 408), OnOff& '                                                         place power button slider
  398.         _DISPLAY '                                                                             update screen with changes
  399.         _SNDLOOP Tone&(PadNum%) '                                                              sound into continuous loop
  400.         SELECT CASE Behavior! '                                                                how was SUB called?
  401.             CASE IS < 5 '                                                                      computer pressing color pad
  402.                 _DELAY Behavior! '                                                             use value as a delay
  403.             CASE IS < 120 '                                                                    player is pressing a key
  404.                 _DELAY .125 '                                                                  pause for 1/8 second
  405.                 DO '                                                                           BEGIN KEYBOARD SCAN LOOP
  406.                     _LIMIT 120 '                                                               don't hog CPU
  407.                     KeyPress% = _KEYHIT '                                                      get value of key pressed
  408.                 LOOP UNTIL KeyPress% = -Behavior! '                                            END LOOP when key released
  409.             CASE ELSE '                                                                        player using mouse button
  410.                 _DELAY .125 '                                                                  pause for 1/8 second
  411.                 WAIT4RELEASE '                                                                 wait left button released
  412.         END SELECT
  413.         _SNDSTOP Tone&(PadNum%) '                                                              stop the sound
  414.     END IF
  415.     FOR Count% = 0 TO 3 '                                                                      cycle through all color pads
  416.         _PUTIMAGE (PadXY%(Count%, 0), PadXY%(Count%, 1)), Pad&(Count%, 0) '                    unlight color pad
  417.         _PUTIMAGE (KeysXY%(Count%, 0), KeysXY%(Count%, 1)), Keys&(Count%, 0) '                 set keys to raised position
  418.     NEXT Count%
  419.     _PUTIMAGE (200, 200), Simon& '                                                             place round simon image
  420.     _PUTIMAGE (232 + Game% * 10, 323), Bslider& '                                              place blue slider
  421.     _PUTIMAGE (319 + Skill% * 10, 323), Rslider& '                                             place red slider
  422.     _PUTIMAGE (321, 408), OnOff& '                                                             place power button slider
  423.     _DISPLAY '                                                                                 update screen with changes
  424.  
  425.  
  426. '----------------------------------------------------------------------------------------------------------------------
  427. '                                                                                                            INITIALIZE
  428. SUB INITIALIZE ()
  429.  
  430.     ' --------------------------------------------------------------------------------------------
  431.     ' Initialize all variables, create color pad images, load sounds and load spritesheet graphics
  432.     ' --------------------------------------------------------------------------------------------
  433.  
  434.     SHARED Pad&() '     color pads: 0,x=BLUE, 1,x=RED, 2,x=GREEN, 3,x=YELLOW
  435.     SHARED PadXY%() '   x,y locations of color pads
  436.     SHARED Tone&() '    game sounds
  437.     SHARED Simon& '     simon graphics image
  438.     SHARED SimonHelp& ' simon help screen
  439.     SHARED Keys&() '    keyboard key images 0=Q, 1=W, 2=S, 3=A
  440.     SHARED Bslider& '   blue slider switch image
  441.     SHARED Rslider& '   red slider switch image
  442.     SHARED OnOff& '     on/off slider switch
  443.     SHARED KeysXY%() '  location of keyboard key images
  444.     SHARED Game% '      the position the blue slider switch is in (0-2)
  445.     SHARED Skill% '     the position the red slider switch is in (0-3)
  446.     SHARED GameDir% '   the direction blue slider switch will move (1, -1)
  447.     SHARED SkillDir% '  the direction red slider switch will move (1, -1)
  448.     SHARED Pcolor~&() ' color pad base colors: 0=BLUE, 1=RED, 2=GREEN, 3=YELLOW
  449.  
  450.     DIM Sheet& '        sprite sheet containing game graphics
  451.     DIM Mask& '         color pad mask image
  452.     DIM Count% '        increasing color brightness counter
  453.     DIM Pcount% '       pad counter
  454.     DIM x% '            x location of pad circles
  455.     DIM y% '            y location of pad circles
  456.     DIM Clr~& '         temporary color pad color holder
  457.  
  458.     '-------------
  459.     '- MAIN CODE -
  460.     '-------------
  461.  
  462.     RANDOMIZE TIMER '                                            seed random number generator
  463.     Tone&(0) = _SNDOPEN("SimonB209.ogg", "VOL,SYNC") '           load blue   sound 209 Hz
  464.     Tone&(1) = _SNDOPEN("SimonR310.ogg", "VOL,SYNC") '           load red    sound 310 Hz
  465.     Tone&(2) = _SNDOPEN("SimonG415.ogg", "VOL,SYNC") '           load green  sound 415 Hz
  466.     Tone&(3) = _SNDOPEN("SimonY252.ogg", "VOL,SYNC") '           load yellow sound 252 Hz
  467.     Tone&(4) = _SNDOPEN("SimonL042.ogg", "VOL,SYNC") '           load lose   sound  42 Hz
  468.     Simon& = _NEWIMAGE(242, 242, 32) '                           simon image holder
  469.     Bslider& = _NEWIMAGE(57, 22, 32) '                           blue slider image holder
  470.     Rslider& = _NEWIMAGE(57, 22, 32) '                           red slider image holder
  471.     OnOff& = _NEWIMAGE(11, 11, 32) '                             power button slider image holder
  472.     Sheet& = _LOADIMAGE("SimonGFX.png", 32) '                    load simon sprite sheet of images
  473.     SimonHelp& = _LOADIMAGE("SimonHELP.png", 32) '               load simon help screen
  474.     _PUTIMAGE (0, 0), Sheet&, Simon&, (0, 94)-(241, 335) '       extract simon from spritesheet
  475.     _PUTIMAGE (0, 0), Sheet&, Bslider&, (200, 0)-(256, 21) '     extract blue slider from spritesheet
  476.     _PUTIMAGE (0, 0), Sheet&, Rslider&, (200, 22)-(256, 43) '    extract red slider from spritesheet
  477.     _PUTIMAGE (0, 0), Sheet&, OnOff&, (200, 44)-(210, 54) '      extract power button slider from spritesheet
  478.     FOR Count% = 0 TO 3 '                                        cycle through 4 color pads
  479.         Pad&(Count%, 0) = _NEWIMAGE(320, 320, 32) '              create color pad off image
  480.         Pad&(Count%, 1) = _NEWIMAGE(320, 320, 32) '              create color pad on  image
  481.         Keys&(Count%, 0) = _NEWIMAGE(50, 47, 32) '               create q,w,s,a raised key image holders
  482.         Keys&(Count%, 1) = _NEWIMAGE(50, 47, 32) '               create q,w,s,a pressed key image holders
  483.         _PUTIMAGE (0, 0), Sheet&, Keys&(Count%, 0), (Count% * 50, 0)-(Count% * 50 + 49, 46) '  extract key raised images
  484.         _PUTIMAGE (0, 0), Sheet&, Keys&(Count%, 1), (Count% * 50, 47)-(Count% * 50 + 49, 93) ' extract key pressed images
  485.     NEXT Count%
  486.     PadXY%(0, 0) = 0 '                                           color pad locations
  487.     PadXY%(0, 1) = 0
  488.     PadXY%(1, 0) = 320
  489.     PadXY%(1, 1) = 0
  490.     PadXY%(2, 0) = 320
  491.     PadXY%(2, 1) = 320
  492.     PadXY%(3, 0) = 0
  493.     PadXY%(3, 1) = 320
  494.     KeysXY%(0, 0) = 20 '                                         keyboard key image locations
  495.     KeysXY%(0, 1) = 20
  496.     KeysXY%(1, 0) = 570
  497.     KeysXY%(1, 1) = 20
  498.     KeysXY%(2, 0) = 570
  499.     KeysXY%(2, 1) = 573
  500.     KeysXY%(3, 0) = 20
  501.     KeysXY%(3, 1) = 573
  502.     Pcolor~&(0) = _RGB32(0, 0, 128) '                            blue color of pad in off condition
  503.     Pcolor~&(1) = _RGB32(128, 0, 0) '                            red color of pad in off condition
  504.     Pcolor~&(2) = _RGB32(0, 128, 0) '                            green color of pad in off condition
  505.     Pcolor~&(3) = _RGB32(128, 128, 0) '                          yellow color of pad in off condition
  506.     Game% = 0 '                                                  set initial game level
  507.     Skill% = 0 '                                                 set initial skill level
  508.     GameDir% = -1 '                                              set intial blue slider direction
  509.     SkillDir% = -1 '                                             set initial red slider direction
  510.     SIMONFILE 0 '                                                load longest tune ever played if available
  511.     '*
  512.     '* Create the eight semi-circle color pads, four off, four on
  513.     '*
  514.     FOR Pcount% = 0 TO 3 '                                       cycle through four color pads
  515.         _DEST Pad&(Pcount%, 0) '                                 set color pad off image as destination
  516.         CLS '                                                    remove black transparency
  517.         SELECT CASE Pcount% '                                    which color pad is being worked on?
  518.             CASE 0 '                                             blue color pad
  519.                 x% = 319: y% = 319 '                             set x,y coordinates of circles
  520.             CASE 1 '                                             red color pad
  521.                 x% = 0: y% = 319 '                               set x,y coordinates of circles
  522.             CASE 2 '                                             green color pad
  523.                 x% = 0: y% = 0 '                                 set x,y coordinates of circles
  524.             CASE 3 '                                             yellow color pad
  525.                 x% = 319: y% = 0 '                               set x,y coordinate of circles
  526.         END SELECT
  527.         CIRCLE (x%, y%), 319, _RGB32(16, 16, 16) '               draw simon outer circle segment
  528.         PAINT (x%, y%), _RGB32(16, 16, 16), _RGB32(16, 16, 16) ' paint simon color
  529.         CIRCLE (x%, y%), 300, Pcolor~&(Pcount%) '                draw color pad outer circle segment
  530.         CIRCLE (x%, y%), 140, Pcolor~&(Pcount%) '                draw color pad inner circle segment
  531.         PAINT (159, 159), Pcolor~&(Pcount%), Pcolor~&(Pcount%) ' paint color pad circle segment interior
  532.         LINE (x%, y%)-(ABS(319 - x%), ABS(10 - y%)), _RGB32(16, 16, 16), BF ' separate color pads horizontally
  533.         LINE (x%, y%)-(ABS(10 - x%), ABS(319 - y%)), _RGB32(16, 16, 16), BF ' separate color pads vertically
  534.         CIRCLE (x%, y%), 319, _RGB32(32, 32, 32) '               highlight edge of simon
  535.         Mask& = _COPYIMAGE(Pad&(Pcount%, 0)) '                   create an image mask
  536.         _DEST Mask& '                                            set the mask as the destination
  537.         _CLEARCOLOR Pcolor~&(Pcount%) '                          set circle segment as transparent
  538.         _DEST Pad&(Pcount%, 1) '                                 set color pad on image as destination
  539.         CLS '                                                    remove black transparency
  540.         Clr~& = Pcolor~&(Pcount%) '                              remember color being worked on
  541.         LINE (0, 0)-(319, 319), Clr~&, BF '                      fill entire image with color pad color
  542.         FOR Count% = 129 TO 255 '                                cycle 126 times
  543.             SELECT CASE Pcount% '                                which color pad is being worked on?
  544.                 CASE 0 '                                         blue color pad
  545.                     Clr~& = Clr~& + 1 '                          increase blue component
  546.                 CASE 1 '                                         red color pad
  547.                     Clr~& = Clr~& + 65536 '                      increase red component
  548.                 CASE 2 '                                         green color pad
  549.                     Clr~& = Clr~& + 256 '                        increase green component
  550.                 CASE 3 '                                         yellow color pad
  551.                     Clr~& = Clr~& + 65792 '                      increase red and green component (yellow)
  552.             END SELECT
  553.             CIRCLE (159, 159), (255 - Count%) * 2, Clr~& '       draw circle with new color component
  554.             PAINT (159, 159), Clr~&, Clr~& '                     paint inside circle new color component
  555.         NEXT Count%
  556.         _PUTIMAGE (0, 0), Mask& '                                place mask over circles
  557.     NEXT Pcount%
  558.     _FREEIMAGE Mask& '                                           remove mask image from RAM (no longer needed)
  559.     _FREEIMAGE Sheet& '                                          remove spritesheet from RAM (no longer needed)
  560.  
  561.  
  562. '----------------------------------------------------------------------------------------------------------------------
  563. '                                                                                                               ENDGAME
  564. SUB ENDGAME ()
  565.  
  566.     '--------------------------------------------------------------------
  567.     '- Removes game's assets from RAM and returns to the operating system
  568.     '--------------------------------------------------------------------
  569.  
  570.     SHARED Pad&() '     color pads: 0,x=BLUE, 1,x=RED, 2,x=GREEN, 3,x=YELLOW
  571.     SHARED Tone&() '    game sounds
  572.     SHARED Simon& '     simon graphics image
  573.     SHARED SimonHelp& ' simon help screen
  574.     SHARED Keys&() '    keyboard key images 0=Q, 1=W, 2=S, 3=A
  575.     SHARED Bslider& '   blue slider switch image
  576.     SHARED Rslider& '   red slider switch image
  577.     SHARED OnOff& '     on/off slider switch
  578.  
  579.     DIM Count% '        generic counter
  580.  
  581.     LINE (321, 408)-(331, 418), _RGB32(0, 0, 0), BF ' clear power button
  582.     _PUTIMAGE (313, 408), OnOff& '                    place power button in new position
  583.     _DISPLAY '                                        update screen with changes
  584.     FOR Count% = 0 TO 3 '                             cycle through assets
  585.         _SNDCLOSE Tone&(Count%) '                     close sound files
  586.         _FREEIMAGE Keys&(Count%, 0) '                 remove key raised images
  587.         _FREEIMAGE Keys&(Count%, 1) '                 remove key pressed images
  588.         _FREEIMAGE Pad&(Count%, 0) '                  remove color pad unlit images
  589.         _FREEIMAGE Pad&(Count%, 1) '                  remove color pad lit images
  590.     NEXT Count%
  591.     _SNDCLOSE Tone&(4) '                              close last sound file
  592.     _FREEIMAGE Simon& '                               remove simon image
  593.     _FREEIMAGE SimonHelp& '                           remove simon help screen image
  594.     _FREEIMAGE Bslider& '                             remove blue slider switch image
  595.     _FREEIMAGE Rslider& '                             remove red slider switch image
  596.     _FREEIMAGE OnOff& '                               remove on/off power switch image
  597.     _DELAY 1 '                                        pause for 1 second
  598.     SYSTEM '                                          return control to the operating system
  599.  
  600.