Error on bouncing ball with cursor

edited January 2016 in Questions about Code

So im trying to make a code so that i have a program with bouncing balls and a cursor (also a ball the same size) and the cursor works like a player pushing the balls or stoping them. Like the air hockey game. I copied a code from the processing website and i've been adapting to what i want but i cant fix a problem with it. All is working as i want but if the ball is moving with x.velocity positive (hits the cursor on its left side) my cursos ball kinda swallows it. As well as if the ball is moving with y.velocity negative (hits the cursos on its down side). You would help me a lot if anyone could fix this, I've been working for days and still getting no further.

Heres de code :

float alfa=PI/6;
float xSpeed, ySpeed;

class cursor {
  PVector position;
  PVector velocityb,velocity;
  float r,m;

  cursor(float raio) {
    float x=mouseX;
    float y=mouseY;
    if ( mouseX-pmouseX > 0 ) {
    xSpeed = abs(mouseX-pmouseX);
  } else {
    xSpeed = -abs(mouseX-pmouseX);
  }

  if ( mouseY-pmouseY > 0 ) {
    ySpeed = abs(mouseY-pmouseY);
  } else {
    ySpeed = -abs(mouseY-pmouseY);
  }
    position = new PVector(x, y);
    velocity = new PVector(xSpeed,ySpeed);
    //velocity = PVector.random2D();
    velocity.mult(3);
    r=raio;
    m = r*.1;
  }

  void lateralcollision(){
    if (position.x > width-r) {
      position.x = width-r;
      velocity.x *= -1;
    } 
    else if (position.x < r) {
      position.x = r;
      velocity.x *= -1;
    } 
    else if (position.y > height-r) {
      position.y = height-r;
      velocity.y *= -1;
    } 
    else if (position.y < r) {
      position.y = r;
      velocity.y *= -1;
    }
  }

  void show() {
    noStroke();
    strokeWeight(1);
    fill(200);
    ellipse(position.x, position.y, r*2, r*2);
    fill(0, 0, 255);
    ellipse(position.x, position.y, r*1.2, r*1.2);
    fill(200);
    for (float alfa=PI/3/2; alfa<=2*PI+PI/3/2; alfa+=PI/3) {
      strokeWeight(3);
      stroke(200);
      line(position.x, position.y, position.x+(r-5)*cos(alfa), position.y+(r-5)*sin(alfa));
    }
    ellipse(position.x, position.y, r*0.9, r*0.9);
    fill(0, 0, 255);
    ellipse(position.x, position.y, r*0.5, r*0.5);
  }

  void chocar(ball other) {
    if ( velocity.x<1 && other.velocity.x < 0 ) {
    velocity.x = 1;
  } else if ( velocity.x<1 && other.velocity.x > 0 ) {
    velocity.x = 1;
  }
  if (velocity.y<1 && other.velocity.y < 0 ) {
    velocity.y = 1;
  } else if ( velocity.y<1 && other.velocity.y > 0 ){
    velocity.y = 1;
  }
    // get distances between the balls components
    PVector bVect = PVector.sub(other.position, position);

    // calculate magnitude of the vector separating the balls
    float bVectMag = bVect.mag();

    if (bVectMag < r + other.r) {
      // get angle of bVect
      float theta  = bVect.heading();
      // precalculate trig values
      float sine = sin(theta);
      float cosine = cos(theta);

      /* bTemp will hold rotated ball positions. You 
       just need to worry about bTemp[1] position*/
      PVector[] bTemp = {
        new PVector(), new PVector()
        };

        /* this ball's position is relative to the other
         so you can use the vector between them (bVect) as the 
         reference point in the rotation expressions.
         bTemp[0].position.x and bTemp[0].position.y will initialize
         automatically to 0.0, which is what you want
         since b[1] will rotate around b[0] */
      bTemp[1].x  = cosine * bVect.x + sine * bVect.y;
      bTemp[1].y  = cosine * bVect.y - sine * bVect.x;

      // rotate Temporary velocities
      PVector[] vTemp = {
        new PVector(), new PVector()
        };

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

      /* Now that velocities are rotated, you can use 1D
       conservation of momentum equations to calculate 
       the final velocity along the x-axis. */
      PVector[] vFinal = {  
        new PVector(), new PVector()
        };

      // final rotated velocity for b[0]
      vFinal[0].x = ((m - other.m) * vTemp[0].x + 2 * other.m * vTemp[1].x) / (m + other.m);
      vFinal[0].y = vTemp[0].y;

      // final rotated velocity for b[1]
      vFinal[1].x = ((other.m - m) * vTemp[1].x + 2 * m * vTemp[0].x) / (m + other.m);
      vFinal[1].y = vTemp[1].y;

      // hack to avoid clumping
      bTemp[0].x += vFinal[0].x;
      bTemp[1].x += vFinal[1].x;

      /* Rotate ball positions and velocities back
       Reverse signs in trig expressions to rotate 
       in the opposite direction */
      // rotate balls
      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;

      // update balls to screen position
      other.position.x = position.x + bFinal[1].x+1;
      other.position.y = position.y + bFinal[1].y+1;

      position.add(bFinal[0]);

      // update velocities
      //velocity.x = cosine * vFinal[0].x - sine * vFinal[0].y;
      //velocity.y = cosine * vFinal[0].y + sine * vFinal[0].x;
      other.velocity.x = (cosine * vFinal[1].x - sine * vFinal[1].y);
      other.velocity.y = (cosine * vFinal[1].y + sine * vFinal[1].x);
      other.velocity.div(4);
    }
  }

} 
Tagged:

