Page 1 of 1

Trajectoire de balle et rebonds

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

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

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

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

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

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

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

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;

Re: Trajectoire de balle et rebonds

PostPosted: 31 Jan 2025, 20:57
by canomod74
Bonsoir, j'ai avancé un peu mon code, si vous voulez tester. C'est encore loin d'être terminé, mais on peut déjà avec la croix directionnelle choisir l'angle et la force, ENTER pour lancer, Esc pour arrêter la balle (si envoyé trop fort) :

C'est une application basé sur "Fonction" et les images sont en bas du message :)

Code: Select all
// ********************* //
// ----- Fonctions ----- //
// ** Conversion Degré vers Radians
DegToRad(adr)
BEGIN
RETURN adr * π / 180;
END;

// ** Affiche un rectangle vide
// **  x, y en bas à gauche
Rect_Vide(grob_dest, x1, y1, x2, y2, color)
BEGIN
LINE_P(grob_dest, x1, Ymax-y1, x2, Ymax-y1, color);
LINE_P(grob_dest, x2, Ymax-y1, x2, Ymax-y2, color);
LINE_P(grob_dest, x2, Ymax-y2, x1, Ymax-y2, color);
LINE_P(grob_dest, x1, Ymax-y2, x1, Ymax-y1, color);
END;

// ** Affiche un Grob
// ** x, y en bas à gauche
Blit_Pict(grob_dest, x, y, grob_src)
BEGIN
BLIT_P(grob_dest, x, Ymax-y, grob_src);
END;

// ** Affiche un rectangle plein avec contour
// ** x, y en bas à gauche
Rect_Pict(grob_dest, x1, y1, x2, y2, col_out, col_in)
BEGIN
RECT_P(grob_dest, x1, Ymax-y1, x2, 239-y2, col_out, col_in);
END;

// ** Affiche un arc de cercle
// ** angle1 vers angle2 (sens trigo)
// ** base x, y en bas à gauche
// ** colors = {contour, remplissage}
Arc_Pict(grob_dest, x, y, rayon, angle1, angle2, colors)
BEGIN
ARC_P(grob_dest, x, Ymax-y, rayon, DegToRad(-angle2), DegToRad(-angle1), colors);
END;

Affichage(x, y, theta, v0)
BEGIN
  Blit_Pict(G1, 0, 239, G2);  // Décor de fond
  Blit_Pict(G1, x, y, G3);    // Ballon
  Blit_Pict(G1, 50, 140, G4); // Joueur
  Arc_Pict(G1, 10, 10, 15, 0, theta, {#000000h, #00AAFFh}); // Angle
  Rect_Pict(G1, 30, 10, 30+v0, 15, #000000, #00FF00); // Vitesse
  Rect_Vide(G1, 30, 10, 60, 15, #000000); // Cadre vitesse
  Blit_Pict(G0, 0, 239, G1); // composition image final à afficher
END;


// ******************** //
// -------------------- //
VIEW "NBA JAM", START()
BEGIN
// Initialisation des limites graphiques
Xmin := 0;
Xmax := 319;
Ymin := 0;
Ymax := 239;
 
  // Boucle Principale
WHILE 1 DO
  LOCAL x, y, ysol, v0, dt, adr;
  LOCAL theta, g;
  LOCAL vx, vy;
  LOCAL key, key2;

  // Initialisation des variables
  x := 63; // x ballon
  y := 147; // y ballon
  ysol := 64; // hauteur du sol
  v0 := 19; // vitesse de lancé   
  theta := 45; // angle de lancé
  g := 9.81/7; // coeff de gravité
  dt := 0.1; // incrément temporel


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

  // initialisation taille grob
  DIMGROB_P(G1, 320, 240, #000000);

  // Attente du choix de l'angle et vitesse flèche directionelles
  // [◄ 7] , [► 8], [▲ 2], [▼ 12]
  // Lancé avec [Enter 30]
  REPEAT
   Affichage(x, y, theta, v0);
   
   // [◄ 7]
   IF (ISKEYDOWN(7) AND v0 > 1) THEN
     v0 := v0-1;
     WAIT(0.1);
   END;
   // [► 8]
   IF (ISKEYDOWN(8) AND v0 < 30) THEN
     v0 := v0+1;
     WAIT(0.1);
   END;
   //[▲ 2]
   IF (ISKEYDOWN(2) AND theta < 89) THEN
     theta := theta+1;
     WAIT(0.1);
   END; 
   // [▼ 12]
   IF (ISKEYDOWN(12) AND theta > 4) THEN
     theta := theta-1;
     WAIT(0.1);
   END;
  UNTIL ISKEYDOWN(30);

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

  // Animation de la balle et test de colission
  REPEAT
   // Affichage des images
   Affichage(x, y, theta, v0);
   
   // 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.9; // Perte d'énergie
     vx := vx * 0.9;
   END;

   // Rebond mur gauche ou droit
   IF x < 0 AND vx < 0 OR x > 319-15 AND vx > 0 THEN
     vx := -vx; // Inversion de vitesse
   END;
   IF ISKEYDOWN(4) THEN
    BREAK;
   END;
   WAIT(0.001);
  UNTIL y < ysol AND ABS(vy) < 1.8;

  WAIT();
END;
END;


fond_basket.png
Image

ballon_basket.png
Image

player.png
Image