• fullscreen
  • gravballs4upload.pde
  • float MAX_METABALLS = 8;
    float FIRST_THRESHOLD = 2.2;
    float SECOND_THRESHOLD = 1;
    
    color lightblue = color(181,213,227);
    color purpleshift = color(197, 196, 214);
    color pink = color(232, 166, 195);
    color color1, color2, color3;
    
    int sketchSize = 200;
    float center = sketchSize/2;
    float interval = 100;
    float POWER_THRESHOLD = 1600;
    boolean makeBalls = true;
    
    ArrayList metaBalls;
    float frameskip = 3;
    float framecounter = frameskip;
    
    void setup()
    {
      color1 = pink;
      color2 = purpleshift;
      color3 = lightblue;
    
      size(sketchSize,sketchSize);
      colorMode(RGB);
      //new array of MetaBalls
      metaBalls = new ArrayList();
    }
    
    void mouseClicked()
    {
      //new metaball at mouseX, mouseY
      //add to array new MetaBall(mouseX, mouseY, whatever power, x vel, y vel, x acc, y acc)
      metaBalls.add(new MetaBall(mouseX, mouseY, 150, 0, 0, 0, 0));
    }
    
    void keyPressed() 
    { 
      if ((keyPressed == true) && (key == ']'))
      { 
        POWER_THRESHOLD = POWER_THRESHOLD + 100;
      } 
      
        if ((keyPressed == true) && (key == '[')) 
      { 
        POWER_THRESHOLD = POWER_THRESHOLD - 100;
      } 
    }
    
    void draw()
    { 
      background(color1);
    
      float sum; // sum of metaball powers
    
      interval = interval - 1;
    
      if(metaBalls.size() == 0)
      {
        makeBalls = true;
      }
    
      if( (metaBalls.size() < MAX_METABALLS) && (makeBalls == true))
      {
        if(interval < 0)
        {
          interval = 100;
          metaBalls.add(new MetaBall(random(width), random(height), 1.1, 0, 0, 0, 0));
        }
      } 
    
      if(metaBalls.size() >= MAX_METABALLS)
      { 
        makeBalls = false;
      }
    
    
    
      for(int y = 0; y < height; y++)
      {
        for(int x = 0; x < width; x++)
        {
          sum = 0;
    
          //calculate power per pixel
          for(int i = 0; i < metaBalls.size(); i++)
          {
            MetaBall mBall = (MetaBall) metaBalls.get(i);
            sum = sum + mBall.equation(x,y);
          }
    
          if(sum < FIRST_THRESHOLD && sum > SECOND_THRESHOLD)
            set(x, y, color2);
    
          //draw pixels if high enough
          if(sum >= FIRST_THRESHOLD)
            set(x, y, color3);
        }
      }
    
      //move metaballs
      for(int i = 0; i < metaBalls.size(); i++)
      {
        MetaBall mBall = (MetaBall) metaBalls.get(i);
        mBall.move();
        mBall.shrink(.995);
        //gravitate towards center, also towards other balls
        mBall.gravitate(center, center, 200);
        for(int j = 0; j < metaBalls.size(); j++)
        {
          MetaBall gravBall = (MetaBall) metaBalls.get(j);
          if ((gravBall.xpos != mBall.xpos) && (gravBall.ypos != mBall.ypos))
            mBall.gravitate(gravBall.xpos, gravBall.ypos, 5);
        }
    
        if(mBall.power < 5 && !(mBall.baby))
          metaBalls.remove(i);
    
        if(mBall.power > -5 && mBall.power < 0 && !(mBall.baby))
          metaBalls.remove(i);
    
        if(mBall.baby)
          mBall.grow(1.05);
      }
    }
    
    
    class MetaBall
    {
      //declare instance vars
      float xpos, ypos, power;
      PVector velocity;
      PVector acceleration;
      boolean baby; //if baby = 1, still growing...
    
      //init
      MetaBall (float x, float y, float p, float xv, float yv, float xa, float ya) 
      {
        xpos = x;
        ypos = y;
        power = p;
    
        velocity = new PVector(xv, yv);
        acceleration = new PVector(xa, ya);
        baby = true;
      }
    
      //equation of metaball
      float equation(float x, float y)
      {
        return( power / (sq(xpos-x) + sq(ypos-y)) );
      }
    
      void move()
      {
        xpos = xpos + velocity.x;
        ypos = ypos + velocity.y;
      } 
    
      void gravitate(float xcenter, float ycenter, float mass)
      {
        int xsignadj = 1;
        int ysignadj = 1;
    
        if(xpos >= xcenter)
          xsignadj = -1;
    
        if(ypos >= xcenter)
          ysignadj = -1;
    
    
        float radius = dist(xpos, ypos, xcenter, ycenter);
        PVector gravity = new PVector(xsignadj/sq(radius), ysignadj/sq(radius));
    
        gravity.div(10/mass); //adjust for gravitational constant
    
        //slow down near the center, due to granularity of draw()
        gravity.limit(.001);
    
        acceleration.add(gravity);
        
        //add drag
        acceleration.mult(.9);
        velocity.add(acceleration);
      }
    
      void shrink(float rate)
      {
        power = power*rate;
      }
    
      void grow(float rate)
      {
        power = power*rate;
    
        if(power > POWER_THRESHOLD)
          baby = false;
      }
    
    }
    
    
    

    code

    tweaks (0)

    about this sketch

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

    license

    advertisement

    Dan Lipert

    Gravballs

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

    Some simple demoscene style metaballs, with gravity and a center attractor. Maybe some sloppy code... use ] and [ to change the power of the metaballs, and click to add a metaball manually. They grow to the threshold size, and then slowly shrink until all are gone, and then it respawns them again.

    You need to login/register to comment.