Processing pool game bug

Hello guys, I need help for a processing project.
Here my code:
When i shoot with tail the ball do not go straight and make a curve. I want to stop the ball

Thanks !

//VARIABLES
float y = 0;
float w = 150;
float h = 40;
float x = width - 100;

float hauteur;
float largeur;


boolean view = false;
boolean clicked = false;

boolean return_to_menu_boolean = false;

float ballSize = 25;
float ballSpeed = 5;

//BALL SETTINGS
PVector ball;

//Holl settings
PVector trou1;
PVector trou2;
PVector trou3;
PVector trou4;
PVector trou5;
PVector trou6;
int holeSize = 15;

//Settings balls
PVector vell;
boolean shot_line;
float powerShoot;

//Table settings 
float xt;
float yt;

//cursor settings
int xBox = 10;
int yBox = 200;

int yCursor = yBox / 1 + yBox - 5;

//variables options panel
boolean show_options_panel = false;

String ActualLanguage = "Français";

boolean click = false;

boolean show_language_options_dropdown = false;

int maxSpeedX = 25;
int maxSpeedY = 25;

double CoeffFrictionX;
double CoeffFrictionY;

void setup(){
 
 fullScreen();

 //PAGE
 background(255);
 stroke(0);
 noFill();
 
 hauteur = height;
 largeur = width;
 
 xt = largeur * 5 / 7;
 yt = hauteur * 5 / 7;
 
 reset();
 smooth();
}

void draw(){
  
  if(return_to_menu_boolean == false){
  menu();
  table();
  }else{
    return_to_menu();
  }
  ball_system();
  if(shot_line == true){
  }else{
   if(vell.x == 0 && vell.y == 0){
     println("Ball stop");
     shot_line = true; 
 }
   stoping_ball(); 
  }
  
  if(show_options_panel == true){
   show_options();
   shot_line = false;
  }
  
  if(show_language_options_dropdown == true){
    show_language_options();
  }
  
  fill(0);
  text("Vell x:" + vell.x, 500, 850);
  text("Vell y:" + vell.y, 650, 850);
  
 
}

void table(){
  fill(79, 134, 58);
  //tapis vert
  rect(largeur / 2 - xt /2, hauteur / 2 - yt / 2, xt, yt, 30);
  //bordure du tap
  noFill();
  stroke(135, 135, 135  );
  strokeWeight(15);
  rect(largeur / 2 - xt /2, hauteur / 2 - yt / 2, xt, yt, 30);
  
  //TROUS DU TAPIS
  strokeWeight(15);
  fill(0);
  //trous du milieu
  ellipse(largeur / 2, hauteur / 7 , 50, 50);
  ellipse(largeur / 2, hauteur * 6 / 7, 50, 50);
  //trous Ă  gauche
  ellipse(largeur / 7 + 8, hauteur / 7 + 10 * 2, 50, 50);
  ellipse(largeur  / 7 + 8, hauteur * 6 / 7 - 10 * 2, 50, 50);
  //trous Ă  droite
  ellipse(largeur * 6 / 7 - 8, hauteur / 7 + 10 * 2, 50, 50);
  fill(255);
  ellipse(largeur * 6 / 7 - 8, hauteur * 6 / 7 - 10 * 2  , 50, 50);
  //ligne du milieu du tapis
  strokeWeight(3);
  stroke(255);
  line(largeur / 2 + 290, height / 2 - 315, largeur / 2 + 290, height / 2 + 315);
  //arc du cercle du milieu du tapis
  fill(79, 134, 58);
  arc(largeur / 2 + 292, height / 2, 450, 450, -1.57, PI - 1.57);
  //point au centre
  fill(255);
  ellipse(largeur / 2 + 312, height / 2, 5, 5);
  
  //arc de cercle haut Ă  droite
  fill(79, 134, 58);
  stroke(79, 134, 58);
  arc(largeur * 6 / 7 - 8, hauteur / 7 + 4 * 2, 90, 98, 1.55, PI);
  fill(0);
  stroke(0);
  ellipse(largeur * 6 / 7 - 8, hauteur / 7 + 10 * 2, 35,35);
  
  //arc de cercle milieu en haut
  fill(79, 134, 58);
  stroke(79, 134, 58);
  arc(largeur / 2, hauteur / 7 + 4 * 2, 90, 98, 0, PI);
  fill(0);
  stroke(0);
  ellipse(largeur / 2, hauteur / 7 , 35,35);
  
  //arc de cercle milieu en haut
  fill(79, 134, 58);
  stroke(79, 134, 58);
  arc(largeur / 2, hauteur * 6 / 7  - 8, 90, 98, -3.14, 0.01);
  fill(0);
  stroke(0);
  ellipse(largeur / 2, hauteur * 6 / 7 , 35,35);
  
  //arc de cercle bas Ă  droite
  fill(79, 134, 58);
  stroke(79, 134, 58);
  arc(largeur * 6 / 7 - 8, hauteur * 6 / 7 - 10 * 2 + 10, 90, 98, 3.092, 4.7099977);
  fill(0);
  stroke(0);
  ellipse(largeur * 6 / 7 - 8, hauteur * 6 / 7 - 10 * 2, 35,35);
  
  //arc de cercle haut Ă  gauche
  fill(79, 134, 58);
  stroke(79, 134, 58);
  arc(largeur / 7 + 8, hauteur / 7 + 8, 90, 98, 0, PI / 2);
  fill(0);
  stroke(0);
  ellipse(largeur / 7 + 8, hauteur / 7 + 20, 35,35);
  
  //arc de cercle bas Ă  gauche
  fill(79, 134, 58);
  stroke(79, 134, 58);
  arc(largeur / 7 + 7, hauteur * 6 / 7 - 4 * 2, 90, 98, -1.55, 0);
  fill(0);
  stroke(0);
  ellipse(largeur / 7 + 7, hauteur * 6 / 7 - 10 * 2, 35,35);
}

