越野车弹跳球

时间:2019-01-20 13:00:27

标签: processing collision

我在“处理”中制作了一个碰撞球草图,但遇到了一个奇怪的错误。尽管有从墙壁弹跳的条件,但一些球会卡在墙壁上。我在这里找不到错误的来源。有人可以帮忙吗?我还意识到,可能有(很多)不良的编码习惯,但我事先表示歉意。

我正在发布以下代码。

1)主:https://pastebin.com/hv0H14gZ

particle[] elec = new particle[5];

boolean record = false;

void setup(){
  float x=0,y=0;
  int i,j;
  float diam = 100;

  size(800,400);

  //Initialising the particle objects
  for (int k = 0; k < elec.length; k++){
    x = random(width/10, width/1.2);
    y = random(height/10, height/1.2);
    elec[k] = new particle(x,y);
  }

  //Spawning at random places
  for ( i = 0; i < elec.length; i++){

   if (i!=0){

     for (  j = 0; j < elec.length; j ++){

       if (dist(x,y,elec[j].getX(),elec[j].getY()) <= diam){
         x = random(width/10, width/1.2);
         y = random(height/10, height/1.2);
         j = -1;
       }
     }
  }

    elec[i] = new particle(x,y,diam,4,4,2);


  }


}
void draw(){
  background(0);

  for (int i = 0; i < elec.length; i++){
    elec[i].update(elec);
    elec[i].move();
    elec[i].bounce();
    if(record){
      saveFrame("collide_#####.png");
      fill(255,0,0);
    } else {
      fill(0,255,0);
    }

    ellipse(width/1.01, height/1.01,5,5);
  }

}

void keyPressed(){
  if (key =='r' || key =='R'){
    record = !record;
  }
}

2)类别:https://pastebin.com/Rt49sN9c

public class velocity{
  float delx, dely;

  //Constructor 1 
  public velocity(){}

  //Constructor 2
  public velocity(float delx, float dely){
    this.delx = delx;
    this.dely = dely;
  }

  //Mutators for xvelocity and y velocity
  public float getdelx(){
    return this.delx;
  }

  public float getdely(){
    return this.dely;
  }

  //Accessors for xvelocity and y velocity
  public void setdelx(float delx){
    this.delx = delx;
  }

  public void setdely(float dely){
    this.dely = dely;
  }

}






public class particle{

  private float xpos , ypos, delx , dely,size, decay, mass;
  color colour;

  //constructor 1
  public particle(float x, float y){
  this.xpos = x;
  this.ypos = y;
  }

  //constructor 2
  public particle(float xpos, float ypos, float size, float delx, float dely, float mass){
    this.xpos = xpos;
    this.ypos = ypos;
    this.size = size;
    this.delx = delx;
    this.dely = dely;
    this.mass = mass;

  }

  //Mutators for size, x velocity y velocity and velocity vector
  public void setsize(float size){
    this.size = size;
  }

  public void setDX(float delx){
    this.delx = delx;
  }

  public void setDY(float dely){
    this.dely = dely;
  }




  //Accessors for size, x position, y position, x velocity and y velocity

  public float getsize(){
    return this.size;
  }

  public float getX(){
    return this.xpos;
  }

  public float getY(){
    return this.ypos;
  }

  public float getDX(){
    return this.delx;
  }

  public float getDY(){
    return this.dely;
  }

  public float getmass(){
    return this.mass;
  }

  public velocity getvel(){

    velocity v = new velocity(this.getDX(), this.getDY());
    return v;
  }



  //Functionality. Moving around, Bouncing off of walls, and basic display updates
  public void move(){
    this.xpos += this.delx;
    this.ypos += this.dely;
  }

  public void bounce(){
    if((this.xpos - this.size/2.0) < 0 || (this.xpos + this.size/2.0) > width){
      this.setDX(this.getDX()*-1);
    }
    if((this.ypos - this.size/2.0) < 0 || (this.ypos + this.size/2.0) > height){
       this.setDY(this.getDY()*-1);
    }
  }

  public void update(particle[] elec){

    for(int i =0; i< elec.length; i++){

      if(this == elec[i]) continue;
      if(dist(this.getX(),this.getY(),elec[i].getX(),elec[i].getY()) - this.getsize() <0){
        collision(this, elec[i]);
        //println(dist(this.getX(),this.getY(),elec[i].getX(),elec[i].getY()) - this.getsize()/2);
      }
    }
    display();
  }

  public void display(){
    stroke(0);
    fill(119,240,153);   
    ellipse(this.xpos, this.ypos, this.size ,this.size);
  }
}



velocity rotate(velocity v, float angle){
  float x = v.getdelx()*cos(angle) - v.getdely()*sin(angle);
  float y = v.getdelx()*sin(angle) + v.getdely()*cos(angle);

  velocity vel = new velocity(x,y);
  return vel;
}



void collision(particle p1, particle p2){

  float xveldiff = p1.getDX()-p2.getDX();
  float yveldiff = p1.getDY()-p2.getDY();

  float xdist = p2.getX() - p1.getX();
  float ydist = p2.getY() - p1.getY();

  //Check for accidental overlaps of particles
  if(xveldiff*xdist + yveldiff*ydist > 0){

    float angle = -atan2(p2.getY() - p1.getY(), p2.getX() - p1.getY());

    float m1 = p1.getmass();
    float m2 = p2.getmass();

    velocity u1 = rotate(p1.getvel(),angle);
    velocity u2 = rotate(p2.getvel(),angle);

    velocity v1 = new velocity(u1.getdelx() * (m1 - m2) / (m1 + m2) + u2.getdelx() * 2 * m2 / (m1 + m2), u1.getdely());
    velocity v2 = new velocity(u2.getdelx() * (m1 - m2) / (m1 + m2) + u1.getdelx() * 2 * m2 / (m1 + m2), u2.getdely());

    velocity vf1 = rotate(v1, -angle);
    velocity vf2 = rotate(v2, -angle);

    p1.setDX(vf1.getdelx());
    p1.setDY(vf1.getdely());

    p2.setDX(vf2.getdelx());
    p2.setDY(vf2.getdely());
  }

}

1 个答案:

答案 0 :(得分:4)

不错的动画,问题由类bounce的方法particle解决:

如果“球”没有一步就离开墙壁,则它会粘住。
注意,例如,如果满足条件(this.xpos - this.size/2.0) < 0两次,则方向反转两次(this.getDX()*-1)。这会导致球连续弹回墙壁并导致沿着墙壁的颤抖运动。

 public void bounce(){

     if((this.xpos - this.size/2.0) < 0 || (this.xpos + this.size/2.0) > width){
         this.setDX(this.getDX()*-1);
     }
     if((this.ypos - this.size/2.0) < 0 || (this.ypos + this.size/2.0) > height){
         this.setDY(this.getDY()*-1);
     }
 }

如果球要靠近墙壁,则必须确保方向(delxdely)始终指向墙壁之外:

public void bounce(){

    if( this.xpos - this.size/2.0 < 0 ) {
        this.setDX( Math.abs(this.getDX()) );
    } else if( this.xpos + this.size/2.0 > width ) {
        this.setDX( -Math.abs(this.getDX()) );
    }

    if( this.ypos - this.size/2.0 < 0 ) {
        this.setDY( Math.abs(this.getDY()) );
    } else if( this.ypos + this.size/2.0 > height ) {
        this.setDY( -Math.abs(this.getDY()) );
    }
}