Mouvement d'un projectile

GW-Basic, utilisé par PC-Basic

Programme avec Graphique et Texte

PC-BASIC

Combiner les méthodes de codage d'un plan de coordonnées (dans COORD.BAS) avec les fonctions trigonométriques (dans TRIG.BAS) peut donner lieu à des applications de programmation intéressantes, comme la modélisation du mouvement d'un projectile à l'écran.

Tout d'abord, un mot sur la physique.

Nous devons définir un certain nombre de variables : le temps écoulé depuis le lancement, t, la vitesse de lancement, V0 ; l'angle de lancement, θ ; l'accélération gravitationnelle, g, la vitesse horizontale initiale, V0x ; la vitesse verticale initiale, V0y ; et les coordonnées du projectile, x et y, qui représentent les déplacements horizontaux et verticaux.

Les formules de modélisation du mouvement d'un projectile nécessitent un peu de trigonométrie. Les vitesses horizontale et verticale initiales du corps en mouvement sont données par:

V0x = V0 * cosθ

V0y = V0 * sinθ

tandis que les déplacements horizontaux et verticaux sont trouvés avec les formules suivantes :

x = V0 * t * cosθ

 Vy = V0 * t * sinθ - 0,5gt²

Notez que si le temps (t) joue un rôle à la fois horizontalement et verticalement, la gravité (g) n'intervient que dans l'équation du déplacement vertical, ce qui conduit à l'idée contre-intuitive qu'une balle tirée par une arme à feu touchera le sol en même temps qu'une balle lâchée de la même hauteur initiale (en supposant que la balle tirée ne heurte pas d'abord quelque chose sur sa trajectoire).

Plutôt que de simplement créer une animation d'un objet en mouvement, créons un jeu rudimentaire autour des formules de mouvement des projectiles. Que diriez-vous de pouvoir lancer une balle dans un panier placé au hasard, en définissant l'angle de lancement et la vitesse initiale de la balle ?

Si c'est votre rêve (plutôt anodin) est un jeu vidéo, alors PROD.BAS devrait largement le réaliser.

Plutôt que de simplement saisir la vitesse initiale et l'angle de lancement, il serait plus amusant de définir visuellement la trajectoire et la vitesse de lancement de la balle.

PROD.BAS utilise une ligne dynamique tirée depuis la balle au repos pour réaliser cette astuce : vous pouvez faire pivoter la ligne en modifiant l'angle de lancement et l'allonger en augmentant la vitesse initiale. Lorsque vous appuyez sur la barre d'espace, la balle suit, au moins initialement, la trajectoire de la ligne.

La ligne dynamique, comme beaucoup d'autres fonctions de PROD.BAS, nécessite un peu de trigonométrie pour fonctionner.

Rappelons qu'avant d'appeler une fonction trigonométrique GW-BASIC, les mesures d'angle doivent être converties en radians.

Avant d'examiner le code de PROD.BAS, examinez attentivement le code de FAN.BAS ci-dessous pour comprendre comment une ligne peut pivoter sur un axe ; exécutez le programme et un motif en éventail de couleurs vives apparaîtra lentement à l'écran.

Nous utiliserons certaines des techniques de FAN.BAS pour construire PROD.BAS.

Le panier placé aléatoirement est généré aux lignes 16 et 17, tandis qu'une instruction INKEY$ accepte les saisies au clavier de l'utilisateur à partir de la ligne 22.

La ligne 23 calcule les coordonnées x et y du ballon ; les lignes 24 et 25 dessinent le ballon et la ligne dynamique (qui représente la trajectoire et la vitesse initiales du ballon).

Une fois le ballon lancé, le programme doit incrémenter continuellement la variable temps (voir ligne 100) ; il doit également vérifier si le ballon atterrit finalement à l'intérieur ou à l'extérieur du panier ; les lignes 210 et 215 gèrent cette tâche à l'aide d'instructions conditionnelles.

Enfin, une variable compteur, appelée COUNTER, enregistre les coups et les ratés du ballon.

Bien que le programme modélise (en grande partie) correctement le mouvement des projectiles, la présentation pourrait être améliorée.

Au lieu d'une balle, pourquoi pas… une banane ?

