【问题标题】:Bounce bubbles from each other (Processing)相互弹跳气泡(处理中)
【发布时间】:2015-02-10 12:26:48
【问题描述】:

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

所以我有这个

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

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

【问题讨论】:

    标签: math vector processing bounce


    【解决方案1】:

    TLDR 你的代码,但是实现碰撞检测的一个常见错误是检测碰撞,采取措施反弹碰撞的物体......但不能确保物体处于不会再次碰撞的状态下一次迭代并再次反弹,可能会相互反弹(这将解释您的“粘着”行为;您的对象实际上可能在每次迭代时都在振荡反弹;应该确认代码中的一些日志记录)。

    【讨论】:

    • 好吧,这就是我最近几天一直在做的事情,但我仍然不知道为什么......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-15
    • 1970-01-01
    • 1970-01-01
    • 2015-03-14
    相关资源
    最近更新 更多