Variables A$ name of user B$ temporary user input value A color of background B color of even bricks C color of odd bricks D color of paddle E color of ball I X coord of next ball pos J Y coord of next ball pos * 3 K Y coord of next ball pos (J/3, plottable Y coord) L current ball number (1-5) M indicates if we have not just hit the back wall (is usually 1, but is 0 when coming off the back wall until next hit) N count of paddle hits for the current ball P paddle position (Y coord of top pixel of paddle) Q temporary value S score SW are we in demo. mode? (1 = yes, auto paddle movement; 0 = no, user moves paddle) V ball X movement (V<0 means left, V>0 means right, ABS(V) is speed) W ball Y movement (W<0 means up, W>0 means down, ABS(W) is speed/angle) X ball X position (0-39) (0 is at paddle, 39 is at back wall) Y ball Y position * 3 (0-119) (0 is top of screen, 119 is bottom of screen) Implementation Notes To make the ball "bounce," change the sign of one of the coordinates of movement. For example, when the ball is approaching the paddle, V (the X movement) is negative; to make the ball bounce away toward the right, set V = -V, which makes V positive, thus making the ball bounce. Note that all calculations on the Y coordinate are done internally at a three times scale. Then only upon drawing is the Y coordinate divided by three (and rounded down). This allows for a precision of one third pixel (even though we are not using floating point numbers). Bricks in the first column are 1 point; bricks in the second column are 2 points; etc. up to 8 points per brick in the eighth column. Each brick is two pixels tall, so there are 20 bricks in each column. That makes a total of 720 points for all the bricks. While playing the game, if the paddle button is depressed while the ball is bouncing off the top or bottom of the screen, it will toggle "demo" mode. If demo mode is on, then the game controller is ignored, and instead the program automatically moves the paddle on the screen to hit the ball. Line-by-Line Annotated Version Initialization line 5 set "text" mode (turn off any graphics display) TEXT : clear the screen CALL -936 : display title VTAB 4 : TAB 10 : PRINT "*** BREAKOUT GAME ***" : PRINT line 7 display instructions PRINT " OBJECT IS TO DESTROY ALL BRICKS WITH 5 BALLS" : wait a few seconds FOR N = 1 TO 7000 : NEXT N line 10 allocate string variables ("dimension") DIM username (20 characters maximum) A$(20) , temporary user input string (20 characters maximum) B$(20) : set low resolution graphics mode (40x40 pixels) GR : get user’s name PRINT : INPUT "HI, WHAT'S YOUR NAME? ",A$ : set the default colors background (red) A=1 : even brick (yellow) B=13 : odd brick (orange) C=9 : paddle (blue) D=6 : ball (white) E=15 : ask the user if she wants to use the standard color scheme PRINT "STANDARD COLORS, "; A$; Color Customization line 20 if the user does want the default colors, then skip the next section (go to line 30) INPUT "? ", B$ : IF B$#"N" AND B$#"NO" THEN 30 : display color bars and ask the user to choose a color for each of the displayed elements of the game. draw color bars FOR I = 0 TO 39 : COLOR = I/2*(I<32) : VLIN 0, 39 AT I line 25 NEXT I : set four-line window at bottom of screen: POKE 34, 20 : PRINT : PRINT : PRINT : display color numbers FOR I = 0 TO 15 : VTAB 21+I MOD 2 : TAB I+I+1 : PRINT I; : NEXT I : set two-line window at bottom of screen: POKE 34, 22 : ask user each color, and put into vars A-E VTAB 24 : PRINT : PRINT "BACKGROUND"; line 27 subroutine at line 100 GOSUB 100 : A=E : PRINT "EVEN BRICK"; : GOSUB 100 : B=E : PRINT "ODD BRICK"; : GOSUB 100 : C=E : PRINT "PADDLE"; : GOSUB 100 : D=E : PRINT "BALL"; : GOSUB 100 Game Initialization line 30 new game starts here (after optionally picking colors) set 4-line text window at bottom POKE 34, 20 : draw background COLOR = A : FOR I = 0 TO 39 : VLIN 0, 39 AT I : NEXT I : draw bricks and column numbers (points) FOR I = 20 TO 34 STEP 2 : TAB I+1 : PRINT I/2-9; : COLOR = B : VLIN 0, 39 AT I : COLOR = C : FOR J = I MOD 4 TO 39 STEP 4 line 35 VLIN J, J+1 AT I : NEXT J, I : display score TAB 5 : PRINT "SCORE = 0" : PRINT : PRINT : set 3-line window at bottom POKE 34, 21 : initialize score (col n brick is n points; 720 is full game all bricks) S = 0 : initialize paddle position (Y coord of top pixel of paddle) P = S : initialize current ball number L = S : Initialize ball X position. Note that X must start out less than 20 so it does not erase a brick in the PLOT at line 40. X = 19 : initialize ball Y position * 3 Y = 19 : BUG: redundant initialization of X X = 19 Ball Movement and Collision line 40 New ball starts here. Erase any previous ball COLOR = A : PLOT X, Y/3 : Set initial ball postion (X,Y) and movement vectors (V,W) Set X coordinate to be at the bricks, and Y coordinate as a random 0-39 position (times 3). X = 19 : Y = RND(120) : Initialize ball movement. X movement V<0 means left, V>0 means right, ABS(V) is speed Y movement W<0 means up, W>0 means down, ABS(W) is speed/angle V = -1 : W = RND(5)-2 : next ball L = L+1 : if we just missed our last ball, then the game is over (go to line 140) IF L > 5 THEN 140 : display ball number TAB 6 : PRINT "BALL #"; L : PRINT : do not start the game yet, wait a while (but still let the user move the paddle via subroutine at line 200) FOR I = 1 TO 100 : GOSUB 200 : NEXT I : we did not just bounce off the back wall M = 1 : count of paddle hits for the current ball N = 0 line 50 Calculate next Y coordinate of ball (new Y = old Y + Ymovement) J = Y+W : If new value did not go off top or bottom, go to line 60 IF J >= 0 AND J < 120 THEN 60 : else, the ball hit the top or bottom, so we need to make it bounce off set new Ymovement (if was moving up, then set to down; if was moving down, then set to up) W = -W : restore Y coordinate (this keeps the ball at the top or bottom edge of the screen, instead of off-screen; it will bounce on the next iteration) J = Y : make a sound to indicate bounce FOR I = 1 TO 6 : K = PEEK(-16336) : NEXT I line 55 if paddle button depressed, toggle demonstration mode on or off IF PEEK(-16287) > 127 THEN SW = 1-SW line 60 Calculate next X coordinate of ball (new X = old X + Xmovement) I = X+V : if we went off the left edge, the user missed the ball, so go to line 400 IF I < 0 THEN 400 : else, the ball is still in play somewhere move the displayed paddle based on user control via soubroutine at line 200 GOSUB 200 : set to background color (to prepare for erasing a hit brick) COLOR = A : calc plottable Y coordinate (into K) K = J/3 : if we hit the back wall (behind the bricks) go to line 70 IF I > 39 THEN 70 : check what is on the screen at the position of the ball, in order to find out what it hit (if anything) if we did not hit anything (background color), then go to line 90 IF SCRN(I,K) = A THEN 90 : else, we must have hit either a brick or the paddle; we can tell which one by checking the X coordinate of the ball. if X > 0, then we hit a brick, so go to line 120 IF I THEN 120 : else, we must have hit the paddle, so increment count of paddle hits for this ball N = N+1 : set Xmovement to positive (towards the bricks), and at a speed of 1 (slow) if we have had less than 10 hits this ball, or a speed of 2 (fast) if we have had 10 or more hits. V = (N>9)+1 : set Ymovement The position of the ball on the paddle is K-P, which will be from 0 to 5, 0 being the top of the paddle, and 5 being the bottom. The sets of possible values of the terms in the calculation of W, below, is shown here: K-P = { 0, 1, 2, 3, 4, 5 } *2 = { 0, 2, 4, 6, 8, 10 } -5 = {-5, -3, -1, 1, 3, 5 } These represent the angle (up or down) that the ball bounces off the paddle. So striking near the middle of the paddle sends the ball straighter, and striking near the edge of the paddle sends the ball at a more oblique angle, up (for positive W) or down (for negative W) W = (K-P)*2-5 : indicate that we did not just bounce off the back wall M = 1 line 65 make a sound, and go to line 90 Z = PEEK(-16336)-PEEK(-16336)-PEEK(-16336)-PEEK(-16336)-PEEK(-16336)-PEEK(-16336)-PEEK(-16336) : GOTO 90 line 70 (we come here if the ball has hit the back wall) make a sound FOR I = 1 TO 6 : M = PEEK(-16336) : NEXT I : restore Xpos (keep ball at back wall, instead of off the screen) I = X : indicate that we have hit the back wall M = 0 line 80 ball bounces off of back wall or a brick, so toggle X direction V = -V line 90 erase previous ball position (plot background color) PLOT X, Y/3 : display the ball (new ball position I,K) COLOR = E : PLOT I, K : store new ball position (I,J) into current ball position (X,Y) X = I : Y = J : Go to line 50 GOTO 50 Color Input Subroutine line 99 function to ask user for a color (enter at line 100). output: E the color that the user chose (0-15) PRINT "INVALID. REENTER"; line 100 Ask user to enter color. If OK, then return from function, otherwise go to line 99 to print error message. INPUT " COLOR (0 TO 15)", E : IF E < 0 OR E > 15 THEN 99 : RETURN Hit a Brick line 120 We have hit a brick. We need to fix the ball direction. We do this by making sure the sign of V is correct. Negative V means move left, and positive V means move right. However, we will later be toggling the sign (at line 80), so here we set it to the opposite of what we need it to be. Usually, when we hit a brick we want to move left after that, so set V positive here (and it will become negative at line 80). However there is a special case; after we hit the back wall, we want the ball to be able to bounce off the back side of the bricks and go towards the back wall again. So if we have just hit the back wall (indicated by M being zero), then leave V as negative (and it will switch to positive at line 80, so the ball will move right, towards the back wall again). IF M THEN V = ABS(V) : erase the whole brick (each brick is two pixels tall) VLIN K/2*2, K/2*2+1 AT I : increase score S = S+I/2-9 : display score VTAB 21 : TAB 13 : PRINT S line 123 make a sound Q = PEEK(-16336)-PEEK(-16336)-PEEK(-16336)-PEEK(-16336)-PEEK(-16336)- PEEK(-16336)-PEEK(-16336)-PEEK(-16336)-PEEK(-16336)-PEEK(-16336) line 124 if user has not cleared all the bricks yet, then continue playing (go to line 80) IF S < 720 THEN 80 else the user won, so fall through: Game Over line 130 game over (a win enters here; a loss enters at line 140) print the evaluation message corresponding to the user’s score, then go to line 150 a score of 720 is a win PRINT "CONGRATULATIONS, YOU WIN." : GOTO 150 line 140 go to appropriate line number depending on score (in hundreds) PRINT "YOUR SCORE OF "; S; " IS "; : GOTO 141+S/100 line 141 score 0-99 PRINT "TERRIBLE!" : GOTO 150 line 142 score 100-199 PRINT "LOUSY." : GOTO 150 line 143 score 200-299 PRINT "POOR." : GOTO 150 line 144 score 300-399 PRINT "FAIR." : GOTO 150 line 145 score 400-499 PRINT "GOOD." : GOTO 150 line 146 score 500-599 PRINT "VERY GOOD." : GOTO 150 line 147 score 600-699 PRINT "EXCELLENT." : GOTO 150 line 148 score 700-719 PRINT "NEARLY PERFECT." line 150 go back to let user pick colors and restart the game, to line 20 PRINT "SAME COLORS"; : GOTO 20 Paddle Movement Subroutine line 200 function to move displayed paddle based on user control in/out: P on input, previous position; on output, current position (where position is Y coord of top-most pixel of paddle, 0-34) in: A background color D paddle color SW demo. mode (1 or 0) if in demo. mode, then also input: V ball X movement W ball Y movement X ball X position Y ball Y position if in demo. mode, then go to line 220 IF SW THEN 220 : get paddle postion (Q) (top end of paddle) PDL(0) paddle 0 ? 0 to 255 -5 ? -5 to 250 /6 ? 0 to 41 Q = (PDL(0)-5)/6 : BUG: unnecessary check for Q < 0; acutally Q cannot be less than zero here IF Q < 0 THEN Q = 0 line 205 constrain Q [0,34] IF Q >= 34 THEN Q = 34 : draw paddle 6 pixels tall, possible positions: (0,5) to (34,39) COLOR = D : VLIN Q, Q+5 AT 0 : erase old paddle BUG: P > Q should be P >= Q COLOR = A : IF P > Q THEN 210 : paddle moved down, so erase area above paddle, and return IF Q THEN VLIN 0, Q-1 AT 0 : P = Q : RETURN line 210 paddle did not move, so just return IF P = Q THEN RETURN : paddle moved up, so erase area below paddle, and return IF Q # 34 THEN VLIN Q+6, 39 AT 0 : P = Q : RETURN line 220 demo. mode: ignore real paddle, instead automatically position the paddle so it hits the ball if the ball is coming towards the paddle (V<0), and is close to the paddle (X<10), then add some random wiggle to the paddle Q = (Y-5)/3 + RND(3)*SGN(W)*(X<10 AND V<0) : IF Q < 0 THEN Q = 0 : we only come here from line 200, so we always return to line 205 GOTO 205 Sound for Missed the Ball line 400 make a sound, then go to line 40 FOR I = 1 TO 80 : Q = PEEK(-16336) : NEXT I : GOTO 40