1

I'm trying to trigger animations in a simple pong game when the ball bounces off each edge. However, I'm struggling to get the animations to appear the way I want them to. I want the ellipses to draw on top of each other in the order that the edges are hit. This sometimes happens, but I believe the problem is that when two animation booleans are true at the same time, whichever animation appears later in the program flow will draw over the other. So the way I've laid it out below, the blue will always draw over the yellow if both are true, and the red will always draw over both blue and yellow if both are true.

Any assistance with this would be much appreciated! Thanks.

var bg = 220;

var x = 0;
var y = 200;
var speed = 3;
var speedY = 4;

var leftAnim = false;
var leftX;
var leftY;
var leftDiam = 40;

var rightAnim = false;
var rightX;
var rightY;
var rightDiam = 40;

var topAnim = false;
var topX;
var topY;
var topDiam = 40;

function setup() {
  createCanvas(400, 400);
}

function draw() {

  background(bg);
  noStroke();

  edgeAnimation();

  fill("white");
  ellipse(x, y, 40, 40);
  x += speed;
  y += speedY;

  if (x > width) {
    //set rightAnim boolean to true to trigger right edge animation
    rightAnim = true;
    //update animating ellipse position variables to draw it at the same point where ball bounced
    rightX = x;
    rightY = y;
    //reverse x direction of ball
    speed *= -1;
  }

  if (x < 0) {
    leftAnim = true;
    leftX = x;
    leftY = y;
    speed *= -1;
  }
  // if the ball hits the top of the canvas, reverse the y direction of the ball    
  if (y < 0) {
    topAnim = true;
    topX = x;
    topY = y;
    speedY *= -1;
  }

  //if ball hits bottom of the canvas, stop the ball's motion
  if (y > height) {
    speed = 0;
    speedY = 0;
  }

  //conditional to check for collision with paddle
  if (x > mouseX && x < mouseX + 100 && y == height - 60) {
    speedY *= -1;
  }
  // Paddle
  rect(mouseX, height - 40, 100, 30);
}

function edgeAnimation() {
  if (leftAnim == true) {
    fill("gold");
    ellipse(leftX, leftY, leftDiam);
    leftDiam += 20;
    //if animating ellipse fills the canvas, change the background color to the ellipse color, change leftAnim boolean to false and reset the diameter's size
    if (leftDiam > 1150) {
      bg = "gold";
      leftAnim = false;
      leftDiam = 40;
    }
  }

  if (rightAnim == true) {
    fill("RoyalBlue");
    ellipse(rightX, rightY, rightDiam);
    rightDiam += 20;
    if (rightDiam > 1150) {
      bg = "RoyalBlue";
      rightAnim = false;
      rightDiam = 40;
    }
  }

  if (topAnim == true) {
    fill("crimson");
    ellipse(topX, topY, topDiam);
    topDiam += 20;
    if (topDiam > 1150) {
      bg = "crimson";
      topAnim = false;
      topDiam = 40;
    }
  }

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.js"></script>
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
bettywhite
  • 13
  • 3

1 Answers1

2

Don't use boolean states, but use list of animations.

var animation = []

Is a new edge is hit the append a new animation data set at the end (.push) of the animation list:

function draw() {

    // [...]

    if (x > width) {
        animation.push( {color: "RoyalBlue", x: x, y: y, diam:40} );
        speed *= -1;
    }
    if (x < 0) {
        animation.push( {color: "gold", x: x, y: y, diam: 40} );
        speed *= -1;
    }  
    if (y < 0) {
        animation.push( {color: "crimson", x: x, y: y, diam: 40} );
        speedY *= -1;
    }

    // [...]

}

The animations can be drawn in a loop. Keep only that animations which doesn't exceed the limit:

function edgeAnimation() {

    var keepAnimation = []
    for (let i = 0; i < animation.length; ++i) {
        fill( animation[i].color );
        ellipse( animation[i].x, animation[i].y, animation[i].diam );
        animation[i].diam += 20;
        if (animation[i].diam > 1150) {
            bg = animation[i].color;
        } else {
            keepAnimation.push(animation[i]);
        }
    }
    animation = keepAnimation;
}

See the example, wher I applied the suggestions to the code of the question:

var bg = 220;

var x = 0;
var y = 200;
var speed = 3;
var speedY = 4;

var animation = []

function setup() {
  createCanvas(400, 400);
}

function draw() {

    background(bg);
    noStroke();

    edgeAnimation();

    fill("white");
    ellipse(x, y, 40, 40);
    x += speed;
    y += speedY;

    if (x > width) {
        animation.push( {color: "RoyalBlue", x: x, y: y, diam:40} );
        speed *= -1;
    }
    if (x < 0) {
        animation.push( {color: "gold", x: x, y: y, diam: 40} );
        speed *= -1;
    }  
    if (y < 0) {
        animation.push( {color: "crimson", x: x, y: y, diam: 40} );
        speedY *= -1;
    }

    //if ball hits bottom of the canvas, stop the ball's motion
    if (y > height) {
        x = random(20, width-20);
        y = 20;
        speed = random(2,4);
        speedY = 6 - speed;
    }

    //conditional to check for collision with paddle
    if (x > mouseX && x < mouseX + 100 && y < height - 59 + speedY && y > height - 60) {
        speedY *= -1;
        y = height - 60
    }
    // Paddle
    rect(mouseX, height - 40, 100, 30);
}

function edgeAnimation() {

    var keepAnimation = []
    for (let i = 0; i < animation.length; ++i) {
        fill( animation[i].color );
        ellipse( animation[i].x, animation[i].y, animation[i].diam );
        animation[i].diam += 20;
        if (animation[i].diam > 1150) {
            bg = animation[i].color;
        } else {
            keepAnimation.push(animation[i]);
        }
    }
    animation = keepAnimation;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.js"></script>
Rabbid76
  • 202,892
  • 27
  • 131
  • 174