1

I want the balls I spawn in to bounce off of each other when they collide but first I am trying to make it so the code actually detects when they collide. To do that I change the color of the balls that collide with each other and then change them back to the original color when they are not colliding. Some of the time it works but a lot of the time it does not. When I spawn the balls in, some will change color when they hit each other but then will not change color when they hit a different ball.

// ctrl+alt+l to run
let fr = 60; // starting FPS
let balls = [];

function setup(){
    createCanvas(window.innerWidth,window.innerHeight);
    frameRate(fr);
}

function draw(){
    background(50);
    for(b of balls){
        b.move();
        b.show();
        b.bounce();
        for(other of balls){
            if(b != other && b.intersects(other)){
                b.changeColor(100);
        }else{
            b.changeColor(0);
        }
    }
  }
}

function mouseClicked(){
    b = new Ball(mouseX,mouseY,random(20,70),random(-10,10),random(-10,10));
    balls.push(b);
}

class Ball{
    constructor(_x,_y,_r,_sx,_sy){
        this.x = _x;
        this.y = _y;
        this.r = _r;
        this.sx = _sx;
        this.sy = _sy;
        this.brightness = 0;
    }

    move(){
        this.x += this.sx;
        this.y += this.sy;
    }

    show(){
      if(this.brightness==0){
          noFill();
      } else{
          fill(this.brightness)
      }
      stroke(255);
      strokeWeight(4);
      ellipse(this.x,this.y,this.r*2,this.r*2);
    }

    changeColor(bright){
        this.brightness = bright;
    }

    bounce(){
        if(this.x + this.r > width || this.x - this.r < 0){
            this.sx = this.sx * -1;
        }
        if(this.y + this.r > height || this.y - this.r < 0){
            this.sy = this.sy * -1;
        } 
    }

    intersects(other,color){
        if(dist(this.x,this.y,other.x,other.y) < this.r + other.r){
          return true;
        }
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.js"></script>
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Tjtorin
  • 99
  • 1
  • 1
  • 10

1 Answers1

1

In your code

for(b of balls){
    b.move();
    b.show();
    b.bounce();
    for(other of balls){
        if(b != other && b.intersects(other)){
            b.changeColor(100);
    }else{
            b.changeColor(0);
    }
}

the color of the ball is changed, if it collides with an other ball, but the color is change back, if the next ball doesn't collide with.

In draw you've to do the following steps:

  • update the positions of the balls.
  • verify for each Ball object if it collides with any other Ball
  • draw all Balls
function draw(){
    background(50);

    for(b of balls){
        b.move();
        b.bounce();
    }

    for(b of balls){

        anyCollision = false;
        for(other of balls){
            if(b != other && b.intersects(other)){
                anyCollision = true;
                break;
            }
        }

        b.changeColor(anyCollision ? 100 : 0);
    }

    for(b of balls){
        b.show();
    }
}

See the example, where I applied the suggestions to your original code:

let fr = 60; // starting FPS
let balls = [];

function setup(){
    createCanvas(window.innerWidth,window.innerHeight);
    frameRate(fr);
}

function draw(){
    background(50);
    
    for(b of balls){
        b.move();
        b.bounce();
    }

    for(b of balls){
        
        anyCollision = false;
        for(other of balls){
            if(b != other && b.intersects(other)){
                anyCollision = true;
                break;
            }
        }

        b.changeColor(anyCollision ? color(255, 0, 0) : 0);
    }

    for(b of balls){
        b.show();
    }
}

function mouseClicked(){
    b = new Ball(mouseX,mouseY,random(20,70),random(-10,10),random(-10,10));
    balls.push(b);
}

class Ball{
    constructor(_x,_y,_r,_sx,_sy){
        this.x = _x;
        this.y = _y;
        this.r = _r;
        this.sx = _sx;
        this.sy = _sy;
        this.brightness = 0;
    }

  move(){
      this.x += this.sx;
      this.y += this.sy;
  }

  show(){
    if(this.brightness==0){
        noFill();
    } else{
        fill(this.brightness)
    }
    stroke(255);
    strokeWeight(4);
    ellipse(this.x,this.y,this.r*2,this.r*2);
  }

  changeColor(bright){
      this.brightness = bright;
  }

  bounce(){
      if(this.x + this.r > width || this.x - this.r < 0){
          this.sx = this.sx * -1;
      }
      if(this.y + this.r > height || this.y - this.r < 0){
          this.sy = this.sy * -1;
      } 
  }

  intersects(other,color){
      if(dist(this.x,this.y,other.x,other.y) < this.r + other.r){
        return true;
      }
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.js"></script>
Rabbid76
  • 202,892
  • 27
  • 131
  • 174