Sanguisughe 2

Le sanguisughe si evitano, se troppo vicine

int NUM=30,  // worm length
    DIM=8,   // max speed
    TOT=16,
    DIST;

Worm[] W=new Worm[TOT];

void setup()
{
  size(500, 350);
  noStroke();
  smooth();
  frameRate(30);

  for(int i=0; i < TOT; i++)
	W[i]=new Worm();
}

void mousePressed()
{
  for(int i=0; i < TOT; i++)
	W[i]=new Worm();
}

void draw()
{
  background(0);
  for(int i=NUM-1; i >= 0; i--)
  {
	for(int j=0; j < TOT; j++)
	  W[j].disegna(i);
  }

  for(int j=0; j < TOT; j++)
	W[j].aggiorna(j);

}

class Disco
{
  float xpos, ypos;
  float raggio, raggio2;
  color colore;    

  Disco(float xp, float yp, float ra, color co)
  {
	xpos=xp; 
	ypos=yp;
	raggio=ra; 
	colore=co;    
	raggio2=raggio/2;
  }

  void limita()
  {
	xpos=min(xpos+raggio2, width-1);
	xpos=max(xpos-raggio2, raggio2+1);
	ypos=min(ypos+raggio2, height-1);
	ypos=max(ypos-raggio2, raggio2+1);
  }

  float distanza(Disco D)
  {
	return sqrt((xpos-D.xpos)*(xpos-D.xpos)+(ypos-D.ypos)*(ypos-D.ypos));
  }

  void draw()
  {
	fill(colore);
	ellipse(xpos, ypos, raggio, raggio);
  }
  void draw2()
  {
	fill(color(0, 255, 255));
	ellipse(xpos, ypos, raggio, raggio);
  }

}

// ....................................................................

class Worm
{
  Disco[] D=new Disco[NUM];

  Worm()
  {
	for(int i=0; i < NUM; i++)
	  D[i]=new Disco(width/2, height/2, i+10, color(255-6*i, 255-6*i, 6*i));
  }

  Worm(int x)
  {
	for(int i=0; i < NUM; i++)
	  D[i]=new Disco(DIST*(x+1), (x%2+5)*height/11, i+10, color(255-6*i, 255-6*i, 6*i));
  }

  float distanza(Worm WW)
  {
	return D[0].distanza(WW.D[0]);
  }
  /*  
   void aggiorna()
   {
   D[0].xpos+=random(-DIM, DIM);
   D[0].ypos+=random(-DIM, DIM);
   D[0].limita();
   
   for(int i=1; i < NUM; i++)
   {
   D[i].xpos=(D[i-1].xpos+D[i].xpos)/2;
   D[i].ypos=(D[i-1].ypos+D[i].ypos)/2;
   
   D[i].limita();
   }
   }
   */
  void aggiorna(int x)
  {
	float oldX=D[0].xpos;
	float oldY=D[0].ypos;

	D[0].xpos+=random(-DIM, DIM);
	D[0].ypos+=random(-DIM, DIM);
	D[0].limita();

	boolean OK=true;

	for(int i=0; i < TOT; i++)
	  if(i!=x && distanza(W[i]) < 1.1*D[0].raggio)
	  {
		OK=false;
		accendi();
		W[i].accendi();
		break;
	  }

	if(OK)
	{
	  for(int i=1; i < NUM; i++)
	  {
		D[i].xpos=(D[i-1].xpos+D[i].xpos)/2;
		D[i].ypos=(D[i-1].ypos+D[i].ypos)/2;

		D[i].limita();
	  }
	}  
	else
	{
	  D[0].xpos=oldX;
	  D[0].ypos=oldY;
	}
  }

  void disegna()
  {
	for(int i=NUM-1; i >= 0; i--)
	  D[i].draw();
  }

  void disegna(int x)
  {
	D[x].draw();
  }

  void accendi()
  {
	D[0].draw2();
  }
}