void menu(){
 background(206, 220, 173);
 noStroke();
 fill(79, 134, 58);
 rect(x,y,w,h);
 textSize(15);
 fill(255);
 text("Menu", 45, 25);
 fill(255);
 if(mousePressed && clicked == false){
   clicked = true;
  if(mouseX>x && mouseX <x+w && mouseY>y && mouseY <y+h){
   view = !view;
   //click sur le bouton menu
   shot_line = false;
   println("Menu");
   delay(200);
  }
  if(view){//detection si le menu est déroulé
  if(mouseX>x && mouseX <x+w && mouseY>y+40 && mouseY <y+h+40){
    show_options_panel = true;
    println("Options");
    delay(200);
  }
  
  if(mouseX>x && mouseX <x+w && mouseY>y+80 && mouseY <y+h+80){
    return_to_menu_boolean = true;
    println("Retour");
    delay(200);
  }
  }
  
  if(mouseX > (width / 4) * 3 - 20 && mouseX < (width / 4) * 3 + 20 && mouseY > height / 4 && mouseY < height / 4 + 20){
    show_options_panel = false;
    show_language_options_dropdown = false;
   }else if(mouseX > width / 4 + 300 && mouseX < width / 4 + 350 && mouseY < height / 4 + 75 && mouseY > height / 4 + 50){
     if(click == false){
     click = true;
     show_language_options_dropdown = !show_language_options_dropdown;
     click = false;
     delay(100);
     }
   }else if(mouseX > width / 4 + 50 && mouseX < width / 4 + 350 && mouseY < height / 4 + 105 && mouseY > height / 4 + 80 && show_language_options_dropdown == true){//options
     if(ActualLanguage == "Français"){
     ActualLanguage = "English";
     }else{
       ActualLanguage = "Français";
     }
     show_language_options_dropdown = false;
   }else if(mouseX > width / 4 + 450 && mouseX < width / 4 + 600 && mouseY > height / 4 + 400 && mouseY < height / 4 + 425){//sauvegarder
     show_options_panel = false;
     show_language_options_dropdown = false;
     //ecriture fichier csv
   }else if(mouseX > width / 4 + 625 && mouseX < width / 4 + 775 && mouseY > height / 4 + 400 && mouseY < height / 4 + 425){//annuler
   println("Annuler");
     show_options_panel = false;
     show_language_options_dropdown = false;
   }

  clicked = false;
 }
 
 if(view){//affiche dropdown du menu
   fill(79, 134, 58);
   rect(x,y+ 40,w,h);
   fill(255);
   text("Options", 45, 25+40);
   
   fill(79, 134, 58);
   rect(x,y+ 80,w,h);
   fill(255);
   text("Retour", 45, 25+80);
 }
}

void return_to_menu(){
 
}

void placing_ball(){
}

 
void reset() {
  ball =  new PVector(largeur / 2 + 312, height / 2, 0);
  trou1 = new PVector(largeur / 2, hauteur / 7,  0);
  trou2 = new PVector(largeur / 2, hauteur * 6 / 7,  0);
  trou3 = new PVector(largeur / 7 + 8, hauteur / 7 + 10 * 2,  0);
  trou4 = new PVector(largeur  / 7 + 8, hauteur * 6 / 7 - 10 * 2,  0);
  trou5 = new PVector(largeur * 6 / 7 - 8, hauteur / 7 + 10 * 2,  0);
  trou6 = new PVector(largeur * 6 / 7 - 8, hauteur * 6 / 7 - 10 * 2,  0);
  vell = new PVector( 0, 0, 0);
  shot_line = true;
}

