• fullscreen
  • Food.pde
  • Leg.pde
  • Ripple.pde
  • octopus5TextWithRipple_3d.pde
  • class Food {
      PVector pos,vel;
      float quantity,a,b,c,angle,BoWa,speed;
      String textFood;
     char[] letters; 
      boolean consumed=false;
      int g,co;
      
      float d0=10;
    float d1=sqrt(sq(d0)+sq(3.3));
    float d2=sqrt(sq(2*d0)+sq(3.3));
    float d3=sqrt(sq(3*d0)+sq(2));
    float an1=atan2(3.3,d1);
    float an2=atan2(3.3,d2);
    float an3=atan2(2,d3);
    
    
      Food(String _text, float _x,float _y,float _z) {
        pos = new PVector(_x,_y,_z);
        textFood = _text;
        quantity =(float)textFood.length()/2;
        letters = textFood.toCharArray();
        
        pos = new PVector(random(width),random(height),random(-500,500));
        vel = new PVector();
        vel.normalize();
        
        co = int(random(20,70));
    
          a = random(0,1);
          b = random(1,10);
      }
    
      void display() {
       if (!consumed) {
       
        move();
        ff.pushMatrix();
        ff.noStroke();
        ff.fill(255,100);
         ff.translate(pos.x,pos.y,pos.z);
         rotateY(atan2(-vel.z,vel.x)); 
         rotateZ(acos(vel.y/vel.mag()));
         ff.textFont(font);
         ff.textAlign(CENTER);
         //ff.textMode(SCREEN);
         ff.textSize(10);
         drawBody();
         //ff.hint(ENABLE_ACCURATE_TEXTURES); 
         //ff.text(textFood,0,-6);
         //ff.box(quantity);
        ff.popMatrix();
       }
      }
      
     void move() {
      // movement
      a += .005;
      b += .035;
      if (random(10)>9.5)  { 
      speed = 5*noise(b)/random(0.1,5);
      //if (random(10)>7)
      
     
      } else {
      speed = noise(b)*5;
      }
     vel.add(random(-0.05,0.05),random(-0.05,0.05),random(-0.05,0.05)); 
     vel.normalize(); 
     vel.mult(speed);
     pos.add(vel);
    
      //boundary
      if (pos.x>width+50) pos.x=-50;
      if (pos.x<-50) pos.x= width+50;
      if (pos.y>height+50) pos.y =-50;
      if (pos.y<-50) pos.y =height+50;
      if (pos.z>500) pos.z =-500;
      if (pos.z<-500) pos.z =500;
    
      //Fish wave the body according to its speed
      c += 0.1*speed;
      BoWa=sin(c)*PI/15;
    }
    
    void drawBody() {
      
      
      for (g=0;g<letters.length; g++) {
        ff.translate(6,0);
        //ff.translate(textWidth(letters[g]),0);
        ff.rotate(BoWa/8);
        ff.textSize(8);
        ff.text(letters[g],0,0);
      }
    } 
      
      
      
    }
    
    
    //every leg is a strand of three lines
    
    class Leg {
      int jointsNum = 10;
      int counter,life;
      PVector[][] joints = new PVector[jointsNum][3];
      PVector initia,driver,target,ankle;
      float driverAngle,randomness,rotation,angle,O,Oangle;
      float speed =100;
      float[] armLength= new float[3];
    
      Leg(float xin, float yin, float zin, float _rotation, float _randomness, int _partNum, int _counter) {
        for (int i=0; i<jointsNum; i++) {
          for (int g= 0; g<3;g++) {
          joints[i][g] = new PVector(0,0,0);
          }
        }
        for (int g= 0; g<3;g++) {
          armLength[g] = random(9,12);
        }
        counter= _counter;
        angle = counter*TWO_PI/_partNum;
        
        initia = new PVector(xin,yin,zin);
        driver = new PVector(xin,yin,zin);
        target = new PVector(xin,yin,zin);
        rotation = _rotation;
        randomness = _randomness;  
      }
    
      void drawLeg(PVector _target, float _speed) {
        //pushMatrix();
    
        //rotate(rotation);
        //driver.add(noise(-0.5,0.5),noise(-0.5,0.5),noise(-0.5,0.5));
    
        target= _target;
        speed = _speed;
        //Oangle+=0.1;
        //O=6*cos(Oangle)*cos(Oangle);
        /*       
        initia.x += (target.x-initia.x)/100;
        initia.y += (target.y-initia.y)/100;
        initia.z += (target.z-initia.z)/100;
       */
        //if (random(10)>9.8) target.set(random(width),random(height),random(800));
    
        driver.x += (target.x-driver.x)/speed;
        driver.y += (target.y-driver.y)/speed;
        driver.z += (target.z-driver.z)/speed;
        //float heading = PVector.angleBetween(driver,initia);
        
        initia=driver.get();
        //O--;
        //if (O<2) O=10;
        if (PVector.dist(driver,target)>30) {
        Oangle+=0.1;
        O=0.8*cos(Oangle)+0.2;
        driver.add(O*cos(angle),O*sin(angle),0);
        } 
    
        //driverAngle += noise(randomness);
        //driver.add(5*cos(driverAngle),5*sin(driverAngle),0);
     for (int g= 0; g<3;g++) {
        joints[0][g]=driver.get();
        
     }
    for (int g= 0; g<3;g++) {
      
        ff.noFill();
       //stroke(255, 102, 180);
       //strokeWeight(1);
       /*
       line(initia.x, initia.y, initia.z, 
            joints[0][g].x,joints[0][g].y,joints[0][g].z);
       line(joints[0][g].x,joints[0][g].y,joints[0][g].z, 
            joints[0][g].x,joints[0][g].y+20,joints[0][g].z);
            */
       //stroke(0, 0, 0);
       ff.pushMatrix();
       
       ff.stroke(255,10);
    
       ff.point(initia.x, initia.y, initia.z);
       //point(joints[0][g].x,joints[0][g].y,joints[0][g].z);
       ff.stroke(255,40);
         ff.line(initia.x, initia.y, initia.z, joints[0][g].x,joints[0][g].y,joints[0][g].z);
            /*
       translate(initia.x, initia.y, initia.z);
       rotateZ(angle);
       bezier(0, 0,  30, 
              -10,  -30, 30,  
              O*cos(angle)+10,O*sin(angle)+30,0,
              O*cos(angle),O*sin(angle),0);
              */
       /*
       bezier(initia.x, initia.y, initia.z, 
            initia.x+100, initia.y+100, initia.z,
            joints[0][g].x-100,joints[0][g].y-30,joints[0][g].z, 
            joints[0][g].x,joints[0][g].y,joints[0][g].z);
       */
       ff.popMatrix();
        ff.beginShape();
        ff.noFill();
        ff.stroke(255,10);
        ff.strokeWeight(2);
        //point(joints[0].x,joints[0].y,joints[0].z);
     
        ff.curveVertex(joints[0][g].x,joints[0][g].y,joints[0][g].z);
         
        //vertex(joints[0].x,joints[0].y,joints[0].z);
    
    
        for (int i=1; i<jointsNum; i++) {
    
          float angleZ = atan2(joints[i][g].y-joints[i-1][g].y,joints[i][g].x-joints[i-1][g].x);
          float angleY = atan2(joints[i][g].z-joints[i-1][g].z,joints[i][g].x-joints[i-1][g].x);
          float angleX = atan2(joints[i][g].y-joints[i-1][g].y,joints[i][g].z-joints[i-1][g].z);
    
          joints[i][g].x = joints[i-1][g].x + armLength[g]*cos(angleZ);
          joints[i][g].y = joints[i-1][g].y + armLength[g]*sin(angleZ);
          joints[i][g].z = joints[i-1][g].z + armLength[g]*cos(angleX);
    
          
          //line(joints[i].x,joints[i].y,joints[i].z,joints[i-1].x,joints[i-1].y,joints[i-1].z);
          //point(joints[i].x+random(-i*0.3,i*0.3),joints[i].y+random(-i*0.3,i*0.3),joints[i].z);
          //if (random(1)>0.2)
          ff.curveVertex(joints[i][g].x+random(-i*0.3,i*0.3),joints[i][g].y+random(-i*0.3,i*0.3),joints[i][g].z);
           }
     
        ff.endShape();
    }
      }
     
    }
    
    
    
    
    
    
    
    
    
    
    class Ripple {
      int i, a, b;
      int oldind, newind, mapind;
      short ripplemap[]; // the height map
      int col[]; // the actual pixels
      int riprad;
      int rwidth, rheight;
      int ttexture[];
      int ssize;
    
      Ripple() {
        // constructor
        riprad = 3;
        rwidth = width >> 1;
        rheight = height >> 1;
        ssize = width * (height + 2) * 2;
        ripplemap = new short[ssize];
        col = new int[width * height];
        ttexture = new int[width * height];
        oldind = width;
        newind = width * (height + 3);
      }
    
    
    
      void newframe() {
        // update the height map and the image
        i = oldind;
        oldind = newind;
        newind = i;
    
        i = 0;
        mapind = oldind;
        for (int y = 0; y < height; y++) {
          for (int x = 0; x < width; x++) {
            short data = (short)((ripplemap[mapind - width] + ripplemap[mapind + width] + 
              ripplemap[mapind - 1] + ripplemap[mapind + 1]) >> 1);
            data -= ripplemap[newind + i];
            data -= data >> 5;
            if (x == 0 || y == 0) // avoid the wraparound effect
              ripplemap[newind + i] = 0;
            else
              ripplemap[newind + i] = data;
    
            // where data = 0 then still, where data > 0 then wave
            data = (short)(1024 - data);
    
            // offsets
            a = ((x - rwidth) * data / 1024) + rwidth;
            b = ((y - rheight) * data / 1024) + rheight;
    
            //bounds check
            if (a >= width) 
              a = width - 1;
            if (a < 0) 
              a = 0;
            if (b >= height) 
              b = height-1;
            if (b < 0) 
              b=0;
    
            col[i] = ff.pixels[a + (b * width)];
            mapind++;
            i++;
          }
        }
      }
    }
    void mouseDragged() {
    hit(mouseX,mouseY);
    foodNum++;
    food[foodNum-1] =new Food("New food!!!", mouseX, mouseY,random(-500,500));
    }
    
    void hit(float _foodX, float _foodY) {
      int foodX =(int)_foodX;
      int foodY = (int)_foodY;
      for (int j = foodY - ripple.riprad; j < foodY + ripple.riprad; j++) {
        for (int k = foodX - ripple.riprad; k < foodX + ripple.riprad; k++) {
          if (j >= 0 && j < height && k>= 0 && k < width) {
            ripple.ripplemap[ripple.oldind + (j * width) + k] += 512;
          }
        }
      }
    }
    
    //import processing.opengl.*;
    
    int legNum=6;
    int partNum=18;
    Leg[][] leg = new Leg[legNum][partNum];
    PVector[] Target = new PVector[legNum];
    float[] speed = new float[legNum];
    
    PFont font;
    
    Food[] food = new Food[1000];
    int foodNum = 90;
    int foodCounter;
    
    PGraphics ff;
    Ripple ripple;
    
    void setup() {
      size(800,600,P3D);
      ff= createGraphics(width,height,P3D);
      ff.smooth();
      ff.fill(255, 100);
      
      font = createFont("arial",100,true);
      
      ff.textFont(font);
      ff.textAlign(CENTER);
    
      //initiate food
      for (int i=0; i<foodNum; i++) {
        food[i] = new Food("This is food",random(width),random(height),random(-500,500));
      }
    
      //initiate the creature
      for (int i=0; i<legNum; i++) {
        float x = random(width);
        float y = random(height);
        for (int g=0; g<partNum;g++){
          float angle = g*TWO_PI/partNum;
          leg[i][g]= new Leg(x,y,300,i*TWO_PI/legNum,0.1+i*0.5, partNum, g);  
          //leg[i][g]= new Leg(x+30*cos(angle),y+30*sin(angle),300,i*TWO_PI/legNum,0.1+i*0.5, partNum, g); 
          Target[i] = new PVector();
          speed[i] = 100;
        }
      }
      
      ripple = new Ripple();
      frameRate(30);
    
    
    }
    
    void draw() {
      ff.beginDraw();
      ff.background(0);
      //background(0);
      
      //display food
      foodCounter=0;
      for (int i=0;i<food.length; i++) {
        if (food[i]!= null && !food[i].consumed) {
          food[i].display();
          foodCounter++;
        } 
      }
      println("There is "+foodCounter+" pieces of food left.");
      
      //display creature
      for (int i=0; i<legNum; i++) {
        float randomNumber =random(10);
        if (randomNumber>9.8 && randomNumber <=9.9) Target[i].set(random(width),random(height),random(-800,800));
        if (randomNumber>9.9) {
          int iWantFood = (int)random(foodNum);
          if (food[i]!= null && !food[i].consumed)
            Target[i].set(food[iWantFood].pos.x,food[iWantFood].pos.y,food[iWantFood].pos.z);  
        }
        speed[i] +=0.05;
        for (int g=0; g<partNum;g++){    
          leg[i][g].drawLeg(Target[i],speed[i]);
        }
    
        //eat!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        for (int j =0; j<foodNum; j++) {
          float d = PVector.dist(food[j].pos,leg[i][0].initia);
          if (d<50) {
            food[j].consumed =true;
            leg[i][0].life++;
            hit(food[j].pos.x,food[j].pos.y);
            if(speed[i]>21) speed[i] -=10;
          }
        }
      }
    
    
      ff.endDraw();
      loadPixels();
    
      ff.loadPixels();
      for (int loc = 0; loc < width * height; loc++) {
        pixels[loc] = ripple.col[loc];
      }
      updatePixels();
      ripple.newframe();
    }
    
    void cameraLight() {
      //camera(width/2,height/2,850, 450,0,-30, 0,0,-0.5);
      /* 
       // Orange point light on the right
       pointLight(255, 255, 255, // Color
       200, -150, 0); // Position
       
       // Blue directional light from the left
       directionalLight(0, 102, 255, // Color
       1, 0, 0); // The x-, y-, z-axis direction
       
       // Yellow spotlight from the front
       spotLight(255, 255, 109, // Color
       0, 40, 200, // Position
       0, -0.5, -0.5, // Direction
       PI / 2, 2); // Angle, concentration
       */
    }
    
    
    

    code

    tweaks (0)

    about this sketch

    This sketch is running as Java applet, exported from Processing.

    license

    advertisement

    shaocong zhou

    agentJelly

    Add to Faves Me Likey@!
    You must login/register to add this sketch to your favorites.

    Use Ripple class from Dario Ghersi.

    http://www.openprocessing.org/visuals/?visualID=7715

    You need to login/register to comment.