Et au lieu de lancer une balle dans un panier, pourquoi pas une banane dans une cage occupée par un singe glouton ?

Ou, mieux encore, essayez de coder une version GW-BASIC d'Angry Birds.

Ajustez légèrement la physique pour réduire – ou augmenter – la gravité. Les possibilités sont infinies.

FAN.BAS

5 SCREEN 9:KEY OFF:COLOR 15,0:CLS
10 FOR ANGLE = 0 TO 90*3.14159/180 STEP .05
20 PSET(COS(ANGLE)*100+100,200-SIN(ANGLE)*100),15:LINE -(102,200),INT(1*15*RND(1))
25 FOR PAUSE=1 TO 900:NEXT PAUSE
30 NEXT ANGLE

PROJ.BAS

10 KEY OFF:SCREEN 9:COLOR 15,0:CLS:RANDOMIZE TIMER
11 TOTAL=TOTAL+1 'Accounting for a new game
15 PRINT"--- Launch the ball into the basket ---": PRINT
16 R=INT(1+450*RND(1))+50 'Begin to draw basket
17 PSET(R,300),15:LINE -(R,340),15:LINE -(R+99, 340),15:LINE -(R+99,300),15
20 X=0:Y=0:V=3:ANGLE=45
21 PRINT"Press +/- to adjust launch angle": PRINT"Press A/S to adjust initial velocity": PRINT"Press <SPACE> to launch ball"
22 I$=INKEY$
23 THETA=ANGLE*3.14159/180:M=COS(THETA)*V*10+100: N=200-SIN(THETA)*V*10 'Convert angle to radians, then find the x and y coordinates
24 LINE(102,200)-(M,N),15:CIRCLE(102,200),15,15: FOR PAUSE=1 TO 106:NEXT PAUSE
25 LINE(102,200)-(M,N),0:CIRCLE(102,200),15,0
26 GOSUB 300
27 GOTO 22
28 G=9.8 'Constant of gravity
29 T=0 'Starting time = 0
39 THETA=ANGLE*3.14159/180 'Convert angle to radians
40 VX=V*COS(THETA) 'Find initial horizontal velocity
50 VY=V*SIN(THETA) 'Find initial vertical velocity
60 CIRCLE(100*X+100,200-100*Y),15,15
62 FOR PAUSE=1 TO 200:NEXT PAUSE
64 CIRCLE(100*X+100,200-100*Y),15,0
70 X=X+VX*.02 'Calculate the horizontal coordinates
80 VY=VY-G*.02 'Calculate the vertical velocity taking into account gravity '
90 Y=Y+VY*.02 'Calculate the vertical coordinates
100 T=T+.02 'Increment time
105 IF (200-100*Y)>321 THEN GOTO 200
110 GOTO 60
200 'Check to see if ball made it in the "basket"
205 CIRCLE(100*X+100,200-100*Y),15,15
210 IF (100*X+100)>R+15 AND (100*X+100)<R+84 THEN COUNT=COUNT+1:LOCATE 8,10:PRINT"MADE IT!":LOCATE 9,10:PRINT"You've made ";COUNT;" out of";TOTAL;" shots."
215 IF (100*X+100)<R+15 OR (100*X+100)>R+84 THEN LOCATE 8,10
218 PRINT"MISSED IT!":LOCATE 9,10: PRINT"You've made ";COUNT;" out of ";TOTAL;" shots."
220 FOR PAUSE=1 TO 20000:NEXT PAUSE
230 PRINT:INPUT"Another (0=Yes, 1=No)";ANOTHER
240 IF ANOTHER=0 THEN GOTO 10 ELSE CLS:END
300 IF I$="+" THEN ANGLE=ANGLE+1
310 IF I$="-" THEN ANGLE=ANGLE-1
320 IF I$="A" OR I$="a" THEN V=V-1
330 IF I$="S" OR I$="s" THEN V=V+1
340 IF I$=CHR$(27) THEN CLS:END
350 IF I$=" " THEN GOTO 28
351 IF V<0 THEN V=0
352 IF V>8 THEN V=8
355 LOCATE 6,1:PRINT"Angle = ";ANGLE;" and Velocity = ";V
360 RETURN