void ball_system(){
  ball.x+=vell.x;
  ball.y+=vell.y;
  if(shot_line){
    stroke(255, 255, 0);
    text("Mouse X:" + mouseX, 500, 100);
    text("Mouse Y:" + mouseY, 750, 100);
    line(mouseX, mouseY, ball.x, ball.y);
  }
  stroke(0, 64, 0);
  fill(0);
  stroke(0);
  fill(255);
  ellipse(ball.x, ball.y, 20, 20);
  if (dist(ball.x, ball.y, trou1.x, trou1.y)<holeSize) {
    println("POINT!");
    reset();
  }else if(dist(ball.x, ball.y, trou2.x, trou2.y)<holeSize){
   println("POINT!");
    reset(); 
  }else if(dist(ball.x, ball.y, trou3.x, trou3.y)<holeSize){
   println("POINT!");
    reset(); 
  }else if(dist(ball.x, ball.y, trou4.x, trou4.y)<holeSize){
   println("POINT!");
    reset(); 
  }else if(dist(ball.x, ball.y, trou5.x, trou5.y)<holeSize){
   println("POINT!");
    reset(); 
  }else if(dist(ball.x, ball.y, trou6.x, trou6.y)<holeSize){
   println("POINT!");
    reset(); 
  }else if (ball.x<250||ball.x>1355) {
    vell.x *= -1;
  }else if(ball.y<145||ball.y>755){
    vell.y *= -1;
  }
}

void mousePressed() {
  if(shot_line == true){
  shot_line = false;
  vell = new PVector(0.1 * (ball.x-mouseX), 0.1 * (ball.y-mouseY), 0);
  
  if(vell.x > maxSpeedX){
    vell.x = maxSpeedX;
  }
  
  if(vell.y > maxSpeedY){
    vell.y = maxSpeedY;
  }
  
  if(vell.x < -maxSpeedX){
    vell.x = -maxSpeedX;
  }
  
  if(vell.y < -maxSpeedY){
    vell.y = -maxSpeedY;
  }
  
  }
}


void stoping_ball(){
  
 if(vell.x > -0.1 && vell.x < 0.1){
   vell.x = 0;
 }
 
 if(vell.y > -0.1 && vell.y < 0.1){
      vell.y = 0;
 }
  
  if(vell.x > 0 && vell.x != 0){
    CoeffFrictionX = 0.1D;
    vell.x -= CoeffFrictionX;
    println("Vell x " + vell.x);
  }else if(vell.x < 0 && vell.x != 0){
    CoeffFrictionX = -0.1D;
    println("Vell x " + vell.x);
    vell.x -= CoeffFrictionX;
  }
  
  if(vell.y > 0 && vell.y != 0){
    CoeffFrictionY = 0.1D;
    println("Vell y " + vell.y);
     vell.y -= CoeffFrictionY;
  }else if(vell.y < 0 && vell.y != 0){
    CoeffFrictionY = -0.1D;
    println("Vell y " + vell.y);
     vell.y -= CoeffFrictionY;
  }
}

void show_options(){
   //fond de la page options et carrée pour fermer
   textSize(20);
   fill(255);
   rect(width / 4, height / 4, width / 2, height / 2); 
   fill(255,0,0);
   rect(width / 4 * 3 - 20 , height / 4, 20, 20);
   fill(0);
   text("X", width / 4 * 3 - 15 , height / 4 + 17); 
   
   //langue
   fill(155);
   rect(width / 4 + 50, height / 4 + 50,  300, 30);
   fill(0);
   text(ActualLanguage, width / 4 + 50, height / 4 + 55,  300, 30);
   stroke(0);
   fill(155);
   rect(width / 4 + 300, height / 4 + 50,  50, 30);
   fill(0);
   text("â–Ľ", width / 4 + 315, height / 4 + 75);
   fill(155);
   rect(width / 4 + 450, height / 4 + 400,  150, 30);
   fill(0);
   text("Sauvegarder", width / 4 + 465, height / 4 + 405,  150, 30);
   fill(155);
   rect(width / 4 + 625, height / 4 + 400,  150, 30);
   fill(0);
   text("Annuler", width / 4 + 660, height / 4 + 405,  150, 30);
}

void show_language_options(){
    fill(155);
    rect(width / 4 + 50, height / 4 + 80,  300, 30);
    fill(0);
    if(ActualLanguage == "Français"){
    text("English", width / 4 + 50, height / 4 + 105);
    }else{
      text("Français", width / 4 + 50, height / 4 + 105);
    }
}

Here my code to stop the ball. But he don’t work

if(vell.x > 0 && vell.x != 0){
    CoeffFrictionX = 0.1D;
    vell.x -= CoeffFrictionX;
    println("Vell x " + vell.x);
  }else if(vell.x < 0 && vell.x != 0){
    CoeffFrictionX = -0.1D;
    println("Vell x " + vell.x);
    vell.x -= CoeffFrictionX;
  }
  
  if(vell.y > 0 && vell.y != 0){
    CoeffFrictionY = 0.1D;
    println("Vell y " + vell.y);
     vell.y -= CoeffFrictionY;
  }else if(vell.y < 0 && vell.y != 0){
    CoeffFrictionY = -0.1D;
    println("Vell y " + vell.y);
     vell.y -= CoeffFrictionY;
  }
1 Like

wow, i like that.
-a- but the corner holes position is not symmetric
-b- much more work on the border / bounce needed.

your ball stop
just a idea:

double CoeffFriction=0.98D;

