彼此反弹气泡(加工)

时间:2014-12-11 21:28:34

标签: 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 < 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);
  }
}

到目前为止,气泡或多或少地相互反弹,但它们有时表现得很奇怪,它们会相互缠绕或者只是粘在一起一段时间。碰撞主要基于http://processing.org/examples/circlecollision.html,我改变它以适应arraylist。

有没有人知道为什么他们表现得如此奇怪,尽管上面的例子运作得很好?

1 个答案:

答案 0 :(得分:0)

TLDR您的代码,但实现碰撞检测的一个常见错误是检测碰撞,采取措施反弹碰撞对象......但不确保对象处于这样一种状态,以至于他们不会再碰撞在下一次迭代并再次反弹,可能会回到彼此(这将解释你的&#34;坚持&#34;行为;你的对象可能实际上是在每次迭代时振荡跳跃;代码中的一些记录应该确认)。