Site3D.java

Java source for Green liquid goo, 334 lines. Raw file

import java.awt.image.*;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Event;
import java.awt.Image;
import java.awt.Font;
import java.util.Vector;  //  http://java.sun.com/products/jdk/1.1/docs/api/java.util.Vector.html



//---- MAIN CLASS ------------------------------------------------------------//

public class Site3D extends tinyptc
{
  //---- DATA

  //- Buffers

  int width, height, size;
  
  int[] back;
  int[] buf;
  int[] pot;

  //- Mouse

  int mouse_x = 0, mouse_y = 0;
  boolean mouse_click = false;

  //- Particle system

  int num_particles = 1300;

  double[] particle_x, particle_y, particle_vx, particle_vy;
  boolean[] particle_active;
  double particle_force_x, particle_force_y, particle_friction;



  //---- CODE

  //---- fillRect

  public void fillRect(int[] buf, int x1, int y1, int x2, int y2, int col)
  {
    int i, j;
    for(j=y1; j<y2; j++) for(i=x1; i<x2; i++) buf[i+width*j] = col;
  }



  //---- getPot
  
  public int getPot(double x, double y)
  {
    int xx = (int)x, yy = (int)y;
    if(xx < 0 || xx >= width || yy < 0 || yy >= height) return 0;
    return pot[xx+width*yy];
  }



  //---- drawParticle
  
  public void drawParticle(int[] buf, double px, double py)
  {
    int i, j;
    double d;
    
    int x = (int)px - 6;
    int y = (int)py - 6;

    for(j=y; j<=y+12; j++)
    {
      for(i=x; i<=x+12; i++)
      {
        if(i >= 0 && i < width && j >= 0 && j < height)
        {
          d = (i-px)*(i-px) + (j-py)*(j-py);
          d /= 25;
          d = 1-d;
          if(d < 0) d = 0;
          if(d > 1) d = 1;

//          buf[i+width*j] = (int)(buf[i+width*j] * (1-d) + 255 * d);
          buf[i+width*j] += (int)(d*512);
        }
      }
    }

  }



  //---- calcForce
  
  public void calcForce(int[] buf, double px, double py)
  {
    int i, j;
    double d;

    particle_force_x = 0;
    particle_force_y = 0;
    particle_friction = 0.99;
    
    double f;

    int x = (int)px - 11;
    int y = (int)py - 11;

    for(j=y; j<=y+22; j++)
    {
      for(i=x; i<=x+22; i++)
      {
        if(i >= 0 && i < width && j >= 0 && j < height)
        {
          d = (i-px)*(i-px) + (j-py)*(j-py);
          d /= 100;
          d = 1-d;
          if(d < 0) d = 0;
          if(d > 1) d = 1;

          //- Get value mixed with force
          
          f = buf[i+width*j] - 5100;
          if(f < 0) f =- f;
          
          if(f < 0) f = 0;
          if(f > 8000) f = 8000;
          
          f *= d;
          
          particle_friction -= 0.00000001 * f * d;

          particle_force_x -= 0.000016 * f * d * (i-px);
          particle_force_y -= 0.000016 * f * d * (j-py);
        }
      }
    }

//    particle_friction *= 0.0000005;
//    particle_friction = 1-particle_friction;

    if(particle_friction < 0.9) particle_friction = 0.9;

  }



  //---- main

  public void main(int width, int height)
  {
    int i, j;
    int x, y;

    int frame = 0;

    //- Set up variables
    
    this.width = width;
    this.height = height;

    size = width * height;
    back = new int[size];
    buf = new int[size];
    pot = new int[size];

    //- Set up particle system

    particle_x = new double[num_particles];
    particle_y = new double[num_particles];
    particle_vx = new double[num_particles];
    particle_vy = new double[num_particles];
    particle_active = new boolean[num_particles];

    for(i=0; i<num_particles; i++) particle_active[i] = false;

    //- Create background
    
    for(i=size-1; i>=0; i--) back[i] = 0;
    fillRect(back, 20, 100, 100, 130, 0x7FFFFFFF);
    fillRect(back, 50, 190, 190, 220, 0x7FFFFFFF);

    //- Animation loop

    while (true)
    {
      //- Add a new particle if necessary

      if(mouse_click)
      {
        for(j=0; j<3; j++)
        {
          for(i=0; i<num_particles && particle_active[i]; i++);

          if(i < num_particles)
          {
            particle_active[i] = true;
          
            particle_x[i] = mouse_x - 2 + 4*(((j*6172+frame*frame*11714)%12379)/12379.0);
            particle_y[i] = mouse_y - 2 + 4*(((j*9899+frame*frame*8394)%17121)/17121.0);
            particle_vx[i] = 0;
            particle_vy[i] = 0;
          }
        }
      }

      //- Move particles

      for(i=0; i<num_particles; i++) if(particle_active[i])
      {
        //- Gravity

        particle_vy[i] += 0.5;

        //- Update velocity

/*
        if(getPot(particle_x[i] + particle_vx[i], particle_y[i] + particle_vy[i]) > 1024)
        {
          particle_vy[i] = 0;
        }
*/

        calcForce(pot, particle_x[i], particle_y[i]);
        
        //- Limit acceleration
/*
        if(particle_force_x < -3) particle_force_x = -3;
        if(particle_force_x >  3) particle_force_x =  3;
        if(particle_force_y < -3) particle_force_y = -3;
        if(particle_force_y >  3) particle_force_y =  3;
*/
        particle_vx[i] += particle_force_x;
        particle_vy[i] += particle_force_y;

        //- Apply friction

        particle_vx[i] *= particle_friction;
        particle_vy[i] *= particle_friction;

/*
        if(particle_vx[i] < -5) particle_vx[i] = -5;
        if(particle_vx[i] >  5) particle_vx[i] =  5;
        if(particle_vy[i] < -5) particle_vy[i] = -5;
        if(particle_vy[i] >  5) particle_vy[i] =  5;
*/
        //- Move particle

        particle_x[i] += 0.02 * (particle_vx[i] - 0.005 + 0.01*(((frame*frame*3171)%5237)/5237.0));
        particle_y[i] += 0.02 * (particle_vy[i] - 0.005 + 0.01*(((frame*frame*4187)%5771)/5771.0));

        //- Remove particle if necessary
        
        if(particle_y[i] >= 256) particle_active[i] = false;
      }

      //- Clear buffers
      
      for(i=size-1; i>=0; i--) buf[i] = back[i];
      for(i=size-1; i>=0; i--) pot[i] = back[i];

      //- Render particles

      for(i=0; i<num_particles; i++) if(particle_active[i])
      {
        drawParticle(pot, particle_x[i], particle_y[i]);
      }

      //- Render water
      
      for(i=0; i<size; i++)
      {
        if(pot[i] > 800) buf[i] |= 0x00FF00;
      }
      
      //- Display frame

      update(buf);
      frame++;
    }
  }



  //---- mouseMove

  public boolean mouseMove(Event e, int x, int y)
  {
    mouse_x = x;
    mouse_y = y;
    return true;
  }



  //---- mouseDrag

  public boolean mouseDrag(Event e, int x, int y)
  {
    mouse_x = x;
    mouse_y = y;
    return true;
  }



  //---- mouseDown

  public boolean mouseDown(Event e, int x, int y)
  {
    mouse_click = true;
    return true;
  }



  //---- mouseUp

  public boolean mouseUp(Event e, int x, int y)
  {
    mouse_click = false;
    return true;
  }

}



//---- end of code -----------------------------------------------------------//