void stoping_ball() {
  if (vell.x > -0.1 && vell.x < 0.1) vell.x = 0;
  else vell.x *= CoeffFriction;
  if (vell.y > -0.1 && vell.y < 0.1) vell.y = 0;
  else vell.y *= CoeffFriction;
}

1 Like

Really thanks for your answer. Yes i know for my border. The game is not finish.
When he was finish i post the code :slight_smile:

1 Like

Code update ! Any help to create collision ?

//VARIABLES
float y = 0;
float w = 150;
float h = 40;
float x = width - 100;

float hauteur;
float largeur;


boolean view = false;
boolean clicked = false;

boolean return_to_menu_boolean = false;

float ballSize = 25;
float ballSpeed = 5;

//BALL SETTINGS
PVector ball;
PVector bball;

PVector[] RedBall = new PVector[7];
PVector[] YellowBall = new PVector[7];

PVector[] vellRedBall = new PVector[7];
PVector[] vellYellowBall = new PVector[7];

//Holl settings
PVector trou1;
PVector trou2;
PVector trou3;
PVector trou4;
PVector trou5;
PVector trou6;
int holeSize = 15;

//Settings balls
PVector vell;
PVector bvell;
boolean shot_line;
float powerShoot;

//Table settings 
float xt;
float yt;

//variables options panel
boolean show_options_panel = false;

String ActualLanguage = "Français";

boolean click = false;

boolean show_language_options_dropdown = false;

double CoeffFriction=0.98D;

float xBorderMax;
float xBorderMin;
float yBorderMax;
float yBorderMin;

boolean cheat = false;

void setup(){
 
 fullScreen();

 //PAGE
 background(255);
 stroke(0);
 noFill();
 
 hauteur = height;
 largeur = width;
 
 xt = largeur * 5 / 7;
 yt = hauteur * 5 / 7;
 
 xBorderMin = int(largeur / 2 - xt /2 + 15);
 xBorderMax = int(largeur / 2 - xt /2 + xt - 15);
 yBorderMin = int(hauteur / 2 - yt / 2 + 15);
 yBorderMax = int(hauteur / 2 - yt / 2 + yt - 15);
 
 reset();
 smooth();
 
 placing_ball();
 first_placing_ball();
}

void draw(){
  
  if(return_to_menu_boolean == false){
  menu();
  table();
  }else{
    return_to_menu();
  }
  ball_system();
  if(shot_line == true){
  }else{
   if(vell.x == 0 && vell.y == 0){
     println("Ball stop");
     shot_line = true; 
    }
   stoping_ball(); 
  }
  
  if(show_options_panel == true){
   show_options();
   shot_line = false;
  }
  
  if(show_language_options_dropdown == true){
    show_language_options();
  }
  
  fill(0);
  text("Vell x:" + vell.x, 500, 850);
  text("Vell y:" + vell.y, 650, 850);
   if(cheat){
        ball.x = mouseX;
        ball.y = mouseY;
      } 
      
      println(xBorderMin, xBorderMax);
 
}

void table(){
  fill(79, 134, 58);
  //tapis vert
  rect(largeur / 2 - xt /2, hauteur / 2 - yt / 2, xt, yt, 30);
  //bordure du tap
  noFill();
  stroke(135, 135, 135  );
  strokeWeight(15);
  rect(largeur / 2 - xt /2, hauteur / 2 - yt / 2, xt, yt, 30);
  
  //TROUS DU TAPIS
  strokeWeight(15);
  fill(0);
  //trous du milieu
  ellipse(largeur / 2, hauteur / 7 , 50, 50);
  ellipse(largeur / 2, hauteur * 6 / 7, 50, 50);
  //trous Ă  gauche
  ellipse(largeur / 7 + 8, hauteur / 7 + 10 * 2, 50, 50);
  ellipse(largeur  / 7 + 8, hauteur * 6 / 7 - 10 * 2, 50, 50);
  //trous Ă  droite
  ellipse(largeur * 6 / 7 - 8, hauteur / 7 + 10 * 2, 50, 50);
  fill(255);
  ellipse(largeur * 6 / 7 - 8, hauteur * 6 / 7 - 10 * 2  , 50, 50);
  //ligne du milieu du tapis
  strokeWeight(3);
  stroke(255);
  line(largeur / 2 + 290, height / 2 - 315, largeur / 2 + 290, height / 2 + 315);
  //arc du cercle du milieu du tapis
  fill(79, 134, 58);
  arc(largeur / 2 + 292, height / 2, 450, 450, -1.57, PI - 1.57);
  //point au centre
  fill(255);
  ellipse(largeur / 2 + 312, height / 2, 5, 5);
  
  //arc de cercle haut Ă  droite
  fill(79, 134, 58);
  stroke(79, 134, 58);
  arc(largeur * 6 / 7 - 8, hauteur / 7 + 4 * 2, 90, 98, 1.55, PI);
  fill(0);
  stroke(0);
  ellipse(largeur * 6 / 7 - 8, hauteur / 7 + 10 * 2, 35,35);
  
  //arc de cercle milieu en haut
  fill(79, 134, 58);
  stroke(79, 134, 58);
  arc(largeur / 2, hauteur / 7 + 4 * 2, 90, 98, 0, PI);
  fill(0);
  stroke(0);
  ellipse(largeur / 2, hauteur / 7 , 35,35);
  
  //arc de cercle milieu en haut
  fill(79, 134, 58);
  stroke(79, 134, 58);
  arc(largeur / 2, hauteur * 6 / 7  - 8, 90, 98, -3.14, 0.01);
  fill(0);
  stroke(0);
  ellipse(largeur / 2, hauteur * 6 / 7 , 35,35);
  
  //arc de cercle bas Ă  droite
  fill(79, 134, 58);
  stroke(79, 134, 58);
  arc(largeur * 6 / 7 - 8, hauteur * 6 / 7 - 10 * 2 + 10, 90, 98, 3.092, 4.7099977);
  fill(0);
  stroke(0);
  ellipse(largeur * 6 / 7 - 8, hauteur * 6 / 7 - 10 * 2, 35,35);
  
  //arc de cercle haut Ă  gauche
  fill(79, 134, 58);
  stroke(79, 134, 58);
  arc(largeur / 7 + 8, hauteur / 7 + 8, 90, 98, 0, PI / 2);
  fill(0);
  stroke(0);
  ellipse(largeur / 7 + 8, hauteur / 7 + 20, 35,35);
  
  //arc de cercle bas Ă  gauche
  fill(79, 134, 58);
  stroke(79, 134, 58);
  arc(largeur / 7 + 7, hauteur * 6 / 7 - 4 * 2, 90, 98, -1.55, 0);
  fill(0);
  stroke(0);
  ellipse(largeur / 7 + 7, hauteur * 6 / 7 - 10 * 2, 35,35);
  
}

