Math 相互反弹气泡(处理)

Math 相互反弹气泡(处理),math,vector,processing,bounce,Math,Vector,Processing,Bounce,我正在为学校做一个加工项目。 这个想法是让不同数量的气泡相互反弹,并在每次点击时改变它们的颜色(值)。这是一个多人游戏的基础。 所以我有这个 //ArrayList<Bubble> bubbles; int firstBubbles = 80; ArrayList<Bubble> bubbles = new ArrayList<Bubble>(10); void setup() { size(1200,800); for (int i = 0; i

我正在为学校做一个加工项目。 这个想法是让不同数量的气泡相互反弹,并在每次点击时改变它们的颜色(值)。这是一个多人游戏的基础。

所以我有这个

//ArrayList<Bubble> bubbles;
int firstBubbles = 80;
ArrayList<Bubble> bubbles = new ArrayList<Bubble>(10);

void setup() {
  size(1200,800);
  for (int i = 0; i < firstBubbles; ++i) {
    bubbles.add(new Bubble(int(random(0,width-100)),int(random(0,height-100)),true));
    //bubbles.get(i).addfirstbubbles();
    //println("Value: " + bubble.get(i).value);
    bubbles.get(i).addfirstbubbles();
  }
}

void draw() {
  background(200,200,200);
  for (int i = 0; i < bubbles.size(); i++) {

    Bubble bubble = bubbles.get(i); //get reference bubble

    bubble.move();
    bubble.display();
    bubble.bounceWalls();

    for (int j = 0; j < bubbles.size(); j++) {

      Bubble compare = bubbles.get(j); //compare bubble

      PVector vect = PVector.sub(compare.position, bubble.position);
      float magnitude = vect.mag();
      if(magnitude < bubble.size/2 + compare.size/2) {
        bubble.collide(compare); 
      }
    }


  }
}

void mouseReleased() {
  println("Released");
  for (Bubble b : bubbles) {
    if(mouseX > b.position.x - (b.size/2) && mouseX < b.position.x + (b.size/2) && mouseY > b.position.y - (b.size/2) && mouseY < b.position.y + (b.size/2)) {
      b.click();
    }    
  }
}

class Bubble {
  int value, size, xpos, ypos;
  PVector position, speed;
  Boolean comein;

  Bubble(int pos1, int pos2, Boolean ci) {
    xpos = pos1;
    ypos = pos2;
    comein = ci;
  }

  void addfirstbubbles() {
      size = 50;
      value = int(random(2));
      speed = new PVector(random(0.1, 2), (random(0.1, 2)));
      position = new PVector(xpos, ypos);
  }

  void bounceWalls() {
    if (position.x > width-size/2) {
      position.x = width-size/2;
      speed.x *= -1;
    } 
    else if (position.x < size/2) {
      position.x = size/2;
      speed.x *= -1;
    } 
    else if (position.y > height-size/2) {
      position.y = height-size/2;
      speed.y *= -1;
    } 
    else if (position.y < size/2) {
      position.y = size/2;
      speed.y *= -1;
    } 
  }

  //----- Update position -----
  void move() {
    position.add(speed);
  }

  //----- Draw on screen -----
  void display() {
    if (value == 1) {
      fill(255, 50, 100);
    } else {
      fill(100, 50, 255);
    }
    noStroke();
    ellipse(position.x, position.y, size, size);
  }

  //----- Collision -----
  void collide(Bubble other) {
    PVector bVect = PVector.sub(other.position, position);

    float bVectMag = bVect.mag();

    if (bVectMag < size/2 + other.size/2) {
      float theta  = bVect.heading();
      float sine = sin(theta);
      float cosine = cos(theta);

      PVector[] bTemp = {
        new PVector(), new PVector()
        };

        bTemp[1].x  = cosine * bVect.x + sine * bVect.y;
        bTemp[1].y  = cosine * bVect.y - sine * bVect.x;

      PVector[] vTemp = {
        new PVector(), new PVector()
        };

      vTemp[0].x  = cosine * speed.x + sine * speed.y;
      vTemp[0].y  = cosine * speed.y - sine * speed.x;
      vTemp[1].x  = cosine * other.speed.x + sine * other.speed.y;
      vTemp[1].y  = cosine * other.speed.y - sine * other.speed.x;

      PVector[] vFinal = {  
        new PVector(), new PVector()
        };

      vFinal[0].x = ((size - other.size) * vTemp[0].x + 2 * other.size * vTemp[1].x) / (size + other.size);
      vFinal[0].y = vTemp[0].y;

      vFinal[1].x = ((other.size - size) * vTemp[1].x + 2 * size * vTemp[0].x) / (size + other.size);
      vFinal[1].y = vTemp[1].y;

      bTemp[0].x += vFinal[0].x;
      bTemp[1].x += vFinal[1].x;

      PVector[] bFinal = { 
        new PVector(), new PVector()
        };

      bFinal[0].x = cosine * bTemp[0].x - sine * bTemp[0].y;
      bFinal[0].y = cosine * bTemp[0].y + sine * bTemp[0].x;
      bFinal[1].x = cosine * bTemp[1].x - sine * bTemp[1].y;
      bFinal[1].y = cosine * bTemp[1].y + sine * bTemp[1].x;

      other.position.x = position.x + bFinal[1].x;
      other.position.y = position.y + bFinal[1].y;

      position.add(bFinal[0]);

      speed.x = cosine * vFinal[0].x - sine * vFinal[0].y;
      speed.y = cosine * vFinal[0].y + sine * vFinal[0].x;
      other.speed.x = cosine * vFinal[1].x - sine * vFinal[1].y;
      other.speed.y = cosine * vFinal[1].y + sine * vFinal[1].x;
    }
  }

