Why do some balls show they collided but others don't?

时间:2019-04-17 00:41:46

标签: javascript processing collision p5.js

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>

1 个答案:

答案 0 :(得分:1)

在您的代码中

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);
    }
}

如果球与另一个球发生碰撞,则该球的颜色会更改,但如果下一个球不与该球发生碰撞,则该球的颜色会变回。

draw中,您必须执行以下步骤:

  • 更新球的位置。
  • 验证每个Ball对象是否与其他Ball发生冲突
  • 绘制所有Ball
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();
    }
}

请参见示例,其中我将建议应用于您的原始代码:

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>