void menu(){
 background(206, 220, 173);
 noStroke();
 fill(79, 134, 58);
 rect(x,y,w,h);
 textSize(15);
 fill(255);
 text("Menu", 45, 25);
 fill(255);
 if(mousePressed && clicked == false){
   clicked = true;
  if(mouseX>x && mouseX <x+w && mouseY>y && mouseY <y+h){
   view = !view;
   //click sur le bouton menu
   shot_line = false;
   println("Menu");
   delay(200);
  }
  if(view){//detection si le menu est déroulé
  if(mouseX>x && mouseX <x+w && mouseY>y+40 && mouseY <y+h+40){
    show_options_panel = true;
    println("Options");
    delay(200);
  }
  
  if(mouseX>x && mouseX <x+w && mouseY>y+80 && mouseY <y+h+80){
    return_to_menu_boolean = true;
    println("Retour");
    delay(200);
  }
  }
  
  if(mouseX > (width / 4) * 3 - 20 && mouseX < (width / 4) * 3 + 20 && mouseY > height / 4 && mouseY < height / 4 + 20){
    show_options_panel = false;
    show_language_options_dropdown = false;
   }else if(mouseX > width / 4 + 300 && mouseX < width / 4 + 350 && mouseY < height / 4 + 75 && mouseY > height / 4 + 50){
     if(click == false){
     click = true;
     show_language_options_dropdown = !show_language_options_dropdown;
     click = false;
     delay(100);
     }
   }else if(mouseX > width / 4 + 50 && mouseX < width / 4 + 350 && mouseY < height / 4 + 105 && mouseY > height / 4 + 80 && show_language_options_dropdown == true){//options
     if(ActualLanguage == "Français"){
     ActualLanguage = "English";
     }else{
       ActualLanguage = "Français";
     }
     show_language_options_dropdown = false;
   }else if(mouseX > width / 4 + 450 && mouseX < width / 4 + 600 && mouseY > height / 4 + 400 && mouseY < height / 4 + 425){//sauvegarder
     show_options_panel = false;
     show_language_options_dropdown = false;
     //ecriture fichier csv
   }else if(mouseX > width / 4 + 625 && mouseX < width / 4 + 775 && mouseY > height / 4 + 400 && mouseY < height / 4 + 425){//annuler
   println("Annuler");
     show_options_panel = false;
     show_language_options_dropdown = false;
   }

  clicked = false;
 }
 
 if(view){//affiche dropdown du menu
   fill(79, 134, 58);
   rect(x,y+ 40,w,h);
   fill(255);
   text("Options", 45, 25+40);
   
   fill(79, 134, 58);
   rect(x,y+ 80,w,h);
   fill(255);
   text("Retour", 45, 25+80);
 }
}

void return_to_menu(){
 
}