  void click() {
    value*=-1;
    //println("Value changed to" + value);
  }
}
//数组列表气泡;
int=80;
ArrayList气泡=新的ArrayList(10);
无效设置(){
规模(1200800);
对于(int i=0;ib.position.x-(b.size/2)和&mouseXb.position.y-(b.size/2)和&mouseY宽度大小/2){
位置x=宽度尺寸/2;
速度x*=-1;
} 
否则如果(位置x<尺寸/2){
位置x=尺寸/2;
速度x*=-1;
} 
否则如果(位置y>高度大小/2){
位置y=高度尺寸/2;
速度y*=-1;
} 
否则如果(位置y<尺寸/2){
位置y=尺寸/2;
速度y*=-1;
} 
}
//-----更新位置-----
无效移动(){
位置。添加(速度);
}
//-----在屏幕上画画-----
无效显示(){
如果(值==1){
填充(255、50、100);
}否则{
填充(100、50、255);
}
仰泳();
椭圆(位置.x,位置.y,大小,大小);
}
//-----碰撞-----
无效碰撞(气泡其他){
PVector bVect=PVector.sub(其他位置,位置);
float bVectMag=bVect.mag();
如果(bVectMag<尺寸/2+其他尺寸/2){
浮点θ=bVect.heading();
浮动正弦=正弦(θ);
浮点余弦=余弦(θ);
PVector[]bTemp={
新建PVector(),新建PVector()
};
bTemp[1].x=cosine*bVect.x+sine*bVect.y;
bTemp[1].y=余弦*bVect.y-正弦*bVect.x;
PVector[]vTemp={
新建PVector(),新建PVector()
};
vTemp[0].x=余弦*速度.x+正弦*速度.y;
vTemp[0].y=余弦*速度.y-正弦*速度.x;
vTemp[1].x=cosine*other.speed.x+sine*other.speed.y;
vTemp[1].y=cosine*other.speed.y-sine*other.speed.x;
PVector[]vFinal={
新建PVector(),新建PVector()
};
vFinal[0].x=((size-other.size)*vTemp[0].x+2*other.size*vTemp[1].x)/(size+other.size);
vFinal[0].y=vTemp[0].y;
vFinal[1].x=((other.size-size)*vTemp[1].x+2*size*vTemp[0].x)/(size+other.size);
vFinal[1].y=vTemp[1].y;
bTemp[0].x+=vFinal[0].x;
bTemp[1].x+=vFinal[1].x;
PVector[]bFinal={
新建PVector(),新建PVector()
};
b最终[0].x=cosine*bTemp[0].x-sine*bTemp[0].y;
b最终[0]。y=cosine*bTemp[0]。y+sine*bTemp[0]。x;
b最终[1].x=cosine*bTemp[1].x-sine*bTemp[1].y;
b最终[1]。y=cosine*bTemp[1]。y+sine*bTemp[1]。x;
其他.position.x=position.x+bFinal[1].x;
其他.position.y=position.y+bFinal[1].y;
位置。添加(b最终[0]);
速度.x=余弦*vFinal[0].x-正弦*vFinal[0].y;
速度.y=cosine*vFinal[0].y+sine*vFinal[0].x;
其他.speed.x=cosine*vFinal[1].x-sine*vFinal[1].y;
其他.speed.y=cosine*vFinal[1].y+sine*vFinal[1].x;
}
}
无效单击(){
值*=-1;
//println(“值更改为”+值);
}
}
到目前为止,这些泡沫或多或少都在相互反弹,但它们有时会表现得很怪异,它们会彼此环绕或只是粘在一起一段时间。碰撞主要基于,我将其更改为适合arraylist


尽管上面的例子非常有效,但有人知道他们为什么表现得如此奇怪吗?

TLDR您的代码,但是实现碰撞检测的一个常见错误是检测碰撞,采取步骤反弹碰撞的对象。。。但是,不能确保对象处于这样一种状态,即它们不会在下一次迭代中再次碰撞和反弹,可能会相互反弹(这可以解释您的“粘滞”行为;您的对象可能在每次迭代中都是振荡反弹;代码中的日志记录应该可以确认)。

,这是我过去几天一直在做的事,但我仍然一点也不知道为什么。。。