为什么有些球显示它们发生了碰撞,而有些却没有?

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

我希望我生成的球在碰撞时相互反弹,但首先我试图做到这一点,以便代码实际检测到它们何时发生碰撞。为此,我改变了相互碰撞的球的颜色,然后在它们没有碰撞时将它们改回原来的颜色。有些时候它有效,但很多时候无效。当我生成球时,有些球在相互撞击时会改变颜色,但当它们撞击不同的球时不会改变颜色。

// 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>

在您的代码中

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
  • 绘制所有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();
    }
}

查看示例,其中我将建议应用于您的原始代码:

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>