P5 JS 圆圈移动问题

问题描述 投票:0回答:2

我正在为学校做一个项目,它的想法是,一个球开始移动并撞到另一个球,开始那个球移动,然后移动并撞到另一个球,直到最终整个网格移动并改变颜色。

我目前遇到的问题如下。

首先,这些球偶尔会不断相互碰撞和反弹,基本上会导致人们癫痫发作,因为它们闪烁着各种不同的颜色。

其次,球会从屏幕上弹开,我希望屏幕边缘像保险杠或碰撞物体一样,这样物体就不会弹到屏幕之外。

这是我的代码

function setup() {
  createCanvas(750, 750);
 
  noStroke();
  balls = [];
  for (x=0;x<25;x++){
    for (y=0;y<25;y++){
      b = new Ball(10+ x*30, 10+ y*30);
      balls.push(b);
    }
  }
  balls[210].vel = p5.Vector.random2D().mult(0.3);
}

function draw(){
  background(220);
  for (b of balls){
    b.update();
    b.checkCollision(balls);
  }
  for (b of balls){
    b.draw();
  }
}

class Ball{
  constructor(x,y){
    this.pos = createVector(x,y);
    this.vel = createVector(0,0);
    this.color = 'white';
  }
  update(){
    this.pos.add(this.vel);
  }
  draw(){
    fill(this.color);
    circle(this.pos.x, this.pos.y, 20);
  }
  checkCollision(others){
    for (const other of others){
      if (other != this){
        const d = this.pos.dist(other.pos);
        if (d < 20){
          this.vel.mult(-0.3);
          this.pos = this.pos.sub(1,1);
          other.pos = other.pos;
          other.vel = p5.Vector.random2D().mult(0.3);
          this.color = random(['red','pink','purple','blue','green','orange','yellow','olive','maroon','magenta','indigo','teal','violet','crimson','gold','azure','coral','cyan','emerald']);
          other.color = random(['red','pink','purple','blue','green','orange','yellow','olive','maroon','magenta','indigo','teal','violet','crimson','gold','azure','coral','cyan','emerald']);
        }
      }
    }
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js"></script>

如有任何帮助,我们将不胜感激!

我尝试添加一个位置修改器来处理两个圆圈不断碰撞的问题,但这似乎使它从屏幕上反弹成为一个更大的问题。我还没能想到解决它出界问题的方法,或者让屏幕边界充当保险杠。

javascript p5.js
2个回答
0
投票

我在您的代码中添加了一些内容,并更改了根据当前速度设置的颜色,以便更好地进行测试交互可视化。

const c_colors = ['red', 'pink', 'purple', 'blue', 'green', 'orange', 'yellow', 'olive', 'maroon', 'magenta', 'indigo', 'teal', 'violet', 'crimson', 'gold', 'azure', 'coral', 'cyan', 'emerald'];

function setup() {
  createCanvas(750, 750);

  noStroke();
  balls = [];
  for (x = 0; x < 9; x++) {
    for (y = 0; y < 9; y++) {
      b = new Ball(35 + x * 80, 35 + y * 80);
      balls.push(b);
    }
  }

  balls[55].vel = p5.Vector.random2D().mult(5);
}

function draw() {
  background(220);
  for (b of balls) {
    //b.checkCollision(balls);
    b.update();
  }

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

class Ball {
  constructor(x, y) {
    this.pos = createVector(x, y);
    this.vel = createVector(0, 0);
    this.color = 'white';
    this.radius = 25;
  }

  update() {
    this.pos.add(this.vel);
    this.vel.mult(0.99);

    this.checkCollision(balls);
    let velMagNorm = p5.Vector.mag(this.vel);
    this.color = lerpColor(color(255), color(255, 0, 0), velMagNorm);
  }

  draw() {
    fill(this.color);
    circle(this.pos.x, this.pos.y, this.radius * 2);
  }

  checkCollision(others) {
    if (this.pos.x <= this.radius || this.pos.x >= width - this.radius)
      this.vel.x *= -1;

    if (this.pos.y <= this.radius || this.pos.y >= height - this.radius)
      this.vel.y *= -1;

    for (const other of others) {
      if (this == other)
        continue;

      const d = this.pos.dist(other.pos);
      const vec = p5.Vector.sub(this.pos, other.pos);
      const velMag = p5.Vector.mag(this.vel);
      const normVec = vec.normalize();

      if (d < this.radius * 2) {
        this.vel.add(p5.Vector.mult(normVec, velMag * 0.99));

        other.vel.add(p5.Vector.mult(normVec, -velMag * 0.99));

        //this.color = random(c_colors);
        //other.color = random(c_colors);
      }
    }
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js"></script>


0
投票

最终的问题在于,球在随机方向上移动,没有规定什么是可行的区域,什么不是可行的移动区域 - 即,如果碰撞发生在向下运动中,则不要向上移动,反之,如果向下移动并与某物发生碰撞,则不要继续向下移动。为了解决这个问题,我根据命中条件规定了方向 - 增强碰撞检测,而不仅仅是检测发生了碰撞

© www.soinside.com 2019 - 2024. All rights reserved.