void first_placing_ball(){
  
  for (int i = 0; i < RedBall.length; i++) {
    RedBall[i] = new PVector();
  } 
  
  RedBall[0] = new PVector(largeur / 2 - 410, height / 2 + 60, 0);
  RedBall[1] = new PVector(largeur / 2 - 332, height / 2 - 15, 0);
  RedBall[2] = new PVector(largeur / 2 - 355, height / 2 + 30, 0);
  RedBall[3] = new PVector(largeur / 2 - 410, height / 2 - 30, 0);
  RedBall[4] = new PVector(largeur / 2 - 380, height / 2 + 15, 0);
  RedBall[5] = new PVector(largeur / 2 - 380, height / 2 - 45, 0);
  RedBall[6] = new PVector(largeur / 2 - 410, height / 2);
  
  YellowBall[0] = new PVector(largeur / 2 - 332, height / 2 +15, 0);
  YellowBall[1] = new PVector(largeur / 2 - 410, height / 2 + 30);
  YellowBall[2] = new PVector(largeur / 2 - 308, height / 2, 0);
  YellowBall[3] = new PVector(largeur / 2 - 380, height / 2 + 45, 0);
  YellowBall[4] = new PVector(largeur / 2 - 380, height / 2 - 15, 0);
  YellowBall[5] = new PVector(largeur / 2 - 355, height / 2 - 30, 0);
  YellowBall[6] = new PVector(largeur / 2 - 410, height / 2 - 60, 0);
  
  vellRedBall[0] = new PVector(0, 0);
  vellRedBall[1] = new PVector(0, 0);
  vellRedBall[2] = new PVector(0, 0);
  vellRedBall[3] = new PVector(0, 0);
  vellRedBall[4] = new PVector(0, 0);
  vellRedBall[5] = new PVector(0, 0);
  vellRedBall[6] = new PVector(0, 0);
  
  vellYellowBall[0] = new PVector(0, 0);
  vellYellowBall[1] = new PVector(0, 0);
  vellYellowBall[2] = new PVector(0, 0);
  vellYellowBall[3] = new PVector(0, 0);
  vellYellowBall[4] = new PVector(0, 0);
  vellYellowBall[5] = new PVector(0, 0);
  vellYellowBall[6] = new PVector(0, 0);
  
}

void placing_ball(){
  bball = new PVector(largeur / 2 - 355, height / 2, 0);
}

 
void reset() {
  trou1 = new PVector(largeur / 2, hauteur / 7,  0);
  trou2 = new PVector(largeur / 2, hauteur * 6 / 7,  0);
  trou3 = new PVector(largeur / 7 + 8, hauteur / 7 + 10 * 2,  0);
  trou4 = new PVector(largeur  / 7 + 8, hauteur * 6 / 7 - 10 * 2,  0);
  trou5 = new PVector(largeur * 6 / 7 - 8, hauteur / 7 + 10 * 2,  0);
  trou6 = new PVector(largeur * 6 / 7 - 8, hauteur * 6 / 7 - 10 * 2,  0);
  ball =  new PVector(largeur / 2 + 312, height / 2, 0);
  vell = new PVector( 0, 0, 0);
  bvell = new PVector( 0, 0, 0);
  shot_line = true;
  
}

void ball_system(){
  ball.x+=vell.x;
  ball.y+=vell.y;
  
  bball.x+=bvell.x;
  bball.y+=bvell.y;
  
  if(shot_line){
    stroke(255, 255, 0);
    text("Mouse X:" + mouseX, 500, 100);
    text("Mouse Y:" + mouseY, 750, 100);
    line(mouseX, mouseY, ball.x, ball.y);
  }
  stroke(0, 64, 0);
  fill(0);
  stroke(0);
  fill(255);
  ellipse(ball.x, ball.y, ballSize, ballSize); //boule blanche
  fill(0);
  ellipse(bball.x, bball.y, ballSize, ballSize); //boule noire
  
  //boules rouges
  noStroke();
  fill(255, 0, 0);
  for(int i = 0; i < RedBall.length; i++){
   RedBall[i].x += vellRedBall[i].x;
   RedBall[i].y += vellRedBall[i].y;
   ellipse(RedBall[i].x, RedBall[i].y, ballSize, ballSize); 
  }
  
  //boules jaunes
  fill(255, 255, 0);
  for(int i = 0; i < RedBall.length; i++){
   YellowBall[i].x += vellYellowBall[i].x;
   YellowBall[i].y += vellYellowBall[i].y;
   ellipse(YellowBall[i].x, YellowBall[i].y, ballSize, ballSize); 
  }
  
  stroke(0, 64, 0);
  if (dist(ball.x, ball.y, trou1.x, trou1.y)<holeSize) {//white ball
    println("POINT!");
    reset();
  }else if(dist(ball.x, ball.y, trou2.x, trou2.y)<holeSize){
   println("POINT!");
    reset(); 
  }else if(dist(ball.x, ball.y, trou3.x, trou3.y)<holeSize){
   println("POINT!");
    reset(); 
  }else if(dist(ball.x, ball.y, trou4.x, trou4.y)<holeSize){
   println("POINT!");
    reset(); 
  }else if(dist(ball.x, ball.y, trou5.x, trou5.y)<holeSize){
   println("POINT!");
    reset(); 
  }else if(dist(ball.x, ball.y, trou6.x, trou6.y)<holeSize){
   println("POINT!");
    reset(); 
  }else if (ball.x<xBorderMin||ball.x>xBorderMax) {
    vell.x *= -1;
  }else if(ball.y<yBorderMin||ball.y>yBorderMax){
    vell.y *= -1;
  }else if (bball.x<xBorderMin||bball.x>xBorderMax) {
    bvell.x *= -1;
  }else if(bball.y<yBorderMin||bball.y>yBorderMax){
   bvell.y *= -1;
  }
  
  for(int i = 0; i < RedBall.length; i++){
  if (RedBall[i].x<xBorderMin||RedBall[i].x>xBorderMax) {
    vellRedBall[i].x *= -1;
  }else if(RedBall[i].y<yBorderMin||RedBall[i].y>yBorderMax){
    vellRedBall[i].y *= -1;
  }
  
  if (YellowBall[i].x<xBorderMin||YellowBall[i].x>xBorderMax) {
    vellYellowBall[i].x *= -1;
  }else if(YellowBall[i].y<yBorderMin||YellowBall[i].y>yBorderMax){
    vellYellowBall[i].y *= -1;
  }
  }
  
  if (dist(bball.x, bball.y, trou1.x, trou1.y)<holeSize) {
    println("POINT!");
    end_game(1, 255, 600); 
  }else if(dist(bball.x, bball.y, trou2.x, trou2.y)<holeSize){
   println("POINT!");
    end_game(1, 255, 600); 
  }else if(dist(bball.x, bball.y, trou3.x, trou3.y)<holeSize){
   println("POINT!");
    end_game(1, 255, 600);  
  }else if(dist(bball.x, bball.y, trou4.x, trou4.y)<holeSize){
   println("POINT!");
    end_game(1, 255, 600);  
  }else if(dist(bball.x, bball.y, trou5.x, trou5.y)<holeSize){
   println("POINT!");
   end_game(1, 255, 600);  
  }else if(dist(bball.x, bball.y, trou6.x, trou6.y)<holeSize){
   println("POINT!");
    end_game(1, 255, 600); 
  }
  
  ball_detection();
}

