topical media & game development

talk show tell print

#javascript-processing-example-topic-simulate-multipleparticlesystems.htm / htm



  <!DOCTYPE html>
  <html><head>
  <script src="javascript-processing-example-processing.js"></script>
  <script src="javascript-processing-example-init.js"></script>
  <link rel="stylesheet" href="javascript-processing-example-style.css">
  </head><body><h1><a href="http://ejohn.org/blog/processingjs/">Processing.js</a></h1>
  <h2>MultipleParticleSystems</h2>
  
  <p>by Daniel Shiffman.  
  
  Click the mouse to generate a burst of particles
  at mouse location. 
  
  Each burst is one instance of a particle system
  with Particles and CrazyParticles (a subclass of Particle)
  Note use of Inheritance and Polymorphism here.</p>
  
  <p><a href="http://processing.org/learning/topics/multipleparticlesystems.html"><b>Original Processing.org Example:</b> MultipleParticleSystems</a><br>
  <script type="application/processing">
  ArrayList psystems;
  
  void setup() {
    size(200,200);
    frameRate(30);
    colorMode(RGB,255,255,255,100);
    psystems = new ArrayList();
    smooth();
  }
  
  void draw() {
    background(0);
  
    // Cycle through all particle systems, run them and delete old ones
    for (int i = psystems.size()-1; i >= 0; i--) {
      ParticleSystem psys = (ParticleSystem) psystems.get(i);
      psys.run();
      if (psys.dead()) {
        psystems.remove(i);
      }
    }
  
  }
  
  // When the mouse is pressed, add a new particle system
  void mousePressed() {
    psystems.add(new ParticleSystem(int(random(5,25)),new Vector3D(mouseX,mouseY)));
  }
  
  // A subclass of Particle
  
  // Created 2 May 2005
  
  class CrazyParticle extends Particle {
  
    // Just adding one new variable to a CrazyParticle
    // It inherits all other fields from "Particle", and we don't have to retype them!
    float theta;
  
    // The CrazyParticle constructor can call the parent class (super class) constructor
    CrazyParticle(Vector3D l) {
      // "super" means do everything from the constructor in Particle
      super(l);
      // One more line of code to deal with the new variable, theta
      theta = 0.0;
  
    }
  
    // Notice we don't have the method run() here; it is inherited from Particle
  
    // This update() method overrides the parent class update() method
    void update() {
      //super.update();
      // Increment rotation based on horizontal velocity
      float theta_vel = (vel.x * vel.magnitude()) / 10.0f;
      theta += theta_vel;
    }
  
    // Override timer
    void timer() {
      timer -= 0.5;
    }
    
    // Method to display
    void render() {
      // Render the ellipse just like in a regular particle
      //super.render();
  
      // Then add a rotating line
      pushMatrix();
      translate(loc.x,loc.y);
      rotate(theta);
      stroke(255,timer);
      line(0,0,25,0);
      popMatrix();
    }
  }
  
  // A simple Particle class
  
  class Particle {
    Vector3D loc;
    Vector3D vel;
    Vector3D acc;
    float r;
    float timer;
  
    // One constructor
    Particle(Vector3D a, Vector3D v, Vector3D l, float r_) {
      acc = a.copy();
      vel = v.copy();
      loc = l.copy();
      r = r_;
      timer = 100.0;
    }
    
    // Another constructor (the one we are using here)
    Particle(Vector3D l) {
      acc = new Vector3D(0,0.05,0);
      vel = new Vector3D(random(-1,1),random(-2,0),0);
      loc = l.copy();
      r = 10.0;
      timer = 100.0;
    }
  
    void run() {
      update();
      render();
    }
  
    // Method to update location
    void update() {
      vel.add(acc);
      loc.add(vel);
      timer -= 1.0;
    }
  
    // Method to display
    void render() {
      ellipseMode(CENTER);
      noStroke();
      fill(255,timer);
      ellipse(loc.x,loc.y,r,r);
    }
    
    // Is the particle still useful?
    boolean dead() {
      if (timer <= 0.0) {
        return true;
      } else {
        return false;
      }
    }
  }
  
  // A class to describe a group of Particles
  // An ArrayList is used to manage the list of Particles 
  
  class ParticleSystem {
  
    ArrayList particles;    // An arraylist for all the particles
    Vector3D origin;        // An origin point for where particles are birthed
  
    ParticleSystem(int num, Vector3D v) {
      particles = new ArrayList();              // Initialize the arraylist
      origin = v.copy();                        // Store the origin point
      for (int i = 0; i < num; i++) {
        particles.add(new CrazyParticle(origin));    // Add "num" amount of particles to the arraylist
      }
    }
  
    void run() {
      // Cycle through the ArrayList backwards b/c we are deleting
      for (int i = particles.size()-1; i >= 0; i--) {
        Particle p = (Particle) particles.get(i);
        p.run();
        if (p.dead()) {
          particles.remove(i);
        }
      }
    }
  
    void addParticle() {
      particles.add(new Particle(origin));
    }
  
    void addParticle(Particle p) {
      particles.add(p);
    }
  
    // A method to test if the particle system still has particles
    boolean dead() {
      if (particles.isEmpty()) {
        return true;
      } else {
        return false;
      }
    }
  
  }
  
  // Simple Vector3D Class 
  
  public class Vector3D {
    public float x;
    public float y;
    public float z;
  
    Vector3D(float x_, float y_, float z_) {
      x = x_; y = y_; z = z_;
    }
  
    Vector3D(float x_, float y_) {
      x = x_; y = y_; z = 0f;
    }
    
    Vector3D() {
      x = 0f; y = 0f; z = 0f;
    }
  
    void setX(float x_) {
      x = x_;
    }
  
    void setY(float y_) {
      y = y_;
    }
  
    void setZ(float z_) {
      z = z_;
    }
    
    void setXY(float x_, float y_) {
      x = x_;
      y = y_;
    }
    
    void setXYZ(float x_, float y_, float z_) {
      x = x_;
      y = y_;
      z = z_;
    }
  
    void setXYZ(Vector3D v) {
      x = v.x;
      y = v.y;
      z = v.z;
    }
    public float magnitude() {
      return (float) Math.sqrt(x*x + y*y + z*z);
    }
  
    public Vector3D copy() {
      return new Vector3D(x,y,z);
    }
  
    public Vector3D copy(Vector3D v) {
      return new Vector3D(v.x, v.y,v.z);
    }
    
    public void add(Vector3D v) {
      x += v.x;
      y += v.y;
      z += v.z;
    }
  
    public void sub(Vector3D v) {
      x -= v.x;
      y -= v.y;
      z -= v.z;
    }
  
    public void mult(float n) {
      x *= n;
      y *= n;
      z *= n;
    }
  
    public void div(float n) {
      x /= n;
      y /= n;
      z /= n;
    }
  
    public void normalize() {
      float m = magnitude();
      if (m > 0) {
         div(m);
      }
    }
  
    public void limit(float max) {
      if (magnitude() > max) {
        normalize();
        mult(max);
      }
    }
  
    public float heading2D() {
      float angle = (float) Math.atan2(-y, x);
      return -1*angle;
    }
  
    public Vector3D add(Vector3D v1, Vector3D v2) {
      Vector3D v = new Vector3D(v1.x + v2.x,v1.y + v2.y, v1.z + v2.z);
      return v;
    }
  
    public Vector3D sub(Vector3D v1, Vector3D v2) {
      Vector3D v = new Vector3D(v1.x - v2.x,v1.y - v2.y,v1.z - v2.z);
      return v;
    }
  
    public Vector3D div(Vector3D v1, float n) {
      Vector3D v = new Vector3D(v1.x/n,v1.y/n,v1.z/n);
      return v;
    }
  
    public Vector3D mult(Vector3D v1, float n) {
      Vector3D v = new Vector3D(v1.x*n,v1.y*n,v1.z*n);
      return v;
    }
  
    public float distance (Vector3D v1, Vector3D v2) {
      float dx = v1.x - v2.x;
      float dy = v1.y - v2.y;
      float dz = v1.z - v2.z;
      return (float) Math.sqrt(dx*dx + dy*dy + dz*dz);
    }
  
  }
  </script><canvas width="200" height="200"></canvas></p>
  <div style="overflow: hidden; height: 0px; width: 0px;"></div>
  
  <pre><b>// All Examples Written by <a href="http://reas.com/">Casey Reas</a> and <a href="http://benfry.com/">Ben Fry</a>
  // unless otherwise stated.</b>
  ArrayList psystems;
  
  void setup() {
    size(200,200);
    frameRate(30);
    colorMode(RGB,255,255,255,100);
    psystems = new ArrayList();
    smooth();
  }
  
  void draw() {
    background(0);
  
    // Cycle through all particle systems, run them and delete old ones
    for (int i = psystems.size()-1; i &gt;= 0; i--) {
      ParticleSystem psys = (ParticleSystem) psystems.get(i);
      psys.run();
      if (psys.dead()) {
        psystems.remove(i);
      }
    }
  
  }
  
  // When the mouse is pressed, add a new particle system
  void mousePressed() {
    psystems.add(new ParticleSystem(int(random(5,25)),new Vector3D(mouseX,mouseY)));
  }
  
  // A subclass of Particle
  
  // Created 2 May 2005
  
  class CrazyParticle extends Particle {
  
    // Just adding one new variable to a CrazyParticle
    // It inherits all other fields from "Particle", and we don't have to retype them!
    float theta;
  
    // The CrazyParticle constructor can call the parent class (super class) constructor
    CrazyParticle(Vector3D l) {
      // "super" means do everything from the constructor in Particle
      super(l);
      // One more line of code to deal with the new variable, theta
      theta = 0.0;
  
    }
  
    // Notice we don't have the method run() here; it is inherited from Particle
  
    // This update() method overrides the parent class update() method
    void update() {
      super.update();
      // Increment rotation based on horizontal velocity
      float theta_vel = (vel.x * vel.magnitude()) / 10.0f;
      theta += theta_vel;
    }
  
    // Override timer
    void timer() {
      timer -= 0.5;
    }
    
    // Method to display
    void render() {
      // Render the ellipse just like in a regular particle
      super.render();
  
      // Then add a rotating line
      pushMatrix();
      translate(loc.x,loc.y);
      rotate(theta);
      stroke(255,timer);
      line(0,0,25,0);
      popMatrix();
    }
  }
  
  // A simple Particle class
  
  class Particle {
    Vector3D loc;
    Vector3D vel;
    Vector3D acc;
    float r;
    float timer;
  
    // One constructor
    Particle(Vector3D a, Vector3D v, Vector3D l, float r_) {
      acc = a.copy();
      vel = v.copy();
      loc = l.copy();
      r = r_;
      timer = 100.0;
    }
    
    // Another constructor (the one we are using here)
    Particle(Vector3D l) {
      acc = new Vector3D(0,0.05,0);
      vel = new Vector3D(random(-1,1),random(-2,0),0);
      loc = l.copy();
      r = 10.0;
      timer = 100.0;
    }
  
    void run() {
      update();
      render();
    }
  
    // Method to update location
    void update() {
      vel.add(acc);
      loc.add(vel);
      timer -= 1.0;
    }
  
    // Method to display
    void render() {
      ellipseMode(CENTER);
      noStroke();
      fill(255,timer);
      ellipse(loc.x,loc.y,r,r);
    }
    
    // Is the particle still useful?
    boolean dead() {
      if (timer &lt;= 0.0) {
        return true;
      } else {
        return false;
      }
    }
  }
  
  // A class to describe a group of Particles
  // An ArrayList is used to manage the list of Particles 
  
  class ParticleSystem {
  
    ArrayList particles;    // An arraylist for all the particles
    Vector3D origin;        // An origin point for where particles are birthed
  
    ParticleSystem(int num, Vector3D v) {
      particles = new ArrayList();              // Initialize the arraylist
      origin = v.copy();                        // Store the origin point
      for (int i = 0; i &lt; num; i++) {
        particles.add(new CrazyParticle(origin));    // Add "num" amount of particles to the arraylist
      }
    }
  
    void run() {
      // Cycle through the ArrayList backwards b/c we are deleting
      for (int i = particles.size()-1; i &gt;= 0; i--) {
        Particle p = (Particle) particles.get(i);
        p.run();
        if (p.dead()) {
          particles.remove(i);
        }
      }
    }
  
    void addParticle() {
      particles.add(new Particle(origin));
    }
  
    void addParticle(Particle p) {
      particles.add(p);
    }
  
    // A method to test if the particle system still has particles
    boolean dead() {
      if (particles.isEmpty()) {
        return true;
      } else {
        return false;
      }
    }
  
  }
  
  // Simple Vector3D Class 
  
  public class Vector3D {
    public float x;
    public float y;
    public float z;
  
    Vector3D(float x_, float y_, float z_) {
      x = x_; y = y_; z = z_;
    }
  
    Vector3D(float x_, float y_) {
      x = x_; y = y_; z = 0f;
    }
    
    Vector3D() {
      x = 0f; y = 0f; z = 0f;
    }
  
    void setX(float x_) {
      x = x_;
    }
  
    void setY(float y_) {
      y = y_;
    }
  
    void setZ(float z_) {
      z = z_;
    }
    
    void setXY(float x_, float y_) {
      x = x_;
      y = y_;
    }
    
    void setXYZ(float x_, float y_, float z_) {
      x = x_;
      y = y_;
      z = z_;
    }
  
    void setXYZ(Vector3D v) {
      x = v.x;
      y = v.y;
      z = v.z;
    }
    public float magnitude() {
      return (float) Math.sqrt(x*x + y*y + z*z);
    }
  
    public Vector3D copy() {
      return new Vector3D(x,y,z);
    }
  
    public Vector3D copy(Vector3D v) {
      return new Vector3D(v.x, v.y,v.z);
    }
    
    public void add(Vector3D v) {
      x += v.x;
      y += v.y;
      z += v.z;
    }
  
    public void sub(Vector3D v) {
      x -= v.x;
      y -= v.y;
      z -= v.z;
    }
  
    public void mult(float n) {
      x *= n;
      y *= n;
      z *= n;
    }
  
    public void div(float n) {
      x /= n;
      y /= n;
      z /= n;
    }
  
    public void normalize() {
      float m = magnitude();
      if (m &gt; 0) {
         div(m);
      }
    }
  
    public void limit(float max) {
      if (magnitude() &gt; max) {
        normalize();
        mult(max);
      }
    }
  
    public float heading2D() {
      float angle = (float) Math.atan2(-y, x);
      return -1*angle;
    }
  
    public Vector3D add(Vector3D v1, Vector3D v2) {
      Vector3D v = new Vector3D(v1.x + v2.x,v1.y + v2.y, v1.z + v2.z);
      return v;
    }
  
    public Vector3D sub(Vector3D v1, Vector3D v2) {
      Vector3D v = new Vector3D(v1.x - v2.x,v1.y - v2.y,v1.z - v2.z);
      return v;
    }
  
    public Vector3D div(Vector3D v1, float n) {
      Vector3D v = new Vector3D(v1.x/n,v1.y/n,v1.z/n);
      return v;
    }
  
    public Vector3D mult(Vector3D v1, float n) {
      Vector3D v = new Vector3D(v1.x*n,v1.y*n,v1.z*n);
      return v;
    }
  
    public float distance (Vector3D v1, Vector3D v2) {
      float dx = v1.x - v2.x;
      float dy = v1.y - v2.y;
      float dz = v1.z - v2.z;
      return (float) Math.sqrt(dx*dx + dy*dy + dz*dz);
    }
  
  }</pre>
  
  </body></html>
  


(C) Æliens 20/2/2008

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.