(16) Bouncing balls forever

All the previous examples has shown moving balls and astroids but without any sense of real physics. Not saying that this will be real, but much more real looking. I created a simple class for a ball object that has a location (x,y) and a speed (deltaX, deltaY) and size. By doing it as an object and keeping the objects in a list, we can add however as many we want. Look at this code and experiment with the mouse. Click left first, then move mouse and click right. Try changing the gravity and resistance and see what happens.... Do not be afraid.

This is how it looks:

The source code:

void setup() {
  size(600, 600);
  frameRate(60);
}

ArrayList<ball> balls = new ArrayList<ball>();
float gravity = 0.1;
float resistance = 0.9999;
int mX=300, mY=300;

void draw() {
  int i;

  background(0);
  fill(255);
  stroke(255);
  // Update and draw balls, if any
  for (i = 0; i<balls.size(); i++) {
    ball b = balls.get(i);
    b.update();
  }
  // Rest is just for the mouse lines  
  text("Ball goes from green (left click) to red (right click)", 15, 15);
  line(mX, mY, mouseX, mouseY);
  fill(color(0, 255, 0));
  ellipse(mX, mY, 5, 5);
  fill(color(255, 0, 0));
  ellipse(mouseX, mouseY, 5, 5);
}

// When left mouse button is pressed set origin, when right speed and direction
void mousePressed() {
  ball b;
  if (mouseButton == LEFT) {
    mX=mouseX;
    mY=mouseY;
  } else if (mouseButton == RIGHT) {
    // Add new ball
    b = new ball(mX,mY,10, 0.1*(mouseX-mX), 0.1*(mouseY-mY));
    balls.add(b);
  }
}

class ball {
  float x, y;
  int r;
  float dx, dy;

  // Constructor
  ball(int _x, int _y, int _r, float _dx, float _dy) {
    x = _x;
    y = _y;
    r = _r;
    dx = _dx;
    dy = _dy;
  }
  
  void update() {
    dy=dy+gravity;
    dy=dy*resistance;
    dx=dx*resistance;
    x=x+dx;
    y=y+dy;
    // Detect if we hit bottom, if so reverse y speed
    // Since we have gravity there is a small chance to get stuck at the bottom, 
    // thus we deduct 1 to y to make sure we always bounce back up (try remove it)
    if ((y+r)>height) {dy = -dy; y = y - 1; }
    // Detect if we hit top, if so reverse y speed
    if ((y-r)<0) dy = -dy;
    // Detect if we hit right, if so reverse x speed
    if ((x+r)>width) dx = -dx;
    // Detect if we hit left, if so reverse x speed
    if ((x-r)<0) dx = -dx;
    ellipse(x, y, 2*r, 2*r);
  }
}

No comments:

Post a Comment