Author Topic: Why is this returning to the menu?  (Read 4242 times)

0 Members and 1 Guest are viewing this topic.

Offline Jaze

  • Newbie
  • Posts: 86
    • View Profile
Why is this returning to the menu?
« on: July 05, 2021, 02:44:45 pm »
Still working on BreakThru. Added some Bonus drops from a destroyed brick. I'm trying to set it up so that when "B" is dropped a second ball appears on the board. It works fine in debug mode. When debugging is off the game exits to the main menu if a ball goes below the paddle. If there are 2 balls running and 1 goes off the screen the other should stay active. Also, if there are 2 balls active and another bonus "B" is caught the game returns to the main menu instead of simply ignoring it. The thing is, even with an error in my code there is no reason why the DO - LOOP in the Main SUB should be exited until the numberOfGuys = 0. Can anyone tell me why the game is returning to the main menu?

Code: QB64: [Select]
  1. WIDTH 80, 50
  2. TYPE coordinate
  3.     x AS INTEGER
  4.     y AS INTEGER
  5.  
  6. TYPE droppingLetter
  7.     x AS INTEGER
  8.     y AS SINGLE
  9.     letter AS INTEGER
  10.  
  11.  
  12. GOTO beginning
  13. crap:
  14. PRINT "Error, error line"
  15.  
  16. beginning:
  17. CONST TRUE = 1
  18. CONST FALSE = 0
  19. CONST leftDirection = 19200 '   to make the code more readable with the left and right arrowkeys
  20. CONST rightDirection = 19712 '
  21. CONST upAndLeft = 1 'the ball always moves in one diagonal direction
  22. CONST upAndRight = 2
  23. CONST downAndLeft = 3
  24. CONST downAndRight = 4
  25. CONST theBackground = 0 '           to determine what the ball hit
  26. CONST theBrick = 1
  27. CONST theWall = 2
  28. CONST thePaddle = 3
  29. CONST theBall = 4
  30. CONST theBonus = 5
  31. CONST hitWallSound$ = "O2L30G"
  32. CONST hitPaddleSound$ = "O3L30C"
  33. CONST hitBrickSound$ = "O3L30G"
  34. CONST deathSound$ = "O4L15CO3CO2CO1L10C"
  35. CONST successBeep = "L9O2DL15DL9DL4F"
  36. CONST letterE = 69 'to lengthen / expand the paddle
  37. CONST letterS = 83 'to shrink the paddle
  38. CONST letterPlus = 43 ' score increase
  39. CONST letterMinus = 45 ' score decrease
  40. CONST letterStar = 42 'score multiplier
  41. CONST letterB = 66 ' add second ball
  42.  
  43. 'I share everything so I don't have to worry whether or not I was supposed to pass something. Plus it removes the need to pass the same variable multiple times
  44. DIM SHARED creationBoard(2 TO 79, 2 TO 46) AS INTEGER 'the colors on the board when creating a level
  45. FOR initializeArrayX = 2 TO 79
  46.     FOR initializeArrayY = 2 TO 46
  47.         creationBoard(initializeArrayX, initializeArrayY) = 1 'set the board to the background color
  48. DIM SHARED brick AS coordinate: brick.x = 2: brick.y = 2 'start the creation board at 2, 2
  49. DIM SHARED ball(1 TO 2) AS coordinate 'to track where the ball is on the board
  50. DIM SHARED ballDirection AS INTEGER 'track the ball's direction using the directional constants above
  51. DIM SHARED ball2Direction AS INTEGER
  52. DIM SHARED paddleLeft AS SINGLE ' the leftmost character of the paddle
  53. DIM SHARED board(1 TO 80, 1 TO 48, 1 TO 2) AS INTEGER 'the board for the game
  54. DIM SHARED numberOfBricks AS INTEGER 'the number of bricks currently on the board
  55. DIM SHARED currentLevel AS INTEGER: currentLevel = 1 'start at level 1
  56. DIM SHARED numberOfGuys AS INTEGER: numberOfGuys = 5
  57. DIM SHARED score AS INTEGER: scorte = 0
  58. DIM SHARED manDied AS INTEGER: manDied = FALSE
  59. DIM SHARED spaceToStart: spaceToStart = FALSE 'whether or not the spacebar was pushed to begin the level
  60. DIM SHARED debugMode AS INTEGER: debugMode = FALSE 'to bounce the ball off the bottom or to decrement numberOfGuys
  61. DIM SHARED penUp, currentColor, eraserOn AS INTEGER: penUp = TRUE: currentColor = 0: eraserOn = FALSE
  62. DIM SHARED mute AS INTEGER: mute = -1 ' -1 mute is off (sound on)
  63. DIM SHARED lastLevelCreated AS INTEGER: lastLevelCreated = 0
  64. DIM SHARED changeBallSomewhat AS INTEGER: changeBallSomewhat = 0 'used to move the ball a little bit to avoid never hitting all of the bricks
  65. DIM SHARED changeBall2Somewhat AS INTEGER: changeBall2Somewhat = 0
  66. DIM levelChecking AS INTEGER: levelChecking = 0 'used in the following loop to check what is the highest level
  67. DIM SHARED activeLetter AS droppingLetter: activeLetter.x = 0: activeLetter.y = 0: activeLetter.letter = 0
  68.     levelChecking = levelChecking + 1
  69. LOOP UNTIL _FILEEXISTS("Level " + S$(levelChecking)) = 0
  70. lastLevelCreated = levelChecking - 1
  71. DIM SHARED paddleLength AS INTEGER: paddleLength = 8
  72. DIM SHARED secondBall AS INTEGER
  73.  
  74. CALL Menu
  75.  
  76. SUB Menu
  77.     printTheMenu = TRUE 'used to stop the menu from flickering
  78.     DO
  79.         IF printTheMenu = TRUE THEN
  80.             COLOR 14, 1
  81.             CLS
  82.             LOCATE 20, 1
  83.             PRINT CenterText$("Menu")
  84.             PRINT CenterText$("------")
  85.             PRINT
  86.             PRINT CenterText$("1.) Instructions")
  87.             PRINT
  88.             PRINT CenterText$("2.) Create A Level")
  89.             PRINT
  90.             PRINT CenterText$("3.) Play The Game")
  91.             PRINT
  92.             PRINT CenterText$("4.) Exit")
  93.             printTheMenu = FALSE
  94.         END IF
  95.         menuCommand$ = INKEY$
  96.         SELECT CASE menuCommand$
  97.             CASE "1"
  98.                 CALL Instructions
  99.                 printTheMenu = TRUE
  100.             CASE "2"
  101.                 CALL CreationMain
  102.                 printTheMenu = TRUE
  103.             CASE "3"
  104.                 CALL Main
  105.                 printTheMenu = TRUE
  106.         END SELECT
  107.     LOOP UNTIL menuCommand$ = "4"
  108.     END
  109.  
  110. SUB Instructions
  111.     COLOR 10, 1
  112.     CLS
  113.     LOCATE 2
  114.     PRINT CenterText$("Level Creator")
  115.     PRINT CenterText$("---------------")
  116.  
  117.     PRINT CenterText$("The available commands are listed at the bottom of the screen.")
  118.     PRINT CenterText$("When the pen is up, the cursor moves without adding to the level")
  119.     PRINT CenterText$("being created. When the pen is down the current brick is added")
  120.     PRINT CenterText$("to the level being created. The other commands are self explanatory.")
  121.     COLOR 12, 1
  122.     PRINT CenterText$("If no levels have been created, the default level is used.")
  123.     PRINT CenterText$("If you progress beyond all levels created, the last level created repeats.")
  124.     PRINT
  125.     PRINT
  126.     COLOR 14, 1
  127.     PRINT CenterText$("Game")
  128.     PRINT CenterText$("------")
  129.  
  130.     PRINT CenterText$("The object of the game is to progress to the next level by")
  131.     PRINT CenterText$("destroying all of the bricks. To do this you must position the")
  132.     PRINT
  133.     COLOR 15, 1
  134.     PRINT CenterText$(CHR$(219) + CHR$(219) + CHR$(219) + CHR$(219) + CHR$(219) + CHR$(219) + CHR$(219) + CHR$(219))
  135.     PRINT
  136.     COLOR 14, 1
  137.     PRINT CenterText$("under the ball so that it is reflected toward the bricks using")
  138.     PRINT CenterText$("the left and right arrow keys.")
  139.     LOCATE 24, 21
  140.     PRINT "Push ";: COLOR 13, 1: PRINT "[SPACEBAR]";: COLOR 14, 1: PRINT " to set the ball in motion."
  141.     PRINT: PRINT
  142.     COLOR 13, 1:
  143.     LOCATE , 5: PRINT "     Available Commands                         Bonus Drops": COLOR 14, 1: PRINT
  144.     LOCATE , 5: PRINT "+ to increase the game speed               E = Expand paddle": PRINT
  145.     LOCATE , 5: PRINT "- to decrease the game speed               S = Shrink paddle": PRINT
  146.     LOCATE , 5: PRINT "P to pause the game                        + = Plus 15 points": PRINT
  147.     LOCATE , 5: PRINT "M to toggle mute on and off                - = Minus 15 points": PRINT
  148.     LOCATE , 2: PRINT "[ESC] to return to the main menu           * = Score multiplier (-1, 1.5 or 2)": PRINT
  149.     LOCATE , 5: PRINT "                                           D = Change ball direction": PRINT
  150.     LOCATE , 5: PRINT "                                           B = Activate 2nd ball"
  151.     PRINT: PRINT
  152.     PRINT CenterText$("Push C to turn on debug mode and O to turn it off.")
  153.     LOCATE 48
  154.     COLOR 15, 1
  155.     PRINT CenterText$("Push any key to continue.")
  156.     CALL P(FALSE)
  157.  
  158. FUNCTION CenterText$ (thisString$)
  159.     returnString$ = SPACE$(INT((80 - LEN(thisString$)) / 2)) + thisString$
  160.     CenterText$ = returnString$
  161.  
  162. SUB PrintBrick (x, y, onOrOff)
  163.     IF onOrOff = TRUE THEN
  164.         useColor = board(x, y, 2) 'print the brick instead of erasing it, pick up the color there
  165.     ELSEIF onOrOff = FALSE THEN
  166.         useColor = 1
  167.     END IF
  168.     FOR across = 0 TO 5
  169.         LOCATE y, x + across
  170.         COLOR useColor
  171.         PRINT CHR$(219)
  172.         board(x + across, y, 1) = 219
  173.         board(x + across, y, 2) = useColor
  174.     NEXT across
  175.     IF onOrOff = FALSE THEN 'brick is destroyed
  176.         numberOfBricks = numberOfBricks - 1
  177.         score = score + 5
  178.         chanceOfLetter = INT(RND * 100) + 1
  179.         IF chanceOfLetter <= 25 AND activeLetter.letter = 0 THEN ' 25% chance of bonus
  180.             pickingLetter = INT(RND * 6) + 1 'choose which bonus to activate
  181.             SELECT CASE pickingLetter
  182.                 CASE 1
  183.                     activeLetter.letter = letterE
  184.                 CASE 2
  185.                     activeLetter.letter = letterS
  186.                 CASE 3
  187.                     activeLetter.letter = letterPlus
  188.                 CASE 4
  189.                     activeLetter.letter = letterMinus
  190.                 CASE 5
  191.                     activeLetter.letter = letterStar
  192.                 CASE 6
  193.                     activeLetter.letter = letterB ' make 2 balls active
  194.             END SELECT
  195.             activeLetter.x = x + 3 'place the falling letter near the center of destroyed brick
  196.             activeLetter.y = y + 1
  197.             CALL PrintLetter(TRUE)
  198.         END IF
  199.         CALL PrintBoard
  200.     END IF
  201.  
  202. SUB PrintLetter (onOrOff)
  203.     IF INT(activeLetter.y) < 47 THEN 'whether the bonus letter is done falling
  204.         IF onOrOff = TRUE THEN 'display the bonus letter
  205.             clr = 9
  206.         ELSE
  207.             clr = 1 'remove bonus letter from display
  208.         END IF
  209.         CALL PlaceChar(activeLetter.x, activeLetter.y, activeLetter.letter, clr) 'put the letter on the board
  210.     ELSEIF activeLetter.y >= 47 THEN 'activate the letter or ignore it
  211.         IF paddleLeft <= activeLetter.x AND activeLetter.x <= paddleLeft + paddleLength - 1 THEN 'letter was caught
  212.             SELECT CASE activeLetter.letter 'which letter to activate
  213.                 CASE letterE 'lengthen the paddle
  214.                     IF paddleLength <= 10 THEN paddleLength = paddleLength + 2
  215.                     CALL PrintPaddle(TRUE)
  216.                 CASE letterS 'shrink the paddle
  217.                     IF paddleLength >= 8 THEN
  218.                         CALL PrintPaddle(FALSE)
  219.                         paddleLength = paddleLength - 2
  220.                         CALL PrintPaddle(TRUE)
  221.                     ELSEIF paddleLength > 5 AND paddleLength <= 7 THEN
  222.                         CALL PrintPaddle(FALSE)
  223.                         paddleLength = paddleLength - 1
  224.                         CALL PrintPaddle(TRUE)
  225.                     END IF
  226.                 CASE letterPlus 'increase score
  227.                     score = score + 15
  228.                 CASE letterMinus ' decrease score
  229.                     score = score - 15
  230.                 CASE letterStar 'multiply the score
  231.                     DIM multiplier AS SINGLE
  232.                     multiplier = INT(RND * 3) + 1
  233.                     IF multiplier = 1 THEN
  234.                         multiplier = -1
  235.                     ELSEIF multiplier = 3 THEN
  236.                         multiplier = 1.5
  237.                     END IF
  238.                     score = INT(score * multiplier)
  239.                 CASE letterB 'initiate second ball
  240.                     secondBall = TRUE
  241.                     IF ball(1).x <> 0 AND ball(2).x <> 0 THEN
  242.                         '2 balls running already, nothing to do
  243.                     ELSEIF ball(2).x = 0 THEN 'activate ball(2)
  244.                         ball(2).x = activeLetter.x 'start the second ball from the place where "B" was caught
  245.                         ball(2).y = activeLetter.y
  246.                         IF ballDirection = upAndLeft THEN 'ball(1) is moving diagonally up and right
  247.                             ball2Direction = upAndRight ' send ball 2 in the opposite direction
  248.                         ELSEIF ballDirection = upAndLeft THEN
  249.                             ball2Direction = upAndRight
  250.                         ELSEIF ballDirection = downAndLeft THEN
  251.                             ball2Direction = upAndRight
  252.                         ELSEIF ballDirection = downAndRight THEN
  253.                             ball2Direction = upAndLeft
  254.                         END IF ' ball(2) has been given a direction
  255.                     ELSEIF ball(1).x = 0 THEN 'activate ball(1)
  256.                         ball(1).x = activeLetter.x
  257.                         ball(1).y = activeLetter.y
  258.                         IF ball2Direction = upAndLeft THEN
  259.                             ballDirection = upAndRight
  260.                         ELSEIF ball2Direction = upAndRight THEN
  261.                             ballDirection = upAndLeft
  262.                         ELSEIF ball2Direction = downAndLeft THEN
  263.                             ballDirection = upAndRight
  264.                         ELSEIF ball2Direction = downAndRight THEN
  265.                             ballDirection = upAndLeft
  266.                         END IF 'ball(1) has been given a direction
  267.                     END IF 'ball(1) and ball(2) are active
  268.             END SELECT 'action has been done with selected bonus letter
  269.         END IF ' the letter has finished being caught
  270.         activeLetter.x = 0: activeLetter.y = 0: activeLetter.letter = 0 'the letter is no longer active
  271.     END IF
  272.  
  273. SUB PrintLevel
  274.     FOR x = 1 TO 80: FOR y = 1 TO 48 'make the board blue
  275.             board(x, y, 1) = 219 '    ASCII code of board space
  276.             board(x, y, 2) = 1 '      color of board space
  277.     NEXT y: NEXT x
  278.     COLOR 1, 1: CLS
  279.     'print left, right and top borders
  280.     FOR y = 1 TO 48
  281.         LOCATE y, 1: COLOR 12, 1: PRINT CHR$(219) 'print the left border to the screen
  282.         LOCATE y, 80: COLOR 12, 1: PRINT CHR$(219) 'print the right border to the screen
  283.         CALL PlaceChar(1, y, 219, 12) ' put the position, ASCII code and color on the board to make the left border
  284.         CALL PlaceChar(80, y, 219, 12) ' same to make the left border on the board
  285.     NEXT y
  286.     FOR x = 1 TO 80
  287.         LOCATE 1, x: COLOR 12, 1: PRINT CHR$(219) 'print the top border to the screen
  288.         CALL PlaceChar(x, 1, 219, 12) ' put the top border on the board
  289.     NEXT x
  290.     paddleLeft = INT(RND * (72 - 2 + 1)) + 2
  291.     paddleLength = 8
  292.     CALL PrintPaddle(TRUE) ' put the paddle on the board with the left at x coordinate 36
  293.     ball(1).x = paddleLeft + 4: ball(1).y = 47 ' position the ball/moving ball
  294.     CALL PrintBall(TRUE) ' put the ball on the board
  295.     ballDirection = INT(RND * 2) + 1 'randomize the starting direction of the ball as up and left or up and right
  296.  
  297.     IF lastLevelCreated <> 0 THEN
  298.         filename$ = "Level " + S$(currentLevel)
  299.         IF _FILEEXISTS(filename$) = 0 THEN filename$ = "Level " + S$(lastLevelCreated)
  300.         OPEN filename$ FOR INPUT AS #1 'open the file with the level information
  301.         FOR xCounting = 2 TO 79 ' x coordinate of the board
  302.             FOR yCounting = 2 TO 46 ' y coordinate of the board
  303.                 INPUT #1, boardColor$ ' get the color of the board at xCounting, yCounting
  304.                 board(xCounting, yCounting, 2) = VAL(boardColor$) 'color the board at xCounting, yCounting
  305.         NEXT: NEXT
  306.         '        LOCATE 20, 20: COLOR 15, 0: PRINT "Filename: " + filename$: CALL P
  307.         CLOSE #1
  308.     ELSE ' if no levels were created
  309.         FOR x = 2 TO 79
  310.             CALL PlaceChar(x, 2, 219, 14) 'put a yellow (14) block (219) at x, y on the board
  311.             CALL PlaceChar(x, 4, 219, 14)
  312.             CALL PlaceChar(x, 6, 219, 14)
  313.         NEXT x
  314.         lastLevelCreated = 1
  315.     END IF
  316.     numberOfBricks = 0 ' after a level has been put on the board, count the number of bricks on it
  317.     '    CALL PrintBoard 'debugging why the numberOfBricks is sometimes wrong
  318.     '    LOCATE 15, 2
  319.     '    COLOR 15, 0
  320.     '    PRINT "2345678901234567890123456789012345678901234567890123456789012345678901234567890"
  321.     '    LOCATE 14, 2
  322.     '    PRINT "        1         2         3         4         5         6         7         8"
  323.     '    COLOR 10, 0
  324.     '    FOR thirteen = 2 TO 13
  325.     '    LOCATE thirteen, 1
  326.     '    PRINT S$(thirteen)
  327.     '    NEXT
  328.     FOR brickCountingY = 2 TO 46 'with this set to 47 the ball was being counted as a brick sometimes
  329.         FOR brickCountingX = 2 TO 79 STEP 6 'each brick is 6 blocks long
  330.             IF board(brickCountingX, brickCountingY, 2) <> 1 THEN
  331.                 numberOfBricks = numberOfBricks + 1
  332.                 '                LOCATE 46, 1
  333.                 '                COLOR 15, 0
  334.                 '                PRINT "board(" + S$(brickCountingX) + ", " + S$(brickCountingY) + ", 2): " + S$(board(brickCountingX, brickCountingY, 2))
  335.                 '                PRINT "numberOfBricks = " + S$(numberOfBricks)
  336.                 '                CALL P(TRUE)
  337.             END IF
  338.     NEXT: NEXT
  339.  
  340.     CALL PrintBoard 'print the board to the screen
  341.     spaceToStart = FALSE 'spacebar has yet to be puched to start the current level
  342.  
  343. SUB Main
  344.     CALL PrintLevel 'put the current level on the board and print it out
  345.     printOutBoard = FALSE ' to avoid flicker of the board being constantly printed, the need to print it is false
  346.     delaySpeed = 0.029 'delay to use inside the main DO-LOOP
  347.     secondBall = FALSE
  348.     DO
  349.         '        LOCATE 48, 1: PRINT "Level " + S$(currentLevel)
  350.         debugging$ = INKEY$ 'using strings instead of _KEYDOWN(code) is easier. i initially added INKEY$ for debugging
  351.         IF spaceToStart = TRUE THEN ' the spacebar has been hit to start the game
  352.             IF secondBall = FALSE THEN 'there is only one ball active
  353.                 IF ball(1).x <> 0 THEN 'find out if ball(1) is active
  354.                     CALL PrintBall(FALSE) 'remove the ball from the board
  355.                     CALL MoveBall 'move the ball in the current direction
  356.                     CALL PrintBall(TRUE) 'put the ball on the board at the new position
  357.                 ELSEIF ball(2).x <> 0 THEN 'find out if ball(2) is active
  358.                     CALL PrintBall2(FALSE)
  359.                     CALL MoveBall2
  360.                     CALL PrintBall2(TRUE)
  361.                 ELSE
  362.                     LOCATE 45, 1
  363.                     COLOR 15, 0
  364.                     PRINT "Where is the error causing a return to the menu?"
  365.                     CALL P(TRUE)
  366.                 END IF
  367.             ELSEIF secondBall = TRUE THEN 'there are 2 active balls
  368.                 CALL PrintBall(FALSE) 'remove ball(1) from the display
  369.                 CALL PrintBall2(FALSE) ' remove ball(2) from display
  370.                 CALL MoveBall ' move ball(1)
  371.                 CALL MoveBall2 'move ball(2)
  372.                 CALL PrintBall(TRUE) 'redisplay ball(1)
  373.                 CALL PrintBall2(TRUE) ' redisplay ball(2)
  374.             ELSE
  375.                 LOCATE 45, 1
  376.                 COLOR 15, 0
  377.                 PRINT "Where is the error causing an exit from this DO?"
  378.                 CALL P(TRUE)
  379.             END IF
  380.             IF _KEYDOWN(leftDirection) = -1 THEN 'the left arrow key had been pushed
  381.                 CALL PrintPaddle(FALSE) ' remove the paddle from the board
  382.                 paddleLeft = paddleLeft - 1.5 ' move the paddle leftward
  383.                 CALL PrintPaddle(TRUE) ' put the paddle on the board at the new position
  384.                 printOutBoard = TRUE 'it is now needed to print the board to the screen
  385.             ELSEIF _KEYDOWN(rightDirection) = -1 THEN
  386.                 CALL PrintPaddle(FALSE)
  387.                 paddleLeft = paddleLeft + 1.5
  388.                 CALL PrintPaddle(TRUE)
  389.                 printOutBoard = TRUE
  390.             END IF
  391.             IF printOutBoard = TRUE THEN 'print the board to the screen
  392.                 CALL PrintBoard ' print the board to the screen
  393.                 printOutBoard = FALSE 'stop the board from being printed now
  394.             END IF
  395.             IF numberOfBricks = 0 THEN 'there are no bricks left on the board
  396.                 currentLevel = currentLevel + 1 'increment the current level
  397.                 activeLetter.letter = 0: activeLetter.x = 0: activeLetter.y = 0
  398.                 CALL PrintLevel 'put the newest level on the board
  399.                 spaceToStart = FALSE 'the spacebar has not been pressed since the new level has been output
  400.                 score = score + 200 '200 points for finishing a level
  401.                 IF mute = -1 THEN PLAY successBeep '1 is mute, -1 is note muted
  402.             END IF
  403.             IF activeLetter.letter <> 0 THEN
  404.                 CALL PrintLetter(FALSE)
  405.                 activeLetter.y = activeLetter.y + 0.5
  406.                 CALL PrintLetter(TRUE)
  407.                 printOutBoard = TRUE
  408.             END IF
  409.         END IF
  410.         IF debugging$ = "C" THEN debugMode = TRUE
  411.         IF debugging$ = "O" THEN debugMode = FALSE
  412.         IF _KEYDOWN(32) = -1 THEN ' the spacebar has been pushed
  413.             spaceToStart = TRUE ' the spacebar has been pushed
  414.             printOutBoard = TRUE ' it is needed to print the board to the screen
  415.         END IF
  416.         _DELAY (delaySpeed) ' insert a delay to make the movement playable and visible
  417.         IF numberOfGuys = 0 THEN CALL EndOfGame
  418.         IF score MOD 750 = 0 AND score <> 0 THEN numberOfGuys = numberOfGuys + 1 ' new guy every 2,000 points
  419.         IF debugging$ = "+" THEN 'increase the game speed
  420.             delaySpeed = delaySpeed - 0.01
  421.             IF delaySpeed < 0 THEN delaySpeed = 0 'don't allow a negative delay
  422.         END IF
  423.         IF debugging$ = "-" THEN delaySpeed = delaySpeed + 0.005 'decrease the game speed
  424.         IF debugging$ = "m" OR debugging$ = "M" THEN mute = mute * -1 'turn mute on or off
  425.         IF debugging$ = "p" OR debugging$ = "P" THEN pause$ = INPUT$(1) 'pause the game
  426.         IF debugging$ = CHR$(27) THEN EXIT DO 'end the game and return to the main menu
  427.     LOOP
  428.  
  429. SUB EndOfGame
  430.  
  431. SUB MoveBall
  432.     changeBallSomewhat = changeBallSomewhat + 1 'keep track of the number of times the ball has moved to occasionally nudge it
  433.     SELECT CASE ballDirection
  434.         CASE upAndRight
  435.             CALL MoveUpAndRight
  436.         CASE upAndLeft
  437.             CALL MoveUpAndLeft
  438.         CASE downAndRight
  439.             CALL MoveDownAndRight
  440.         CASE downAndLeft
  441.             CALL MoveDownAndLeft
  442.     END SELECT
  443.  
  444. SUB MoveBall2
  445.     changeBall2Somewhat = changeBall2Somewhat + 1 'keep track of the number of times the ball has moved to occasionally nudge it
  446.     SELECT CASE ball2Direction
  447.         CASE upAndRight
  448.             CALL Move2UpAndRight
  449.         CASE upAndLeft
  450.             CALL Move2UpAndLeft
  451.         CASE downAndRight
  452.             CALL Move2DownAndRight
  453.         CASE downAndLeft
  454.             CALL Move2DownAndLeft
  455.     END SELECT
  456.  
  457. FUNCTION Report (x, y) 'determine what element is at specified x, y location
  458.     'if color  12 then border, 1 then background, 15 then paddle, 11 ball, 9 bonus, else brick
  459.     rtn = -1 'initialize what should be returned
  460.     IF board(x, y, 2) = 12 THEN
  461.         rtn = theWall
  462.     ELSEIF board(x, y, 2) = 1 THEN
  463.         rtn = theBackground
  464.     ELSEIF board(x, y, 2) = 15 THEN
  465.         rtn = thePaddle
  466.     ELSEIF board(x, y, 2) = 11 THEN
  467.         rtn = theBall
  468.     ELSEIF board(x, y, 2) = 9 THEN
  469.         rtn = theBonus
  470.     ELSE
  471.         rtn = theBrick
  472.     END IF
  473.     Report = rtn
  474.  
  475. SUB MoveUpAndRight
  476.     SELECT CASE Report(ball(1).x + 1, ball(1).y - 1) 'report one away from where the ball currently is
  477.         CASE theBackground, theBall ' move it even if both balls are in the same place
  478.             ball(1).x = ball(1).x + 1
  479.             ball(1).y = ball(1).y - 1
  480.             IF changeBallSomewhat MOD 100 = 0 AND ball(1).x + 1 < 80 THEN ball(1).x = ball(1).x + 1
  481.         CASE theWall
  482.             IF mute = -1 THEN PLAY hitWallSound
  483.             IF ball(1).x + 1 = 80 THEN
  484.                 'hit the right wall
  485.                 ballDirection = upAndLeft
  486.             ELSEIF ball(1).y - 1 = 1 THEN
  487.                 'hit top wall
  488.                 ballDirection = downAndRight
  489.             END IF
  490.         CASE theBrick
  491.             IF mute = -1 THEN PLAY hitBrickSound
  492.             leftSideOfBrick = FindBrickLeft(ball(1).x + 1)
  493.             vertOfBrick = FindBrickVertical(ball(1).y - 1)
  494.             CALL PrintBrick(leftSideOfBrick, vertOfBrick, FALSE)
  495.             ballDirection = downAndRight
  496.     END SELECT
  497.  
  498. SUB Move2UpAndRight
  499.     SELECT CASE Report(ball(2).x + 1, ball(2).y - 1) 'report one away from where the ball currently is
  500.         CASE theBackground, theBall ' move it even if both balls are in the same place
  501.             ball(2).x = ball(2).x + 1
  502.             ball(2).y = ball(2).y - 1
  503.             IF changeBall2Somewhat MOD 100 = 0 AND ball(2).x + 1 < 80 THEN ball(2).x = ball(2).x + 1
  504.         CASE theWall
  505.             IF mute = -1 THEN PLAY hitWallSound
  506.             IF ball(2).x + 1 = 80 THEN
  507.                 'hit the right wall
  508.                 ball2Direction = upAndLeft
  509.             ELSEIF ball(2).y - 1 = 1 THEN
  510.                 'hit top wall
  511.                 ball2Direction = downAndRight
  512.             END IF
  513.         CASE theBrick
  514.             IF mute = -1 THEN PLAY hitBrickSound
  515.             leftSideOfBrick = FindBrickLeft(ball(2).x + 1)
  516.             vertOfBrick = FindBrickVertical(ball(2).y - 1)
  517.             CALL PrintBrick(leftSideOfBrick, vertOfBrick, FALSE)
  518.             ball2Direction = downAndRight
  519.     END SELECT
  520.  
  521. SUB MoveUpAndLeft
  522.     SELECT CASE Report(ball(1).x - 1, ball(1).y - 1)
  523.         CASE theBackground, theBall
  524.             ball(1).x = ball(1).x - 1
  525.             ball(1).y = ball(1).y - 1
  526.             IF changeBallSomewhat MOD 100 = 0 AND ball(1).x - 1 > 1 THEN ball(1).x = ball(1).x - 1
  527.         CASE theWall
  528.             IF mute = -1 THEN PLAY hitWallSound
  529.             IF ball(1).x - 1 = 1 THEN
  530.                 ballDirection = upAndRight
  531.             ELSEIF ball(1).y - 1 = 1 THEN 'hit the top
  532.                 ballDirection = downAndLeft
  533.             END IF
  534.         CASE theBrick
  535.             IF mute = -1 THEN PLAY hitBrickSound
  536.             leftSideOfBrick = FindBrickLeft(ball(1).x - 1)
  537.             vertOfBrick = FindBrickVertical(ball(1).y - 1)
  538.             CALL PrintBrick(leftSideOfBrick, vertOfBrick, FALSE)
  539.             ballDirection = downAndLeft
  540.     END SELECT
  541.  
  542. SUB Move2UpAndLeft
  543.     SELECT CASE Report(ball(2).x - 1, ball(2).y - 1)
  544.         CASE theBackground, theBall
  545.             ball(2).x = ball(2).x - 1
  546.             ball(2).y = ball(2).y - 1
  547.             IF changeBall2Somewhat MOD 100 = 0 AND ball(2).x - 1 > 1 THEN ball(2).x = ball(2).x - 1
  548.         CASE theWall
  549.             IF mute = -1 THEN PLAY hitWallSound
  550.             IF ball(2).x - 1 = 1 THEN
  551.                 ball2Direction = upAndRight
  552.             ELSEIF ball(2).y - 1 = 1 THEN 'hit the top
  553.                 ball2Direction = downAndLeft
  554.             END IF
  555.         CASE theBrick
  556.             IF mute = -1 THEN PLAY hitBrickSound
  557.             leftSideOfBrick = FindBrickLeft(ball(1).x - 1)
  558.             vertOfBrick = FindBrickVertical(ball(1).y - 1)
  559.             CALL PrintBrick(leftSideOfBrick, vertOfBrick, FALSE)
  560.             ball2Direction = downAndLeft
  561.     END SELECT
  562.  
  563. SUB MoveDownAndRight
  564.     SELECT CASE Report(ball(1).x + 1, ball(1).y + 1)
  565.         CASE theBackground, theBall
  566.             IF ball(1).y + 1 = 48 THEN
  567.                 IF debugMode = FALSE THEN
  568.                     IF secondBall = FALSE THEN
  569.                         manDied = TRUE
  570.                         score = score - 50
  571.                         spaceToStart = FALSE
  572.                         CALL PrintPaddle(FALSE)
  573.                         paddleLength = 8
  574.                         paddleLeft = INT(RND * (72 - 2 + 1)) + 2
  575.                         CALL PrintBall(FALSE)
  576.                         ball(1).x = paddleLeft + 4: ball(1).y = 47
  577.                         CALL PrintBall(TRUE)
  578.                         CALL PrintPaddle(TRUE)
  579.                         ballDirection = INT(RND * 2) + 1
  580.                         IF mute = -1 THEN PLAY deathSound
  581.                         numberOfGuys = numberOfGuys - 1
  582.                         CALL PrintBoard
  583.                     ELSE 'second ball is true but just fell below the board
  584.                         secondBall = FALSE
  585.                         ball(1).x = 0
  586.                         ball(1).y = 0
  587.                     END IF
  588.                 ELSE 'debug mode is on (true)
  589.                     IF mute = -1 THEN PLAY hitWallSound
  590.                     ballDirection = upAndRight
  591.                     ball(1).x = ball(1).x + 1
  592.                     ball(1).y = ball(1).y - 1
  593.                     IF changeBallSomewhat MOD 100 = 0 AND ball(1).x + 1 < 80 THEN ball(1).x = ball(1).x + 1
  594.                 END IF
  595.             ELSE
  596.                 ball(1).x = ball(1).x + 1
  597.                 ball(1).y = ball(1).y + 1
  598.             END IF
  599.         CASE theWall
  600.             IF mute = -1 THEN PLAY hitWallSound
  601.             IF ball(1).x + 1 = 80 THEN ballDirection = downAndLeft
  602.         CASE theBrick
  603.             IF mute = -1 THEN PLAY hitBrickSound
  604.             leftSideOfBrick = FindBrickLeft(ball(1).x + 1)
  605.             vertOfBrick = FindBrickVertical(ball(1).y + 1)
  606.             CALL PrintBrick(leftSideOfBrick, vertOfBrick, FALSE)
  607.             ballDirection = upAndRight
  608.         CASE thePaddle
  609.             IF mute = -1 THEN PLAY hitPaddleSound
  610.             ballDirection = upAndRight
  611.     END SELECT
  612.  
  613. SUB Move2DownAndRight
  614.     SELECT CASE Report(ball(2).x + 1, ball(2).y + 1)
  615.         CASE theBackground, theBall
  616.             IF ball(2).y + 1 = 48 THEN
  617.                 IF debugMode = FALSE THEN
  618.                     IF secondBall = FALSE THEN
  619.                         manDied = TRUE
  620.                         score = score - 50
  621.                         spaceToStart = FALSE
  622.                         CALL PrintPaddle(FALSE)
  623.                         paddleLength = 8
  624.                         paddleLeft = INT(RND * (72 - 2 + 1)) + 2
  625.                         CALL PrintBall2(FALSE)
  626.                         ball(1).x = paddleLeft + 4: ball(1).y = 47
  627.                         ball(2).x = 0: ball(2).y = 0
  628.                         CALL PrintBall(TRUE)
  629.                         CALL PrintPaddle(TRUE)
  630.                         ballDirection = INT(RND * 2) + 1
  631.                         IF mute = -1 THEN PLAY deathSound
  632.                         numberOfGuys = numberOfGuys - 1
  633.                         CALL PrintBoard
  634.                     ELSE 'second ball is ... was true
  635.                         CALL PrintBall2(FALSE)
  636.                         secondBall = FALSE
  637.                         ball(2).x = 0
  638.                         ball(2).y = 0
  639.                     END IF
  640.                 ELSE 'debug mode = true
  641.                     IF mute = -1 THEN PLAY hitWallSound
  642.                     ball2Direction = upAndRight
  643.                     ball(2).x = ball(2).x + 1
  644.                     ball(2).y = ball(2).y - 1
  645.                     IF changeBall2Somewhat MOD 100 = 0 AND ball(2).x + 1 < 80 THEN ball(2).x = ball(2).x + 1
  646.                 END IF
  647.             ELSE
  648.                 ball(2).x = ball(2).x + 1
  649.                 ball(2).y = ball(2).y + 1
  650.             END IF
  651.         CASE theWall
  652.             IF mute = -1 THEN PLAY hitWallSound
  653.             IF ball(2).x + 1 = 80 THEN ball2Direction = downAndLeft
  654.         CASE theBrick
  655.             IF mute = -1 THEN PLAY hitBrickSound
  656.             leftSideOfBrick = FindBrickLeft(ball(2).x + 1)
  657.             vertOfBrick = FindBrickVertical(ball(2).y + 1)
  658.             CALL PrintBrick(leftSideOfBrick, vertOfBrick, FALSE)
  659.             ball2Direction = upAndRight
  660.         CASE thePaddle
  661.             IF mute = -1 THEN PLAY hitPaddleSound
  662.             ball2Direction = upAndRight
  663.     END SELECT
  664.  
  665. SUB MoveDownAndLeft
  666.     SELECT CASE Report(ball(1).x - 1, ball(1).y + 1)
  667.         CASE theBackground
  668.             IF ball(1).y + 1 = 48 THEN
  669.                 IF debugMode = FALSE THEN
  670.                     IF secondBall = FALSE THEN
  671.                         manDied = TRUE
  672.                         score = score - 50
  673.                         spaceToStart = FALSE
  674.                         CALL PrintPaddle(FALSE)
  675.                         CALL PrintBall(FALSE)
  676.                         paddleLeft = INT(RND * (72 - 2% + 1)) + 2
  677.                         paddleLength = 8
  678.                         ball(1).x = paddleLeft + 4: ball(1).y = 47
  679.                         CALL PrintBall(TRUE)
  680.                         CALL PrintPaddle(TRUE)
  681.                         ballDirection = INT(RND * 2) + 1
  682.                         IF mute = -1 THEN PLAY deathSound
  683.                         numberOfGuys = numberOfGuys - 1
  684.                         CALL PrintBoard
  685.                     ELSE 'second ball was true
  686.                         secondBall = FALSE
  687.                         ball(1).x = 0
  688.                         ball(1).y = 0
  689.                     END IF
  690.                 ELSE
  691.                     IF mute = -1 THEN PLAY hitWallSound
  692.                     ballDirection = upAndLeft
  693.                     ball(1).x = ball(1).x - 1
  694.                     ball(1).y = ball(1).y - 1
  695.                     IF changeBallSomewhat MOD 100 = 0 AND ball(1).x - 1 > 1 THEN ball(1).x = ball(1).x + 1
  696.                 END IF
  697.             ELSE
  698.                 ball(1).x = ball(1).x - 1
  699.                 ball(1).y = ball(1).y + 1
  700.             END IF
  701.         CASE theWall
  702.             IF mute = -1 THEN PLAY hitWallSound
  703.             IF ball(1).x - 1 = 1 THEN ballDirection = downAndRight
  704.         CASE theBrick
  705.             IF mute = -1 THEN PLAY hitBrickSound
  706.             leftSideOfBrick = FindBrickLeft(ball(1).x - 1)
  707.             vertOfBrick = FindBrickVertical(ball(1).y + 1)
  708.             CALL PrintBrick(leftSideOfBrick, vertOfBrick, FALSE)
  709.             ballDirection = upAndLeft
  710.         CASE thePaddle
  711.             IF mute = -1 THEN PLAY hitPaddleSound
  712.             ballDirection = upAndLeft
  713.         CASE theBall
  714.             LOCATE 20, 20
  715.             COLOR 15, 0
  716.             PRINT "Error in moving the ball in specified direction": CALL P(TRUE)
  717.     END SELECT
  718.  
  719. SUB Move2DownAndLeft
  720.     SELECT CASE Report(ball(2).x - 1, ball(2).y + 1)
  721.         CASE theBackground, theBall
  722.             IF ball(2).y + 1 = 48 THEN
  723.                 IF debugMode = FALSE THEN
  724.                     IF secondBall = FALSE THEN
  725.                         manDied = TRUE
  726.                         score = score - 50
  727.                         spaceToStart = FALSE
  728.                         CALL PrintPaddle(FALSE)
  729.                         paddleLength = 8
  730.                         paddleLeft = INT(RND * (72 - 2 + 1)) + 2
  731.                         CALL PrintBall2(FALSE)
  732.                         ball(1).x = paddleLeft + 4: ball(1).y = 47
  733.                         ball(2).x = 0: ball(2).y = 0
  734.                         CALL PrintBall(TRUE)
  735.                         CALL PrintPaddle(TRUE)
  736.                         ballDirection = INT(RND * 2) + 1
  737.                         IF mute = -1 THEN PLAY deathSound
  738.                         numberOfGuys = numberOfGuys - 1
  739.                         CALL PrintBoard
  740.                     ELSE 'second ball is ... was true
  741.                         CALL PrintBall2(FALSE)
  742.                         secondBall = FALSE
  743.                         ball(2).x = 0
  744.                         ball(2).y = 0
  745.                     END IF
  746.                 ELSE 'debug mode = true
  747.                     IF mute = -1 THEN PLAY hitWallSound
  748.                     ball2Direction = upAndLeft
  749.                     ball(2).x = ball(2).x - 1
  750.                     ball(2).y = ball(2).y - 1
  751.                     IF changeBall2Somewhat MOD 100 = 0 AND ball(2).x + 1 < 80 THEN ball(2).x = ball(2).x + 1
  752.                 END IF
  753.             ELSE
  754.                 ball(2).x = ball(2).x - 1
  755.                 ball(2).y = ball(2).y + 1
  756.             END IF
  757.         CASE theWall
  758.             IF mute = -1 THEN PLAY hitWallSound
  759.             IF ball(2).x - 1 = 1 THEN ball2Direction = downAndRight
  760.         CASE theBrick
  761.             IF mute = -1 THEN PLAY hitBrickSound
  762.             leftSideOfBrick = FindBrickLeft(ball(2).x - 1)
  763.             vertOfBrick = FindBrickVertical(ball(2).y + 1)
  764.             CALL PrintBrick(leftSideOfBrick, vertOfBrick, FALSE)
  765.             ball2Direction = upAndLeft
  766.         CASE thePaddle
  767.             IF mute = -1 THEN PLAY hitPaddleSound
  768.             ball2Direction = upAndLeft
  769.     END SELECT
  770.  
  771. FUNCTION FindBrickLeft (x) 'this returns the x coordinate of the brick that was hit
  772.     rtn = 0
  773.     FOR cnt = 2 TO 79 STEP 6
  774.         IF cnt <= x AND x <= cnt + 5 THEN rtn = cnt
  775.     NEXT cnt
  776.     FindBrickLeft = rtn
  777.  
  778. FUNCTION FindBrickVertical (y)
  779.     rtn = 0
  780.     FOR cnt = 2 TO 47
  781.         IF cnt = y THEN rtn = cnt
  782.     NEXT
  783.     FindBrickVertical = rtn
  784.  
  785. SUB PrintBall (onOrOff) 'put the ball on the board or remove it from the board to effect position change
  786.     IF onOrOff = TRUE THEN
  787.         useColor = 11
  788.     ELSEIF onOrOff = FALSE THEN
  789.         useColor = 1
  790.     END IF
  791.     COLOR useColor, 1: LOCATE ball(1).y, ball(1).x: PRINT CHR$(254)
  792.     CALL PlaceChar(ball(1).x, ball(1).y, 254, useColor)
  793.  
  794. SUB PrintBall2 (onOrOff)
  795.     IF onOrOff = TRUE THEN
  796.         useColor = 11
  797.     ELSEIF onOrOff = FALSE THEN
  798.         useColor = 1
  799.     END IF
  800.     COLOR useColor, 1: LOCATE ball(2).y, ball(2).x: PRINT CHR$(254)
  801.     CALL PlaceChar(ball(2).x, ball(2).y, 254, useColor)
  802.  
  803. SUB PrintPaddle (onOrOff)
  804.     IF onOrOff = TRUE THEN
  805.         theColor = 15
  806.     ELSEIF onOrOf = FALSE THEN
  807.         theColor = 1
  808.     END IF
  809.     IF paddleLeft < 2 THEN paddleLeft = 2
  810.     IF paddleLeft > 80 - paddleLength THEN paddleLeft = 80 - paddleLength
  811.     FOR across = 0 TO paddleLength - 1
  812.         LOCATE 48, INT(paddleLeft) + across: COLOR theColor: PRINT CHR$(219)
  813.         CALL PlaceChar(INT(paddleLeft) + across, 48, 219, theColor)
  814.     NEXT across
  815.  
  816. SUB PlaceChar (X, Y, char, clr) 'put the character ASCII with specified color on the board
  817.     board(X, Y, 1) = char 'character
  818.     board(X, Y, 2) = clr ' color
  819.  
  820. SUB PrintBoard 'print the current board configurationg to the screen and update the current stats displayed
  821.     FOR y = 2 TO 48: FOR x = 2 TO 79
  822.             this$ = CHR$(board(x, y, 1))
  823.             theColor = board(x, y, 2)
  824.             COLOR theColor, 1
  825.             LOCATE y, x
  826.             PRINT this$
  827.             IF BrickIsThere(x, y) = TRUE THEN
  828.                 xCo = FindBrickLeft(x)
  829.                 yCo = FindBrickVertical(y)
  830.                 CALL PrintBrick(xCo, yCo, TRUE)
  831.             END IF
  832.     NEXT x: NEXT y
  833.     LOCATE 1, 2: COLOR 10, 12
  834.     PRINT "  Level " + S$(currentLevel) + "       ";
  835.     PRINT "Men: " + S$(numberOfGuys) + "       ";
  836.     PRINT "Bricks remaining: " + S$(numberOfBricks) + "       ";
  837.     PRINT "Score: " + S$(score) + "    "
  838.  
  839. FUNCTION BrickIsThere (xCoord, yCoord)
  840.     x = xCoord: y = yCoord
  841.     rtn = FALSE
  842.     IF board(x, y, 2) <> 11 AND board(x, y, 2) <> 15 AND board(x, y, 2) <> 12 AND board(x, y, 2) <> 9 AND board(x, y, 2) <> 1 THEN rtn = TRUE
  843.     BrickIsThere = rtn
  844.  
  845. SUB CreationMain 'main subroutine for the level creation feature
  846.     penUp = TRUE
  847.     eraserOn = FALSE
  848.     currentColor = 0
  849.     brick.x = 2
  850.     brick.y = 2
  851.     FOR countX = 2 TO 79
  852.         FOR countY = 2 TO 46
  853.             creationBoard(countX, countY) = 1
  854.     NEXT: NEXT
  855.     CALL PrintBackdrop
  856.     CALL PrintCreationBoard
  857.     CALL PrintCreationBrick
  858.     printOutCurrentBoard = FALSE
  859.     DO
  860.         whichCommand$ = INKEY$
  861.         SELECT CASE whichCommand$
  862.             CASE "P", "p"
  863.                 IF penUp = TRUE THEN
  864.                     penUp = FALSE
  865.                     CALL PutBrickOnBoard
  866.                 ELSEIF penUp = FALSE AND eraserOn = FALSE THEN
  867.                     penUp = TRUE
  868.                 END IF
  869.                 CALL PrintBackdrop
  870.                 printOutCurrentBoard = TRUE
  871.             CASE "E", "e"
  872.                 IF eraserOn = FALSE THEN
  873.                     eraserOn = TRUE
  874.                     currentColor = 1
  875.                     penUp = FALSE
  876.                     CALL PutBrickOnBoard
  877.                 ELSEIF eraserOn = TRUE THEN
  878.                     eraserOn = FALSE
  879.                     currentColor = 0
  880.                     penUp = TRUE
  881.                 END IF
  882.                 printOutCurrentBoard = TRUE
  883.             CASE "C", "c" 'game uses 12, 15, 11, 1 and 9, 17
  884.                 IF currentColor = 0 THEN
  885.                     currentColor = 2
  886.                 ELSEIF currentColor = 8 THEN
  887.                     currentColor = 10
  888.                 ELSEIF currentColor = 10 THEN
  889.                     currentColor = 13
  890.                 ELSEIF currentColor = 14 THEN
  891.                     currentColor = 16
  892.                 ELSEIF currentColor = 16 THEN
  893.                     currentColor = 18
  894.                 ELSEIF currentColor < 31 THEN
  895.                     currentColor = currentColor + 1
  896.                 ELSEIF currentColor = 31 THEN
  897.                     currentColor = 0
  898.                 END IF
  899.                 printOutCurrentBoard = TRUE
  900.                 IF penUp = FALSE THEN CALL PutBrickOnBoard
  901.             CASE "A", "a"
  902.                 penUp = TRUE
  903.                 eraserOn = FALSE
  904.                 currentColor = 0
  905.                 FOR xCount = 2 TO 79
  906.                     FOR yCount = 2 TO 46
  907.                         creationBoard(xCount, yCount) = 1
  908.                 NEXT: NEXT
  909.                 printOutCurrentBoard = TRUE
  910.             CASE "s", "S"
  911.                 IF SaveBoard$ = "END" THEN EXIT DO
  912.             CASE CHR$(0) + "H" ' up
  913.                 IF brick.y > 2 THEN
  914.                     brick.y = brick.y - 1
  915.                     IF penUp = FALSE THEN CALL PutBrickOnBoard
  916.                     printOutCurrentBoard = TRUE
  917.                 END IF
  918.             CASE CHR$(0) + "K" ' left
  919.                 IF brick.x > 7 THEN
  920.                     brick.x = brick.x - 6
  921.                     IF penUp = FALSE THEN CALL PutBrickOnBoard
  922.                     printOutCurrentBoard = TRUE
  923.                 END IF
  924.             CASE CHR$(0) + "P" ' down
  925.                 IF brick.y < 47 THEN
  926.                     brick.y = brick.y + 1
  927.                     IF penUp = FALSE THEN CALL PutBrickOnBoard
  928.                     printOutCurrentBoard = TRUE
  929.                 END IF
  930.             CASE CHR$(0) + "M" ' right
  931.                 IF brick.x < 73 THEN
  932.                     brick.x = brick.x + 6
  933.                     IF penUp = FALSE THEN CALL PutBrickOnBoard
  934.                     printOutCurrentBoard = TRUE
  935.                 END IF
  936.             CASE CHR$(27)
  937.                 EXIT DO
  938.         END SELECT
  939.         IF printOutCurrentBoard = TRUE THEN
  940.             CALL PrintBackdrop
  941.             CALL PrintCreationBoard
  942.             CALL PrintCreationBrick
  943.             printOutCurrentBoard = FALSE
  944.         END IF
  945.     LOOP
  946.  
  947. FUNCTION SaveBoard$
  948.     COLOR 10, 0
  949.     CLS
  950.     highestLevel = 0
  951.     DO
  952.         highestLevel = highestLevel + 1
  953.         filename$ = "Level " + S$(highestLevel)
  954.     LOOP UNTIL _FILEEXISTS(filename$) = 0
  955.     LOCATE 10, 10
  956.     PRINT "The game board has been saved as " + CHR$(34) + "Level " + S$(highestLevel) + CHR$(34)
  957.     PRINT
  958.     PRINT "It will automatically be loaded after Level " + S$(highestLevel - 1) + " is completed."
  959.     PRINT
  960.     OPEN filename$ FOR OUTPUT AS #1
  961.     FOR x = 2 TO 79
  962.         FOR y = 2 TO 46
  963.             COLOR 10, 0: LOCATE 15, 15: PRINT "Working"
  964.             stringOut$ = S$(creationBoard(x, y))
  965.             IF LEN(stringOut$) = 1 THEN stringOut$ = " " + stringOut$
  966.             PRINT #1, stringOut$
  967.             COLOR 0, 0: LOCATE 15, 15: PRINT "Working"
  968.     NEXT: NEXT
  969.     CLOSE #1
  970.     COLOR 10, 0
  971.     a$ = "Push " + CHR$(34) + "A" + CHR$(34) + " to make (a)nother level"
  972.     LOCATE 30, (80 - LEN(a$)) / 2
  973.     PRINT a$
  974.     pause$ = INPUT$(1)
  975.     IF UCASE$(pause$) = "A" THEN
  976.         CALL CreationMain
  977.     ELSE
  978.         SaveBoard$ = "END"
  979.     END IF
  980.  
  981. SUB PutBrickOnBoard
  982.     FOR counting = 0 TO 5
  983.         creationBoard(brick.x + counting, brick.y) = currentColor
  984.     NEXT counting
  985.  
  986. SUB PrintCreationBrick
  987.     IF penUp = TRUE AND eraserOn = FALSE THEN
  988.         LOCATE brick.y, brick.x
  989.         COLOR 15, 1
  990.         PRINT CHR$(219)
  991.     ELSEIF penUp = FALSE AND eraserOn = TRUE THEN
  992.         LOCATE brick.y, brick.x
  993.         COLOR 7, 1
  994.         PRINT "-"
  995.     ELSE
  996.         LOCATE brick.y, brick.x
  997.         COLOR currentColor, 1
  998.         PRINT CHR$(219)
  999.     END IF
  1000.     FOR count = 1 TO 5
  1001.         LOCATE brick.y, brick.x + count
  1002.         IF eraserOn = TRUE THEN
  1003.             COLOR 7, 1
  1004.             PRINT "-"
  1005.         ELSE
  1006.             COLOR currentColor, 1
  1007.             PRINT CHR$(219)
  1008.         END IF
  1009.     NEXT
  1010.  
  1011.  
  1012. SUB PrintCreationBoard
  1013.     CALL PrintBackdrop
  1014.     FOR y = 2 TO 46
  1015.         FOR x = 2 TO 79
  1016.             COLOR creationBoard(x, y), 1
  1017.             LOCATE y, x
  1018.             PRINT CHR$(219)
  1019.     NEXT: NEXT
  1020.  
  1021. SUB PrintBackdrop
  1022.     COLOR 1, 1: CLS
  1023.     COLOR 12, 1
  1024.     FOR x = 1 TO 80
  1025.         LOCATE 1, x: PRINT CHR$(219)
  1026.     NEXT
  1027.     FOR y = 1 TO 48
  1028.         LOCATE y, 1: PRINT CHR$(219)
  1029.         LOCATE y, 80: PRINT CHR$(219)
  1030.     NEXT
  1031.     COLOR 14, 1
  1032.     LOCATE 47, 3
  1033.     PRINT "Use the Arrow Keys To Move      P - Pen ";
  1034.     IF penUp = TRUE THEN
  1035.         COLOR 10, 1
  1036.         PRINT "up";
  1037.         COLOR 14, 1
  1038.         PRINT "/";
  1039.         COLOR 7, 1
  1040.         PRINT "down";
  1041.     ELSE
  1042.         COLOR 7, 1
  1043.         PRINT "up";
  1044.         COLOR 14, 1
  1045.         PRINT "/";
  1046.         COLOR 10, 1
  1047.         PRINT "down";
  1048.     END IF
  1049.     PRINT "       ";
  1050.     IF currentColor = 0 THEN
  1051.         COLOR 0, 7
  1052.     ELSE
  1053.         COLOR currentColor, 0
  1054.     END IF
  1055.     PRINT "C - Cycle colors"
  1056.     LOCATE 48, 2
  1057.     COLOR 14, 1: PRINT "E - Eraser ";
  1058.     'LOCATE 20, 20: COLOR 15, 0: PRINT "eraserOn = " + S$(eraserOn): CALL P
  1059.     '    LOCATE 48, 26
  1060.     IF eraserOn = TRUE THEN
  1061.         COLOR 10, 1
  1062.         PRINT "On";
  1063.         COLOR 14, 1: PRINT "/";
  1064.         COLOR 7, 1
  1065.         PRINT "Off";
  1066.     ELSE
  1067.         COLOR 7, 1
  1068.         PRINT "On";
  1069.         COLOR 14, 1
  1070.         PRINT "/";
  1071.         COLOR 10, 1
  1072.         PRINT "Off";
  1073.     END IF
  1074.     COLOR 14, 1
  1075.     PRINT "     A - Clear All";
  1076.     PRINT "     S - Save     [ESC] - End Without Save"
  1077.     CALL PrintCreationBrick
  1078.     '    LOCATE 45, 10: COLOR 10, 1: PRINT "eraserOn = " + S$(eraserOn)
  1079.  
  1080.  
  1081. SUB P (EndAllowed)
  1082.     pause$ = INPUT$(1)
  1083.     IF pause$ = CHR$(27) AND EndAllowed = TRUE THEN END
  1084.  
  1085. FUNCTION S$ (number)
  1086.     S$ = LTRIM$(STR$(number))


Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
Re: Why is this returning to the menu?
« Reply #1 on: July 05, 2021, 02:59:44 pm »
C64 feeling! :) (I like the font, especially the star) I tried it and it worked well for me. would you describe in more detail how the error can be caused?

