Paddle Ball

En 1974, Nolan Bushnell et Al Alcom, forts du succès de Pong (voir Tennis de table), cherchaient un nouveau tube et décidèrent de confier cette tâche à leur quarantième employé, le jeune Steve Jobs.

Le concept était Breakout : un jeu dérivé de Pong où un joueur, à l’aide d’une raquette, devait envoyer une balle sur des blocs situés en haut de l’écran, prêts à être détruits.

Jobs n’étant pas à la hauteur de la programmation, il recruta secrètement son ami Steve Wozniak, plus âgé et bien plus doué techniquement, pour concevoir le jeu. La création d’Apple Computer, alors encore à l’état de projet pour Jobs, n’était qu’à quelques années.

PADDLE.BAS, dont le code est présenté ci-dessous, n’est pas un clone de Breakout (il ne contient par exemple qu’un seul niveau), mais, à l’instar de TENNIS.BAS, il s’agit d’une tentative de démonstration de la création d’une version de ce jeu d’arcade en GW-BASIC.

Grâce à plusieurs instructions GET, tous les éléments visuels sont immédiatement chargés en mémoire.

Une fois les blocs disposés à l'écran (voir la sous-routine commençant à la ligne 700), une instruction INKEY gère les entrées utilisateur tandis que des fonctions POINT vérifient si la balle « touche » la raquette (ligne 330.

Notez comment la fonction RND introduit une part d'imprévisibilité dans la déviation) ou une brique (lignes 335 à 375) en capturant la couleur des pixels à huit emplacements autour de la balle : si la couleur est bleu foncé (COULEUR 1), la balle vient de toucher la raquette et doit être renvoyée vers le haut ; si la couleur est gris clair (COULEUR 7), la balle vient de percuter une brique et doit être renvoyée.

De plus, une fois touchée, la brique doit être effacée de l'écran (voir la sous-routine commençant à la ligne 800). Une sous-routine vers la fin du programme compte le nombre de briques restantes à détruire. Une fois qu'ils auront tous disparu, vous aurez terminé le niveau.

Outre l'ajustement du comportement de la balle et la correction de certains bugs occasionnels (ainsi que du scintillement associé), de nombreuses pistes d'amélioration s'offrent à vous.

Par exemple : on pourrait expérimenter avec des blocs de différentes couleurs et tailles, dans diverses combinaisons et agencements.

