Page 1 of 1

Trajectoire de balle et rebonds

Unread postPosted: 29 Jan 2025, 22:15
by canomod74
Bonjour :) ,

j'ai créé un petit programme, sur la HP PRIME G2 pour simuler le lancer d'un ballon de basket avec une équation de trajectoire, mais je rencontre un problème avec les collisions contre les mur.
Lorsque la balle arrive au bord droit de l'écran, elle repart bien vers la gauche, mais pas dans la continuité de la trajectoire, on dirait qu'elle repart avec la même énergie qu'au rebond précèdent.

Code: Select all
VIEW "NBA JAM", START()
BEGIN
  LOCAL x, y, x0, y0, v0, t;
  LOCAL theta, g;
  LOCAL vx, vy;

  // Initialisation des variables
  x0 := 20;
  y0 := 100;
  v0 := 20;     
  theta := 77; 
  g := 9.81/8; 

  // Vitesse initiale
  vx := v0 * COS(theta*π/180);
  vy := v0 * SIN(theta*π/180);

  t := 0;

  // Chargement des images
  G2 := AFiles("fond_basket.png");
  G3 := AFiles("ballon_basket.png");

  DIMGROB_P(G1, 320, 240, #000000);

  REPEAT
   // Affichage des images
   BLIT_P(G1, 0, 0, G2);
   BLIT_P(G1, x, 239 - y, G3);
   BLIT_P(G0, 0, 0, 320, 240, G1);
   
   // Mise à jour des coordonnées
   x := x0 + vx * t;
   y := y0 + vy * t - (1/2) * g * t^2;

   // Rebond au sol 
   IF y < 60 THEN
     y  := 60;
     vy := -vy * 0.9; // Perte d'énergie
     x0 := x;  // On garde x au moment du rebond
     y0 := y;  // Maintenant y0 pour repartir du sol
     t := 0; 
   END;

   // Rebond mur gauche 
   IF x < 0 THEN
     x  := 0;
     vx := -vx; // Inversion de vitesse
     x0 := x;  // Mise à jour du point de départ
     y0 := y;  // Continuité de la hauteur
     t := 0;   
   END;

   // Rebond mur droit 
   IF x > 320 THEN
     x  := 320;
     vx := -vx; // Inversion de vitesse
     x0 := x;  // Mise à jour du point de départ
     y0 := y;  // Continuité de la hauteur
     t := 0; 
   END;

   t := t + 0.1;
   WAIT(0.002);
  UNTIL (x > 320 AND vx > 0) OR ABS(vy) < 1;

  WAIT;
END;


Si vous trouvez d'où peux venir le problème, car je sèche . :bored:

Re: Trajectoire de balle et rebonds

Unread postPosted: 30 Jan 2025, 00:17
by critor
Bonjour.

Je n'ai pas les images donc j'ai bricolé, mais je confirme le problème sur les rebonds sur les bords droit et gauche.
Image

Re: Trajectoire de balle et rebonds

Unread postPosted: 30 Jan 2025, 00:23
by critor
Et effectivement, tu traites les rebonds à droite/gauche, de façon similaire au rebond bas.

C'est-à-dire que tu prends un nouveau point de départ (x0, y0, t=0) et donc repars de ce dernier point à vitesse maximale.

Là de suite, je ne vois pas de façon évidente de corriger sans complexifier sensiblement le code, ou bien le changer radicalement car je n'aurais pas codé la trajectoire de cette façon.

Re: Trajectoire de balle et rebonds

Unread postPosted: 30 Jan 2025, 10:17
by canomod74
Salut, d'accord, si tu as un moment pour me proposer la solution à laquelle tu penses, avec plaisir, je vais continuer à chercher de mon côté

Re: Trajectoire de balle et rebonds

Unread postPosted: 30 Jan 2025, 12:25
by critor
Bonjour.

Finalement j'y arrive sans faire plus compliqué et en restant sur un fonctionnement paramétrique, juste en utilisant les paramètres de façon un peu différente.
Code: Select all
EXPORT TEST()
BEGIN
  LOCAL x, y, ysol, v0, t, dt;
  LOCAL theta, g;
  LOCAL vx, vy;

  // Initialisation des variables
  x := 20;
  y := 100;
  ysol := 60;
  v0 := 20;     
  theta := 77;
  g := 9.81/8;
  dt := 0.1;

  // Vitesse initiale
  vx := v0 * COS(theta*π/180);
  vy := v0 * SIN(theta*π/180);

  t := 0;

  // Chargement des images
  G2 := AFiles("fond_basket.png");
  G3 := AFiles("ballon_basket.png");

  DIMGROB_P(G1, 320, 240, #000000);

  REPEAT
   // Affichage des images
   BLIT_P(G1, 0, 0, G2);
   BLIT_P(G1, x, 239 - y, G3);
   BLIT_P(G0, 0, 0, 320, 240, G1);
   
   // Mise à jour des coordonnées
   x := x + vx*dt;
   y := y + vy*dt;
   vy := vy - g*dt;

   // Rebond au sol
   IF y < ysol AND vy < 0 THEN
     vy := -vy * 0.8; // Perte d'énergie
   END;

   // Rebond mur gauche ou droit
   IF x < 0 AND vx < 0 OR x > 319 AND vx > 0 THEN
     vx := -vx; // Inversion de vitesse
   END;

   WAIT(0.002);
  UNTIL y < ysol AND ABS(vy) < 1;

  WAIT;
END;

Image

Re: Trajectoire de balle et rebonds

Unread postPosted: 30 Jan 2025, 18:02
by canomod74
Parfait merci beaucoup :)

J'ai ajusté un peu les valeur pour que ça soit réaliste, mais c'est top.

Plus qu'a faire un petit jeu maintenant que j'ai la base qui va bien

Re: Trajectoire de balle et rebonds

Unread postPosted: 30 Jan 2025, 18:05
by arnaudfpm
Bravo, j'allais te dire au lieu de réinitialiser t := 0, il faut calculer une nouvelle origine temporelle en fonction du dernier instant de rebond.


critor wrote:Bonjour.

Finalement j'y arrive sans faire plus compliqué et en restant sur un fonctionnement paramétrique, juste en utilisant les paramètres de façon un peu différente.
Code: Select all
EXPORT TEST()
BEGIN
  LOCAL x, y, ysol, v0, t, dt;
  LOCAL theta, g;
  LOCAL vx, vy;

  // Initialisation des variables
  x := 20;
  y := 100;
  ysol := 60;
  v0 := 20;     
  theta := 77;
  g := 9.81/8;
  dt := 0.1;

  // Vitesse initiale
  vx := v0 * COS(theta*π/180);
  vy := v0 * SIN(theta*π/180);

  t := 0;

  // Chargement des images
  G2 := AFiles("fond_basket.png");
  G3 := AFiles("ballon_basket.png");

  DIMGROB_P(G1, 320, 240, #000000);

  REPEAT
   // Affichage des images
   BLIT_P(G1, 0, 0, G2);
   BLIT_P(G1, x, 239 - y, G3);
   BLIT_P(G0, 0, 0, 320, 240, G1);
   
   // Mise à jour des coordonnées
   x := x + vx*dt;
   y := y + vy*dt;
   vy := vy - g*dt;

   // Rebond au sol
   IF y < ysol AND vy < 0 THEN
     vy := -vy * 0.8; // Perte d'énergie
   END;

   // Rebond mur gauche ou droit
   IF x < 0 AND vx < 0 OR x > 319 AND vx > 0 THEN
     vx := -vx; // Inversion de vitesse
   END;

   WAIT(0.002);
  UNTIL y < ysol AND ABS(vy) < 1;

  WAIT;
END;

Image

Re: Trajectoire de balle et rebonds

Unread postPosted: 30 Jan 2025, 18:38
by critor
arnaudfpm wrote:Bravo, j'allais te dire au lieu de réinitialiser t := 0, il faut calculer une nouvelle origine temporelle en fonction du dernier instant de rebond.


critor wrote:Bonjour.

Finalement j'y arrive sans faire plus compliqué et en restant sur un fonctionnement paramétrique, juste en utilisant les paramètres de façon un peu différente.
Code: Select all
EXPORT TEST()
BEGIN
  LOCAL x, y, ysol, v0, t, dt;
  LOCAL theta, g;
  LOCAL vx, vy;

  // Initialisation des variables
  x := 20;
  y := 100;
  ysol := 60;
  v0 := 20;     
  theta := 77;
  g := 9.81/8;
  dt := 0.1;

  // Vitesse initiale
  vx := v0 * COS(theta*π/180);
  vy := v0 * SIN(theta*π/180);

  t := 0;

  // Chargement des images
  G2 := AFiles("fond_basket.png");
  G3 := AFiles("ballon_basket.png");

  DIMGROB_P(G1, 320, 240, #000000);

  REPEAT
   // Affichage des images
   BLIT_P(G1, 0, 0, G2);
   BLIT_P(G1, x, 239 - y, G3);
   BLIT_P(G0, 0, 0, 320, 240, G1);
   
   // Mise à jour des coordonnées
   x := x + vx*dt;
   y := y + vy*dt;
   vy := vy - g*dt;

   // Rebond au sol
   IF y < ysol AND vy < 0 THEN
     vy := -vy * 0.8; // Perte d'énergie
   END;

   // Rebond mur gauche ou droit
   IF x < 0 AND vx < 0 OR x > 319 AND vx > 0 THEN
     vx := -vx; // Inversion de vitesse
   END;

   WAIT(0.002);
  UNTIL y < ysol AND ABS(vy) < 1;

  WAIT;
END;

Image

La variable t n'est plus utilisée, il suffit de supprimer les dernières lignes la mentionnant :
Code: Select all
EXPORT TEST()
BEGIN
  LOCAL x, y, ysol, v0, dt;
  LOCAL theta, g;
  LOCAL vx, vy;

  // Initialisation des variables
  x := 20;
  y := 100;
  ysol := 60;
  v0 := 20;     
  theta := 77;
  g := 9.81/8;
  dt := 0.1;

  // Vitesse initiale
  vx := v0 * COS(theta*π/180);
  vy := v0 * SIN(theta*π/180);

  // Chargement des images
  G2 := AFiles("fond_basket.png");
  G3 := AFiles("ballon_basket.png");

  DIMGROB_P(G1, 320, 240, #000000);

  REPEAT
   // Affichage des images
   BLIT_P(G1, 0, 0, G2);
   BLIT_P(G1, x, 239 - y, G3);
   BLIT_P(G0, 0, 0, 320, 240, G1);
   
   // Mise à jour des coordonnées
   x := x + vx*dt;
   y := y + vy*dt;
   vy := vy - g*dt;

   // Rebond au sol
   IF y < ysol AND vy < 0 THEN
     vy := -vy * 0.8; // Perte d'énergie
   END;

   // Rebond mur gauche ou droit
   IF x < 0 AND vx < 0 OR x > 319 AND vx > 0 THEN
     vx := -vx; // Inversion de vitesse
   END;

   WAIT(0.002);
  UNTIL y < ysol AND ABS(vy) < 1;

  WAIT;
END;