Offline Jaze

  • Newbie
  • Posts: 86
    • View Profile
Re: Why is this returning to the menu?
« Reply #2 on: July 05, 2021, 03:08:14 pm »
Where there are 2 active balls on the screen the error can appear. If either of the balls goes below the paddle the game drops back to the main menu. Also, if there are 2 balls active and another bonus B is caught, the game drops back to the main menu.

Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
Re: Why is this returning to the menu?
« Reply #3 on: July 05, 2021, 05:55:03 pm »
what variable indicates whether BALL 1.2 is active?

Offline Jaze

  • Newbie
  • Posts: 86
    • View Profile
Re: Why is this returning to the menu?
« Reply #4 on: July 05, 2021, 06:03:44 pm »
if ball(1).x = 0 or ball(1).y = 0 then ball(1) isn't active. Same goes for ball(2).x and ball(2).y    There is also an independent TRUE /  FALSE secondBall which tells if there are two active balls but not which one is active when it is FALSE

Offline Jaze

  • Newbie
  • Posts: 86
    • View Profile
Re: Why is this returning to the menu?
« Reply #5 on: July 05, 2021, 07:01:27 pm »
I commented out
Code: QB64: [Select]
  1. numberOfGuys = numberOfGuys - 1
and it stopped the second ball from moving at all. I don't know why it would have that effect. From here I'll see if I can get both balls moving with that commented out. In any case, any suggestions would be greatly appreciated.