On pourrait créer plusieurs niveaux. On pourrait offrir des balles supplémentaires (c'est-à-dire des vies) au joueur. Et on pourrait concevoir des défis supplémentaires, tels que des blocs qui « ripostent ».

PADDLE.BAS

10 KEY OFF:SCREEN 7:COLOR 15,0:CLS:RANDOMIZE TIMER:LIFE=2:TOTALBRICKS=0
20 DIM PADDLE(70):DIM BALL(30):DIM BRICK(100)
30 PSET(2,2),1:LINE -(40,2),1:LINE -(40,5),1:LINE -(2,5),1:LINE -(2,2),1:PAINT(3,3),11,1
40 GET(2,2)-(40,5),PADDLE
50 CLS
60 CIRCLE(5,5),2,14:PAINT(5,5),6,14
70 GET(2,2)-(7,7),BALL
80 CLS
90 PSET(2,2),7:LINE -(30,2),7:LINE -(30,13),7:LINE -(2,13),7:LINE -(2,2),7:PAINT(3,3),4,7
100 GET(2,2)-(30,13),BRICK
110 CLS
120 PRINT,"--- PADDLE BALL ---"
130 PRINT:PRINT"TO MOVE THE PADDLE LEFT/RIGHT, PRESS A/S"
140 PRINT"TO EXIT AT ANY TIME, PRESS <ESC>"
150 PRINT"PRESS ANY OTHER KEY TO START..."
160 Y$=INKEY$
165 IF Y$="" THEN 160
170 IF Y$=CHR$(27) THEN END ELSE 200
200 CLS
202 GOSUB 700 'Draw bricks
205 X=150:BX=130:BY=120
206 A=1:B=1
207 LOCATE 23,1:PRINT"BALLS LEFT:";LIFE
210 I$=INKEY$
220 IF I$=CHR$(27) THEN CLS:END
230 IF I$="A" OR I$="a" THEN X=X-10
240 IF I$="S" OR I$="s" THEN X=X+10
250 IF X<10 THEN X=10
260 IF X>270 THEN X=270
270 PUT(X,160),PADDLE:PUT(BX,BY),BALL,XOR
275 IF TEMP=0 THEN PUT(BX,BY),BALL:TEMP=1
300 IF BX<10 OR BX>290 THEN A=-A
310 IF BY<20 THEN B=-B
320 IF BY>170 THEN GOSUB 600
330 IF POINT(BX+6,BY+6)=1 THEN B=-B:A=A+INT(1+2*RND(1))-(1+RND)
335 'Check to see ball hits a brick
340 IF POINT(BX,BY)=7 THEN A=-A:B=-B:GOSUB 800
345 IF POINT(BX+3,BY)=7 THEN B=-B:GOSUB 800
350 IF POINT(BX+6,BY)=7 THEN A=-A:B=-B:GOSUB 800
355 IF POINT(BX+6,BY+3)=7 THEN A=-A:GOSUB 800
360 IF POINT(BX+6,BY+6)=7 THEN A=-A:B=-B:GOSUB 800
365 IF POINT(BX+3,BY+6)=7 THEN B=-B:GOSUB 800
370 IF POINT(BX,BY+6)=7 THEN A=-A:B=-B:GOSUB 800
375 IF POINT(BX,BY+3)=7 THEN A=-A:GOSUB 800
400 BY=BY+B:BX=BX+A
485 FOR PAUSE=1 TO 50:NEXT PAUSE
490 PUT(X,160),PADDLE:PUT(BX,BY),BALL
500 GOTO 210
600 'Check to see if game's over
605 LIFE=LIFE-1:TEMP=0
610 IF LIFE<0 THEN LOCATE 14,17
612 PRINT"GAME OVER":FOR PAUSE=1 TO 20000:NEXT PAUSE:CLS:END
615 BX=130:BY=120:TEMP=0
620 GOTO 207
700 'Draw bricks
705 FOR COLUMNS=20 TO 80 STEP 30
710 FOR ROWS=10 TO 290 STEP 30
720 PUT(ROWS,COLUMNS),BRICK
730 NEXT ROWS
735 NEXT COLUMNS
749 RETURN
800 'Delete appropriate brick when it's hit
810 TOTALBRICKS=TOTALBRICKS-1
825 FOR COLUMNS=20 TO 80 STEP 30
830 FOR ROWS=10 TO 290 STEP 30
840 IF BX>=ROWS AND BX<=ROWS+30 AND BY>=COLUMNS AND BY<=COLUMNS+30 THEN GOSUB 882
850 NEXT ROWS
865 NEXT COLUMNS
867 GOSUB 900
870 IF TOTALBRICKS=0 THEN LOCATE 14,12:PRINT"YOU CLEARED THE LEVEL":FOR PAUSE=1 TO 20000:NEXT PAUSE:CLS:END
880 RETURN
882 'Erase single brick
883 FOR O=ROWS TO ROWS+28:FOR P=COLUMNS TO COLUMNS+11:PSET(O,P),0:NEXT P:NEXT O
884 RETURN
900 'Count how many bricks are left on-screen
905 TOTALBRICKS=0
910 FOR COLUMNS=20 TO 80 STEP 30
920 FOR ROWS=10 TO 290 STEP 30
930 IF POINT(ROWS+5,COLUMNS+5)=4 THEN TOTALBRICKS=TOTALBRICKS+1
940 NEXT ROWS
950 NEXT COLUMNS
960 RETURN