int res = 110;
float step;
float [] ropeP = new float[res];
float [] ropeV = new float[res];
 
Vector surfers = new Vector();
 
void setup(){
 
size(550,500);
size(550,500);
step = width/res;
 
for (int i = 0; i < res; i++){
ropeP[i] = 0;
ropeV[i] = 0;
}
 
for (int i =0; i < 5; i++){
surfers.add(new Surfer(random(0,width)));
}
}
 
 
void draw(){
background(200,200,255);
fill(0,0,100);
translate(0,height/2);
ropeP[res-1] = ropeP[res-2];
for (int i = 1; i < res-1; i++){
ropeV[i] += ((ropeP[i-1] - ropeP[i]) + (ropeP[i+1] - ropeP[i]))/1.05;
ropeV[i] -= ropeP[i]/100.f;
ropeV[i] /= 1.03f;
}
 
for (int i = 1; i < res-1; i++){
ropeP[i] += ropeV[i];
}
beginShape();
for (int i =0; i < res; i++){
vertex(step*i,ropeP[i]);
}
vertex(width,ropeP[res-1]);
vertex(width,height);
vertex(0,height);
endShape();
 
Surfer bob;
for (int i =0; i < surfers.size(); i++){
bob = (Surfer)surfers.elementAt(i);
bob.draw();
}
 
}
 
void mouseDragged(){
int where = mouseX/(width/res);
if (mouseX > 2 && mouseX < width - 10){
ropeV[where] += (mouseY-height/2)/10;
ropeV[where-1] += (mouseY-height/2)/20;
ropeV[where+1] += (mouseY-height/2)/20;
}
}
 
void keyPressed(){
if (key == ' '){
surfers.add(new Surfer(random(0,width)));
}
 
}
 
 
class Surfer{
 
float x,dx,y,dy;
 
Surfer(float x){
this.x = x;
dx = 0;
this.y = -10;
}
 
void draw(){
float ang = 0;
if (x/step > 0 && x/step < res - 2){
float waterHeight = ropeP[(int)(x/step)];
if (y < waterHeight){
dy += .1;
}
if (y > waterHeight){
y = waterHeight;
dy = (waterHeight - y);
}
y += dy;
 
if (abs(y - waterHeight) < 5 ){
ang = (ropeP[(int)(x/step)] - ropeP[(int)(x/step+2)])/50;
dx -= ang;
}
}
if (x > width-10) dx = 2;
dx *= .99;
x += dx;
stroke(0);
fill(255);
pushMatrix();
translate(x,y-20);
 
rotate(-ang*2);
line(0,0,0,15);
line(0,15,-5,20);
line(0,15,5,20);
line(-5,7,5,7);
ellipse(0,0,7,7);
line(-1,1,1,1);
line(-1,-1,-1,-1);
line(1,-1,1,-1);
fill(200,200,0);
ellipse(0,20,30,2);
popMatrix();
 
}
 
}