Offline Jaze

  • Newbie
  • Posts: 86
    • View Profile
Re: Why is this returning to the menu?
« Reply #6 on: July 05, 2021, 07:33:48 pm »
closed the ide without saving. reloaded the version posted. commented out the same lines and the ball moved but the game is still managing to find a way back to the main menu. If working properly the way it is now written, there is no way to exit the DO LOOP in the Main SUB. This is over my head.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Why is this returning to the menu?
« Reply #7 on: July 05, 2021, 08:40:30 pm »
closed the ide without saving. reloaded the version posted. commented out the same lines and the ball moved but the game is still managing to find a way back to the main menu. If working properly the way it is now written, there is no way to exit the DO LOOP in the Main SUB. This is over my head.

Is it catching an error with the ON ERROR and then falling through to restart the program?  At line 21, place an END statement to make certain you stop execution and read the error message and line.
« Last Edit: July 05, 2021, 08:41:39 pm by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline NOVARSEG

  • Forum Resident
  • Posts: 509
    • View Profile
Re: Why is this returning to the menu?
« Reply #8 on: July 06, 2021, 12:43:39 am »
Break out


Offline Jaze

  • Newbie
  • Posts: 86
    • View Profile
Re: Why is this returning to the menu?
« Reply #9 on: July 06, 2021, 01:45:20 am »
took the menu out. rewrote some subs to merge duplicates. didn't help. the score and the number of lives stayed the same but it reverted back to level 1. That's the second time I've had an issue with managing the level. I'll try a different method tomorrow.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Why is this returning to the menu?
« Reply #10 on: July 07, 2021, 09:38:49 am »
Hi Jaze
I agree totally with Steve!