void mousePressed() {
  if(shot_line == true){
  shot_line = false;
  vell = new PVector(0.1 * (ball.x-mouseX), 0.1 * (ball.y-mouseY), 0);
  }
}


void stoping_ball(){
  for(int i = 0; i < RedBall.length; i++){
   if (vellRedBall[i].x > -0.1 && vellRedBall[i].x < 0.1) vellRedBall[i].x = 0;
   else vellRedBall[i].x *= CoeffFriction;
   if (vellRedBall[i].y > -0.1 && vellRedBall[i].y < 0.1) vellRedBall[i].y = 0;
   else vellRedBall[i].y *= CoeffFriction;
   
   if (vellYellowBall[i].x > -0.1 && vellYellowBall[i].x < 0.1) vellYellowBall[i].x = 0;
   else vellYellowBall[i].x *= CoeffFriction;
   if (vellYellowBall[i].y > -0.1 && vellYellowBall[i].y < 0.1) vellYellowBall[i].y = 0;
   else vellYellowBall[i].y *= CoeffFriction;
  }
  
  
  if (vell.x > -0.1 && vell.x < 0.1) vell.x = 0;
  else vell.x *= CoeffFriction;
  if (vell.y > -0.1 && vell.y < 0.1) vell.y = 0;
  else vell.y *= CoeffFriction;
  
  if (bvell.x > -0.1 && bvell.x < 0.1) bvell.x = 0;
  else bvell.x *= CoeffFriction;
  if (bvell.y > -0.1 && bvell.y < 0.1) bvell.y = 0;
  else bvell.y *= CoeffFriction;
}

void show_options(){
   //fond de la page options et carrée pour fermer
   textSize(20);
   fill(255);
   rect(width / 4, height / 4, width / 2, height / 2); 
   fill(255,0,0);
   rect(width / 4 * 3 - 20 , height / 4, 20, 20);
   fill(0);
   text("X", width / 4 * 3 - 15 , height / 4 + 17); 
   
   //langue
   fill(155);
   rect(width / 4 + 50, height / 4 + 50,  300, 30);
   fill(0);
   text(ActualLanguage, width / 4 + 50, height / 4 + 55,  300, 30);
   stroke(0);
   fill(155);
   rect(width / 4 + 300, height / 4 + 50,  50, 30);
   fill(0);
   text("â–Ľ", width / 4 + 315, height / 4 + 75);
   fill(155);
   rect(width / 4 + 450, height / 4 + 400,  150, 30);
   fill(0);
   text("Sauvegarder", width / 4 + 465, height / 4 + 405,  150, 30);
   fill(155);
   rect(width / 4 + 625, height / 4 + 400,  150, 30);
   fill(0);
   text("Annuler", width / 4 + 660, height / 4 + 405,  150, 30);
}

void show_language_options(){
    fill(155);
    rect(width / 4 + 50, height / 4 + 80,  300, 30);
    fill(0);
    if(ActualLanguage == "Français"){
    text("English", width / 4 + 50, height / 4 + 105);
    }else{
      text("Français", width / 4 + 50, height / 4 + 105);
    }
}

