Pong Trail Question

Hi, I am making a variation of pong, and I want to make the ball have a trail when I press my mouse. I conceptually know this means I need to stop my background from updating, but I am having difficulty in having this actually happen. I also am having trouble having my restart screen actually work. If you can help it would be greatly appreciated.

float gap;    //Assign variables
float ballX_pos = random(300);
float ballX = 30;
float ballY = 30;
float dx = 3;
float neg_dx = -3;
float dy = 3;
float neg_dy = -3;
float rcolor = random(255);
float gcolor = random(255);
float bcolor = random(255);
float disp = 0;
float number = random(3);
boolean right = number>1;
float paddleY  = height+240;
int score;

void setup(){ //Setup the window
  size(640,360);
  textSize(30);
}

void draw(){ //This is gpoing to serve as the games loop
  frameRate(60);
  float paddleX = mouseX;
  rcolor = random(255);
  gcolor = random(255);
  bcolor = random(255);
  
  rectMode(CENTER); //Paddle 
  background(50);
  fill(255);
  rect(paddleX,paddleY-20,100,20);
  
  fill(rcolor,gcolor,bcolor); 
  rcolor+=1;
  rcolor= constrain(rcolor,bcolor,gcolor); //Makes the coloring random
 
  if(ballX >width) { //Statements that keep the ball within the screen.
    dx = -dx; 
  }


  if (ballX <0){
    dx =-dx;
    neg_dx = dx;
  }

  if(ballY <0){
    dy = -dy;
    neg_dy  =dy;
  }

  if((ballY >= paddleY-10 ) && (ballX >= paddleX-50) && (ballX <= paddleX + 50)){
    dy = - abs(dy+1); //When the paddle hits the ball it bounces back
    score++;
  }

  if(right){
    circle(ballX,ballY,20); //Position of the ball
    ballX= ballX+dx; //Right 
    ballX++;
    ballY=ballY+dy;
    ballY++;
  } 
  else {
    circle(ballX,ballY,20); //Position of the ball
    ballX= ballX-dx; //Left 
    ballX++;
    ballY=ballY+dy;
    ballY++;
  }
   
  //Rainbow score is cooler
  text(score, 580 ,50);

  if(ballY>height){
    background(255);
    fill(0);
    text("GAME OVER",230,height/2);
    text("Press Any Key to Restart",145,280);
  }  
}
1 Like

I added some quick and dirty arrays and for loops to get your trails working. I also added code for the reset. See my comments that start with // NEW:, for areas where I added my own code in between yours:

float gap; //Assign variables
float ballX_pos = random(300);
float ballX = 30;
float ballY = 30;
float dx = 3;
float neg_dx = -3;
float dy = 3;
float neg_dy = -3;
float rcolor = random(255);
float gcolor = random(255);
float bcolor = random(255);
float disp = 0;
float number = random(3);
boolean right = number>1;
float paddleY = height+240;
int score;

// NEW: arrays for ball trail
int arrayLen = 20;
float[] arrBallX = new float[arrayLen];
float[] arrBallY = new float[arrayLen];
{
  for (int i = 0; i < arrBallX.length; i++) {
    arrBallX[i] = ballX;
    arrBallY[i] = ballY;
  }
}

void setup() { //Setup the window
  size(640, 360);
  textSize(30);
}

void draw() { //This is gpoing to serve as the games loop
  frameRate(60);
  float paddleX = mouseX;
  rcolor = random(255);
  gcolor = random(255);
  bcolor = random(255);

  rectMode(CENTER); //Paddle
  background(50);
  fill(255);
  rect(paddleX, paddleY-20, 100, 20);

  fill(rcolor, gcolor, bcolor);
  rcolor+=1;
  rcolor= constrain(rcolor, bcolor, gcolor); //Makes the coloring random

  if (ballX >width) { //Statements that keep the ball within the screen.
    dx = -dx;
  }

  if (ballX <0) {
    dx =-dx;
    neg_dx = dx;
  }

  if (ballY <0) {
    dy = -dy;
    neg_dy =dy;
  }

  if ((ballY >= paddleY-10 ) && (ballX >= paddleX-50) && (ballX <= paddleX + 50)) {
    dy = - abs(dy+1); //When the paddle hits the ball it bounces back
    score++;
    ;
  }

  // NEW: store previous ball coords in their respective arrays
  for (int i = arrBallX.length - 1; i > 0; i--) {
    arrBallX[i] = arrBallX[i - 1];
    arrBallY[i] = arrBallY[i - 1];
  }
  
  arrBallX[0] = ballX;
  arrBallY[0] = ballY;
  
  // NEW: if mouse pressed, draw array of balls
  if (mousePressed) {
    for (int i = arrBallX.length - 1; i >= 0; i--) {
      circle(arrBallX[i], arrBallY[i], 20);
    }
  }

  if (right) {
    circle(ballX, ballY, 20); //Position of the ball
    ballX= ballX+dx; //Right
    ballX++;
    ballY=ballY+dy;
    ballY++;
  } else {
    circle(ballX, ballY, 20); //Position of the ball
    ballX= ballX-dx; //Left
    ballX++;
    ballY=ballY+dy;
    ballY++;
  }
    
  //Rainbow score is cooler
  text(score, 580, 50);

  if (ballY>height) {
    background(255);
    fill(0);
    text("GAME OVER", 230, height/2);
    text("Press Any Key to Restart", 145, 280);

    // NEW: reset. Might want to move these initializing assignments to a function
    if (keyPressed && !mousePressed) {
      number = random(3);
      right = number>1;
      ballX = 30;
      ballY = 30;
      score = 0;
      dx = 3;
      neg_dx = -3;
      dy = 3;
      neg_dy = -3;
      setup();
    }
  }
}
2 Likes

Very helpful. Thank you

There are a couple places where I’m repeating myself in the code and could be more efficient, but you probably you get the idea. I’m a Java noob, so I’m sure there are shorter ways to achieve this stuff too. And you can obviously add more variable resets to the reset block–I only reset a handful of things.

is there a way to have the background simply not refresh once the mouse is pressed. I know it would make the circle have a trail and the rectangle. (The trail would not go away until the mouse is released).

Yeah, if you want to do it that way, you can just wrap the background() call in draw() in an if statement, making it so background() draws only if the mouse button isn’t pressed:

  if (!mousePressed) {
    background(50);
  }

And then if you don’t want the custom array of trails, comment that out. But this way, everything gets drawn on top of itself, including the score.

1 Like

One final question (sorry for the bombardment of questions) but how would you get keep the paddle on the bottom of the window if I change the size of the screen. I tried using multipliers but I can’t seem to get it.

You can get rid of the line float paddleY = height + 240 near the start of your sketch (before setup()). All that line is doing is setting paddleY to equal 340, since the default height of the sketch before your setup() runs is just 100. (So, 100 + 240 = 340.)

Then just create the paddleY var in draw(), next to its buddy paddleX, and set paddleY's value relative to height, which at this point equals your actual canvas height. And then drop paddleY into your paddle rect call:

  float paddleX = mouseX;
  float paddleY = height - 60;
  // ...your other existing code here...
  rect(paddleX, paddleY, 100, 20);
3 Likes