1. please put END to distinghish between main module and SUBs/Functions

2. please manage the errors of I/O from files and pointers to images or sounds or something similar to these last.
for example here
Code: QB64: [Select]
  1. filename$ = "Level " + S$(currentLevel)
  2.         IF _FILEEXISTS(filename$) = 0 THEN filename$ = "Level " + S$(lastLevelCreated)
  3.         OPEN filename$ FOR INPUT AS #1 'open the file with the level information

in the rare case that lastLevelCreated is null (0 or "") and you try to open a file "Level0" or "Level" it is possible that it gets an error of file not found and this activates the generic  error trap that can bring the flow of execution in the main or in the place where you have put the manager of errors. And you got a flow error (a glitch) just to not manage the rare but possible case of error  with a second option name of the file to open.

Better twice sure than one!

Good Luck with your project.

Programming isn't difficult, only it's  consuming time and coffee

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: Why is this returning to the menu?
« Reply #11 on: July 07, 2021, 04:01:20 pm »
I am curious... According to Mr. Wozniak, Breakout is a "hardware only" game, so therefore, unless the first person copyrighted the first "software" version of the game, then the software version may be classified as Public Domain? But still, the game itself, will always be the intellectual property of Jobs/Wozniak... Just a random thought... Strange how I get those now and then... lol  Too bad they are usually never about how to improve coding... *sigh*
Logic is the beginning of wisdom.