final int WIDTH = 200, HEIGHT = 200;
final int MAX_BALL = 30;

Ball ball[] = new Ball[MAX_BALL];

int ballNum, maxBallNum;
float parR, parG, parB;

// setup function
void setup() {
  size(WIDTH, HEIGHT);
  ballNum = 0;
  maxBallNum = 0;
  parR = 255 / (float)width;
  parG = 255 / (float)height;
  parB = 255 / (float)(width + height);
  frameRate(30);
}

// draw function
void draw() {
  background(0);

  for (int i = 0; i < maxBallNum; i++) {
    ball[i].update();
  }

  stroke(255);
  line(width/2, height/2, mouseX, mouseY);

  color tmpcolor = color(parR*(float)mouseX, parG*(float)mouseY, parB*(float)(mouseX+mouseY));
  stroke(tmpcolor);
  fill(tmpcolor);
  ellipse(mouseX, mouseY, 10, 10);
}

// This function is called when mouse clicked
void mousePressed() {
  color tmpcolor = color(parR*(float)mouseX, parG*(float)mouseY, parB*(float)(mouseX+mouseY));
  ball[ballNum] = new Ball(mouseX, mouseY, 5, (mouseX-width/2)/5, (mouseY-height/2)/5, tmpcolor);
  ballNum = ++ballNum % MAX_BALL;
  if (maxBallNum < MAX_BALL) {
    maxBallNum++;
  }
}

// Ball class
class Ball {
  float x, y;
  float r;
  float vx, vy;
  color cl;

  // Constructor
  Ball(float x_, float y_, float r_, float vx_, float vy_, color cl_) {
    x = x_;
    y = y_;
    r = r_;
    vx = vx_;
    vy = vy_;
    cl = cl_;
  }

  // define moving of ball
  void move() {
    if (x-r + vx < 0) {
      vx = -1 * vx;
      x = r;
    } else if (x+r + vx > width-1) {
      vx = -1 * vx;
      x = width-1 - r;
    } else {
      x = x + vx;
    }

    if (y-r + vy < 0) {
      vy = -1 * vy;
      y = r;
    } else if (y+r + vy > height-1) {
      vy = -1 * vy;
      y = height-1 - r;
    } else {
      y = y + vy;
    }
  }

  // draw function
  void draw() {
    stroke(cl);
    fill(cl);
    ellipse(x, y, r*2, r*2);
  }

  // call to move and draw
  void update() {
    move();
    draw();
  }
}
