If you're seeing this message, it means we're having trouble loading external resources on our website.

If you're behind a web filter, please make sure that the domains *.kastatic.org and *.kasandbox.org are unblocked.

Main content

Systems of particle systems

Let’s review for a moment where we are. We know how to talk about an individual Particle object. We also know how to talk about a system of Particle objects, and this we call a “particle system.” And we’ve defined a particle system as a collection of independent objects. But isn’t a particle system itself an object? If that’s the case (which it is), there’s no reason why we couldn’t also have a collection of many particle systems, i.e. a system of systems.
This line of thinking could of course take us even further, and you might lock yourself in a basement for days sketching out a diagram of a system of systems of systems of systems of systems of systems. Of systems. After all, this is how the world works. An organ is a system of cells, a human body is a system of organs, a neighborhood is a system of human bodies, a city is a system of neighborhoods, and so on and so forth. While this is an interesting road to travel down, it’s a bit beyond where we need to be right now. It is, however, quite useful to know how to write a program that keeps track of many particle systems, each of which keep track of many particles. Let’s take the following scenario:
  • You start with a blank screen.
  • You click the mouse and generate a particle system at the mouse’s location.
  • Each time you click the mouse, a new particle system is created at the mouse’s location.
Try it out yourself:
How would we accomplish this in code? In the previous article, we stored a single reference to a ParticleSystem object in the variable ps.
var ps = new ParticleSystem(new PVector(width/2, 50));

draw = function() {
  background(50, 50, 50);
  ps.addParticle();
  ps.run();
};
Now that we have multiple systems, a potentially ever increasing number, we don't want to store them in individually named variables. Instead, we'll use an array to keep track of all the systems. We'll start it as empty when the program begins:
var systems = [];
Whenever the mouse is pressed, a new ParticleSystem object is created and pushed onto the array:
mousePressed = function() {
  systems.push(new ParticleSystem(new PVector(mouseX, mouseY)));
};
And in draw(), instead of referencing a single ParticleSystem object, we now look through all the systems in the array and call run() on each of them.
draw = function() {
  background(50, 50, 50);
  for(var i = 0; i < systems.length; i++){
    systems[i].addParticle();
    systems[i].run();
  }
};
Now, try it yourself again, with the code we've written:

Want to join the conversation?

  • aqualine tree style avatar for user KidaTerraBoundUltra
    Can someone help me out on step 1 of the next challenge?
    (9 votes)
    Default Khan Academy avatar avatar for user
  • blobby green style avatar for user daverhine
    // We start off with an empty systems array
    var systems = [];

    // We fill up the leaves array with positions
    var leaves = [];
    for (var i = 0; i < 100; i++) {
    leaves.push(new PVector(random(0, width), random(0, height)));
    }

    mouseClicked = function() {
    systems.push(new ParticleSystem(new PVector(mouseX, mouseY)));
    };

    draw = function() {
    colorMode(RGB);
    background(66, 57, 11);

    for (var i = 0; i < leaves.length; i++) {
    image(getImage("avatars/leaf-orange"), leaves[i].x, leaves[i].y, 30, 30);
    }
    for (var i = 0; i < systems.length; i++){
    systems[i].addParticle();
    systems[i].run();
    }
    };

    in step one i'm asked to add a system, but the code to add systems has already been included,
    mouseClicked = function() {
    systems.push(new ParticleSystem(new PVector(mouseX, mouseY)));

    is this a technical issue or am i missing something,
    (5 votes)
    Default Khan Academy avatar avatar for user
  • starky ultimate style avatar for user Jack Kovski
    My fire turns kinda yellow, but i have no idea what the grader wants :/
    (3 votes)
    Default Khan Academy avatar avatar for user
  • aqualine ultimate style avatar for user T#1EH
    On the Fire Starter Challenge, Step Two, it asks for color in HSB. What's that?
    (2 votes)
    Default Khan Academy avatar avatar for user
    • leaf red style avatar for user deem
      *from the documentation:*
      colorMode(MODE)

      Changes the way that color values are interpreted when set by fill()/stroke()/background().
      Parameters: MODE Either RGB or HSB. The default is RGB.

      *additionally:*
      HSB stands for Hue, saturation, brightness while RGB stands for red, green, blue
      (6 votes)
  • leaf green style avatar for user Merrill Hutchison
    What range of colors do I need to map to? I'm using this, which seems like it should be okay.
    var hue = abs(1-this.timeToLive/100)*50;

    UPDATE: The grader wants a simpler formula. The max time to live is 100 and the time to live counts down by two at each time step. Subtract these two values and scale the result.
    (3 votes)
    Default Khan Academy avatar avatar for user
  • aqualine ultimate style avatar for user Eric Zheng
    (to the khan team) can i post a series of videos on how to use the khan academy javascript?
    (3 votes)
    Default Khan Academy avatar avatar for user
    • ohnoes default style avatar for user Brynden
      (I'm not a team member, but I'll answer your question)
      You're free to post videos of you programming with Khan Academy, as long as you let everyone know that you're not affiliated with the Khan Academy Team in any way, shape, or form. :)
      (3 votes)
  • piceratops ultimate style avatar for user LordBlaze64 [Read Bio]
    I've seen a lot of questions asking about solving step 2. Has anyone managed to solve it according to the grader? If so, could you please post the code? Thanks in advance.
    (3 votes)
    Default Khan Academy avatar avatar for user
  • aqualine ultimate style avatar for user Nondera
    When I was making bubbles on this page, after about 10 clicks it lagged and the program stopped, when i tried again on the challenge before modifying any code, this issue didn't occur. I understand that the computers at khan academy are better that the ones most people have, which is why some programs lag for us but why didn't it lag on the challenge. (btw I don't know if this is something that only i'm experiencing or if anyone can tell me why)
    (1 vote)
    Default Khan Academy avatar avatar for user
  • winston default style avatar for user azmeerk1
    Is it possible to make rain with particle systems?
    (1 vote)
    Default Khan Academy avatar avatar for user
  • winston default style avatar for user sloens
    I can't get past step 1. What is wrong with my code?
    angleMode = "radians";

    var Particle = function(position) {
    this.acceleration = new PVector(0, 0.05);
    this.velocity = new PVector(random(-1, 1), random(-1, 0));
    this.position = position.get();
    this.timeToLive = 100;
    };

    Particle.prototype.run = function() {
    this.update();
    this.display();
    };

    Particle.prototype.update = function(){
    this.velocity.add(this.acceleration);
    this.position.add(this.velocity);
    this.timeToLive -= 2;
    };

    Particle.prototype.display = function() {
    noStroke();
    fill(255, 255, 255, this.timeToLive);
    ellipse(this.position.x, this.position.y, 12, 12);
    };

    Particle.prototype.isDead = function() {
    if (this.timeToLive < 0) {
    return true;
    } else {
    return false;
    }
    };

    var ParticleSystem = function(position) {
    this.origin = position.get();
    this.particles = [];
    };

    ParticleSystem.prototype.addParticle = function() {
    this.particles.push(new Particle(this.origin));
    };

    ParticleSystem.prototype.run = function() {
    for (var i = this.particles.length-1; i >= 0; i--) {
    var p = this.particles[i];
    p.run();
    if (p.isDead()) {
    this.particles.splice(i, 1);
    }
    }
    };

    // We start off with an empty systems array
    var systems = [];
    systems.push(new ParticleSystem(new PVector(width/2, height/2)));

    // We fill up the leaves array with positions
    var leaves = [];
    for (var i = 0; i < 100; i++) {
    leaves.push(new ParticleSystem(random(0, width), random(0, height)));
    }



    draw = function() {
    colorMode(RGB);
    background(66, 57, 11);

    for (var i = 0; i < leaves.length; i++) {
    image(getImage("avatars/leaf-orange"), leaves[i].x, leaves[i].y, 30, 30);
    }
    for (var i = 0; i < systems.length; i++){
    systems[i].addParticle();
    systems[i].run();
    }
    };
    (1 vote)
    Default Khan Academy avatar avatar for user
    • old spice man green style avatar for user Bob Lyon
      When I run this, Yoko Oh Noes says "Uncaught TypeError: position.get is not a function". Clicking on "Show me where" takes me the ParticleSystem constructor. It is easy to conclude that the argument passed to the function is not a PVector.
      (1 vote)