void ball_detection(){
 for(int i = 0; i < RedBall.length; i++){
   for(int j = 0; j < YellowBall.length; j++){
   if(dist(RedBall[i].x, RedBall[i].y, YellowBall[j].x, YellowBall[j].y)< ballSize){
      calculate_collision(RedBall[i], YellowBall[j], vellRedBall[i], vellYellowBall[j]);
    }
    
    if(dist(ball.x, ball.y, YellowBall[j].x, YellowBall[j].y)< ballSize){
      calculate_collision(ball, YellowBall[j], vell, vellYellowBall[j]);
    }
    
    if(dist(bball.x, bball.y, YellowBall[j].x, YellowBall[j].y)< ballSize){
      calculate_collision(bball, YellowBall[j], bvell, vellYellowBall[j]);
    }
    
    if(dist(ball.x, ball.y, RedBall[j].x, RedBall[j].y)< ballSize){
      calculate_collision(ball, RedBall[j], vell, vellRedBall[j]);
    }
    
    if(dist(bball.x, bball.y, RedBall[j].x, RedBall[j].y)< ballSize){
      calculate_collision(bball, RedBall[j], bvell, vellRedBall[j]);
    }
    
    if(dist(ball.x, ball.y, bball.x, bball.y)< ballSize){
      calculate_collision(ball, bball, vell, bvell);
    }
   }
 }
}

void calculate_collision(PVector ball1, PVector ball2, PVector vellball1, PVector vellball2){
   float dx = ball2.x - ball1.x;
   float dy = ball2.y - ball1.y;
   float d = sqrt(sq(dx)+sq(dy)); // distance between balls
    if (d < ballSize + ballSize) {
        //The two balls are colliding.
        float mag1 = sqrt(sq(vellball1.x)+sq(vellball1.y));
        float mag2 = sqrt(sq(vellball2.x)+sq(vellball2.y));
        vellball2.x = (mag1*dx/d)*-1;
        vellball2.y = (mag1*dy/d)*-1;
        vellball1.x = -(mag2*dx/d)*-1 + vellball1.x/4;
        vellball1.y = -(mag2*dy/d)*-1 + vellball1.y/4;
        
        println("Vell modified ", vellball1.x, vellball1.y, vellball2.x, vellball2.y);
    }
}

void keyPressed() {
  if (key == CODED){
    if (keyCode == LEFT){
     cheat = !cheat;
    }  
    
    if (keyCode == RIGHT){
     end_game(2, 260, 400);
    } 
  }
}

void end_game(int player_number, int score_player1, int score_player2){
  shot_line = false;
  bvell.x = 0;
  bvell.y = 0;
  fill(155);
  rect(width / 2 - 250, height / 2 - 125, 500, 250);
  fill(0);
  text("Vous avez perdu(e) ! Joueur " + player_number + " à gagné(e) !\n \n Score :\n Joueur 1 :" + score_player1 + "\n Joueur 2 :" + score_player2, width / 2 - 150, height / 2 - 50);
  fill(157);
  rect(width / 2 - 250, height / 2 + 75, 250, 50);
  rect(width / 2, height / 2 + 75, 250, 50);
  fill(0);
  text("Rejouer", width / 2 - 150,  height / 2 + 100);
  text("Quitter", width / 2 + 100,  height / 2 + 100);
}

Just here need help that work not correctly

void calculate_collision(PVector ball1, PVector ball2, PVector vellball1, PVector vellball2){
   float dx = ball2.x - ball1.x;
   float dy = ball2.y - ball1.y;
   float d = sqrt(sq(dx)+sq(dy)); // distance between balls
    if (d < ballSize + ballSize) {
        //The two balls are colliding.
        float mag1 = sqrt(sq(vellball1.x)+sq(vellball1.y));
        float mag2 = sqrt(sq(vellball2.x)+sq(vellball2.y));
        vellball2.x = (mag1*dx/d)*-1;
        vellball2.y = (mag1*dy/d)*-1;
        vellball1.x = -(mag2*dx/d)*-1 + vellball1.x/4;
        vellball1.y = -(mag2*dy/d)*-1 + vellball1.y/4;
        
        println("Vell modified ", vellball1.x, vellball1.y, vellball2.x, vellball2.y);
    }
}

sorry, i only take a short look
-a- you use too may arrays what complicates the code,
pls make ONE array
[0] is the white ball
[1] … [7] red
[8] … [14] yellow
[15] black
you can store the color in the class or just make for the color a if else

you can also put the first position to an array
so the first_placing_ball() can be a one-line command

also might be good to make one array for the holes.


-b- what is confusing
in
ball_detection()
you calculate a distance between all balls
( loop over i and j ?? looks like check each collision twice? )
using dist()
then you call
calculate_collision()
and inside you calculate distance again??
but use d = sqrt(sq(dx)+sq(dy))

add one time compare with ballSize and one time with 2* ballSize

while you use PVector could use
https://processing.org/reference/PVector_dist_.html

for the mag calc
https://processing.org/reference/PVector_mag_.html

the rest defines a x y position for the 2 balls after collision,
that should be a new direction and speed, but not position???