Answers

  • edited January 2016 Answer ✓

    Where's the Ball class?

  • edited January 2016
    class ball {
      float ang;
      PVector position;
      PVector velocity;
      boolean over;
      float r, m, x, y,add;
      int n,draw,included;
      PImage object;
    
      ball(int i) {
        draw=0;
        ang=0;
        included=0;
        object=loadImage("ds"+i+".png");
        add=random(0.03);
        over=true;
        while(over){
          r = random(height/24,height/12);
          n=i;
          over=false;
          x=random(r+width/25.6,width-r-width/25.6);
          y=random(height/2,height-r-height/7.2);
          for(int z=0;z<n;z++){
            if(dist(x,y,b[z].x,b[z].y)<r+b[z].r){
              over=true;
            }
          }
        }
        position = new PVector(x, y);
        velocity = PVector.random2D();
        velocity.mult(3);
        m = r*.1;
      }
    
      void update() {
        position.add(velocity);
      }
    
          /*if (position.x > width-r) {
            position.x = width-r;
            velocity.x *= -1;
          } 
          else if (position.x < r) {
            position.x = r;
            velocity.x *= -1;
          } 
          else if (position.y > height-r) {
            position.y = height-r;
            velocity.y *= -1;
          } 
          else if (position.y < r) {
            position.y = r;
            velocity.y *= -1;
          }*/
    
      void checkBoundaryCollision() {
        if(barrier==0){
          if (position.x > width-r-width/25.6) {
            position.x = width-r-width/25.6;
            velocity.x *= -1;
          } 
          else if (position.x < r+width/25.6) {
            position.x = r+width/25.6;
            velocity.x *= -1;
          } 
          else if (position.y > height-r-height/7.2) {
            position.y = height-r-height/7.2;
            velocity.y *= -1;
          }else if (position.y < -r*2) {
            position.x = -r*2;
            position.y = -r*2;
            draw=1;
          }
        }
      }
    
      void changeDirections(int i){
        environmentChoice=1;
      }
    
      void checkCollision(ball other) {
    
        // get distances between the balls components
        PVector bVect = PVector.sub(other.position, position);
    
        // calculate magnitude of the vector separating the balls
        float bVectMag = bVect.mag();
    
        if (bVectMag < r + other.r) {
          // get angle of bVect
          float theta  = bVect.heading();
          // precalculate trig values
          float sine = sin(theta);
          float cosine = cos(theta);
    
          /* bTemp will hold rotated ball positions. You 
           just need to worry about bTemp[1] position*/
          PVector[] bTemp = {
            new PVector(), new PVector()
            };
    
            /* this ball's position is relative to the other
             so you can use the vector between them (bVect) as the 
             reference point in the rotation expressions.
             bTemp[0].position.x and bTemp[0].position.y will initialize
             automatically to 0.0, which is what you want
             since b[1] will rotate around b[0] */
            bTemp[1].x  = cosine * bVect.x + sine * bVect.y;
          bTemp[1].y  = cosine * bVect.y - sine * bVect.x;
    
          // rotate Temporary velocities
          PVector[] vTemp = {
            new PVector(), new PVector()
            };
    
          vTemp[0].x  = cosine * velocity.x + sine * velocity.y;
          vTemp[0].y  = cosine * velocity.y - sine * velocity.x;
          vTemp[1].x  = cosine * other.velocity.x + sine * other.velocity.y;
          vTemp[1].y  = cosine * other.velocity.y - sine * other.velocity.x;
    
          /* Now that velocities are rotated, you can use 1D
           conservation of momentum equations to calculate 
           the final velocity along the x-axis. */
          PVector[] vFinal = {  
            new PVector(), new PVector()
            };
    
          // final rotated velocity for b[0]
          vFinal[0].x = ((m - other.m) * vTemp[0].x + 2 * other.m * vTemp[1].x) / (m + other.m);
          vFinal[0].y = vTemp[0].y;
    
          // final rotated velocity for b[0]
          vFinal[1].x = ((other.m - m) * vTemp[1].x + 2 * m * vTemp[0].x) / (m + other.m);
          vFinal[1].y = vTemp[1].y;
    
          // hack to avoid clumping
          bTemp[0].x += vFinal[0].x;
          bTemp[1].x += vFinal[1].x;
    
          /* Rotate ball positions and velocities back
           Reverse signs in trig expressions to rotate 
           in the opposite direction */
          // rotate balls
          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;
    
          // update balls to screen position
          other.position.x = position.x + bFinal[1].x;
          other.position.y = position.y + bFinal[1].y;
    
          position.add(bFinal[0]);
    
          // update velocities
          velocity.x = cosine * vFinal[0].x - sine * vFinal[0].y;
          velocity.y = cosine * vFinal[0].y + sine * vFinal[0].x;
          other.velocity.x = cosine * vFinal[1].x - sine * vFinal[1].y;
          other.velocity.y = cosine * vFinal[1].y + sine * vFinal[1].x;
        }
      }
    
      void chocar(ball other) {
        // get distances between the balls components
        PVector bVect = PVector.sub(other.position, position);
    
        // calculate magnitude of the vector separating the balls
        float bVectMag = bVect.mag();
    
        if (bVectMag < r + other.r) {
          // get angle of bVect
          float theta  = bVect.heading();
          // precalculate trig values
          float sine = sin(theta);
          float cosine = cos(theta);
    
          /* bTemp will hold rotated ball positions. You 
           just need to worry about bTemp[1] position*/
          PVector[] bTemp = {
            new PVector(), new PVector()
            };
    
            /* this ball's position is relative to the other
             so you can use the vector between them (bVect) as the 
             reference point in the rotation expressions.
             bTemp[0].position.x and bTemp[0].position.y will initialize
             automatically to 0.0, which is what you want
             since b[1] will rotate around b[0] */
          bTemp[1].x  = cosine * bVect.x + sine * bVect.y;
          bTemp[1].y  = cosine * bVect.y - sine * bVect.x;
    
          // rotate Temporary velocities
          PVector[] vTemp = {
            new PVector(), new PVector()
            };
    
          vTemp[0].x  = cosine * velocity.x + sine * velocity.y;
          vTemp[0].y  = cosine * velocity.y - sine * velocity.x;
          vTemp[1].x  = cosine * other.velocity.x + sine * other.velocity.y;
          vTemp[1].y  = cosine * other.velocity.y - sine * other.velocity.x;
    
          /* Now that velocities are rotated, you can use 1D
           conservation of momentum equations to calculate 
           the final velocity along the x-axis. */
          PVector[] vFinal = {  
            new PVector(), new PVector()
            };
    
          // final rotated velocity for b[0]
          vFinal[0].x = ((m - other.m) * vTemp[0].x + 2 * other.m * vTemp[1].x) / (m + other.m);
          vFinal[0].y = vTemp[0].y;
    
          // final rotated velocity for b[0]
          vFinal[1].x = ((other.m - m) * vTemp[1].x + 2 * m * vTemp[0].x) / (m + other.m);
          vFinal[1].y = vTemp[1].y;
    
          // hack to avoid clumping
          bTemp[0].x += vFinal[0].x;
          bTemp[1].x += vFinal[1].x;
    
          /* Rotate ball positions and velocities back
           Reverse signs in trig expressions to rotate 
           in the opposite direction */
          // rotate balls
          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;
    
          // update balls to screen position
          other.position.x = position.x + bFinal[1].x;
          other.position.y = position.y + bFinal[1].y;
    
          position.add(bFinal[0]);
    
          // update velocities
          velocity.x = cosine * vFinal[0].x - sine * vFinal[0].y;
          velocity.y = cosine * vFinal[0].y + sine * vFinal[0].x;
          other.velocity.x = cosine * vFinal[1].x - sine * vFinal[1].y;
          other.velocity.y = cosine * vFinal[1].y + sine * vFinal[1].x;
        }
    
        impacto.play();
      }
    
    
      void show() {
        pushMatrix();
        translate(position.x, position.y);
        rotate(ang);
        image(object,0,0, r*2, r*2);
        popMatrix();
        ang+=add;
      }
    }
    
  • don't mark an answer as the solution too soon....

    is that in eclipse or in processing?

  • It was a mistake, could no revert... In processing

  • what do you mean?

  • I accidentally clicked on the mark "yes" for the Answer.

    Then i was saying that the code is programmed for processing

Sign In or Register to comment.