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.

## Computer programming

### Course: Computer programming>Unit 5

Lesson 8: Particle Systems

# A single particle

Before we can create an entire `ParticleSystem`, we have to create an object that will describe a single particle. The good news: we've done this already. Our `Mover` object from the Forces section serves as the perfect template. For us, a particle is an independent body that moves about the screen. It has `location`, `velocity`, and `acceleration`, a constructor to initialize those variables, and functions to `display()` itself and `update()` its location.
``````// A simple Particle object
var Particle = function(position) {
this.acceleration = new PVector();
this.velocity = new PVector();
this.position = position.get();
};

Particle.prototype.update = function(){
};

Particle.prototype.display = function() {
stroke(0, 0, 0);
fill(175, 175, 175);
ellipse(this.position.x, this.position.y, 8, 8);
};``````
This is about as simple as a particle can get. From here, we could take our particle in several directions. We could add an `applyForce()` method to affect the particle’s behavior (we’ll do precisely this in a future example). We could add variables to describe color and shape, or use `image()` to draw the particle. For now, however, let’s focus on adding just one additional detail: lifespan.
Typical particle systems involve something called an emitter. The emitter is the source of the particles and controls the initial settings for the particles, location, velocity, etc. An emitter might emit a single burst of particles, or a continuous stream of particles, or both. The point is that for a typical implementation such as this, a particle is born at the emitter but does not live forever. If it were to live forever, our program would eventually grind to a halt as the number of particles increased to an unwieldy number over time. As new particles are born, we need old particles to die. This creates the illusion of an infinite stream of particles, and the performance of our program does not suffer.
There are many different ways to decide when a particle dies. For example, it could come into contact with another object, or it could simply leave the screen. For our first `Particle` object, however, we’re simply going to add a `timeToLive` property. It will act as a timer, counting down from 255 to 0, at which point we'll consider the particle to be "dead." And so we expand the `Particle` object as follows:
``````// A simple Particle object
var Particle = function(position) {
this.acceleration = new PVector();
this.velocity = new PVector();
this.position = position.get();
this.timeToLive = 255;
};

Particle.prototype.update = function(){
this.timeToLive -= 2;
};

Particle.prototype.display = function() {
stroke(255, 255, 255, this.timeToLive);
fill(127, 127, 127, this.timeToLive);
ellipse(this.position.x, this.position.y, 8, 8);
};``````
The reason we chose to start the `timeToLive` at 255 and count down to 0 is for convenience. With those values, we can use `timeToLive` as the alpha transparency for the ellipse as well. When the particle is “dead” it will also have faded away onscreen.
With the addition of the `timeToLive` property, we’ll also need one additional method—a function that can be queried (for a true or false answer) as to whether the particle is alive or dead. This will come in handy when we are writing the `ParticleSystem` object, whose task will be to manage the list of particles themselves. Writing this function is pretty easy; it just needs to return true if the value of `timeToLive` is less than 0.
``````Particle.prototype.isDead = function() {
return this.timeToLive < 0;
};``````
Before we get to the next step of making many particles, it’s worth taking a moment to make sure our particle works correctly and create a sketch with one single `Particle` object. Here is the full code below, with two small additions. We add a convenience method called `run()` that simply calls both `update()` and `display()` for us. In addition, we give the particle a random initial velocity as well as a downward acceleration (to simulate gravity).
Now that we have an object to describe a single particle, we’re ready for the next big step. How do we keep track of many particles, when we can’t ensure exactly how many particles we might have at any given time?

## Want to join the conversation?

• Why cant the `Particle.prototype.isDead` function just return a boolean value, like this,
``Particle.prototype.isDead = function() {    return this.timeToLive <= 0;}``

instead of having a series of uneeded `if` statements? • Just curious, what does this.position = position.get(); do? • `PVector.get()` creates a copy of the vector object.
Then that copy is assigned to the position of the particle.

So the particle now has a position with the same values, but it can be changed independently.
If you didn't use get() to make a copy, then you would not be able to change one position without also changing the other. Too bad KA doesn't teach why.
• step 3 im getting "Make sure you also change the leaf's angular velocity and acceleration when it hits the ground! "
now ive applied it to the draw , update, display, im not sure where im going wrong?
` if(this.position.y < height){ this.velocity.set(0,0); this.acceleration.set(0,0); }` • For step two on the challenge: I've tried using
``if (leaves[i].position.y >= height) {    leaves[i].position.y = height;    leaves[i].velocity.y = 0;    leaves[i].acceleration = new PVector();}``

in a couple of variations: using `height - 40`; using `>` instead of `>=`; placing in the `draw` function at the top, at the bottom, in its own loop; placing in `Particle.prototype.update` using `this`; etc. These all work: the leaves pile up at the bottom, but I'm not getting credit by the autograder. Any tips? • The autoGrader doesn't accept my changes in step one:
``var ds =[];mouseClicked=function(){    ds.push( new Particle(new PVector(mouseX,mouseY)));};draw = function() {    background(194, 231, 255);    tree.display();    for(var i=0;i<ds.length;i++){        ds[i].run();    }};`` • what is the difference between these three:
var v1 = new PVector(0,1);
var v2 = v1; ...............................(1)
var v2 = v1.get(); .......................(2) &
var v2;
v2.set(v1); ...............................(3) • 1.
``var v1 = new PVector(12, 5);var v2 = new PVector(12, 5);println(v2 === v1);``
We see that `v1` and `v2` are separate objects as witnessed by the equality operator `===`, where as
``var v1 = new PVector(12, 5);var v2 = v1;println(v2 === v1);``
show us that `v1` and `v2` refer to the same object. In the latter case, if you modify `v2` then `v1` will also show that modification.

2.
``var v1 = new PVector(3, 4);var v2 = v1.get();``
The `get` method returns a `new` PVector. So `v1` and `v2` are separate objects that have the same property values, like in the first case of example one.

3.
``var v1 = new PVector(8, 15);var v2;v2.set(v1);``
will fail since `v2` is undefined and as such has no `set` method. Try
``var v1 = new PVector(8, 15);var v2 = new PVector();v2.set(v1);``
to make the separate objects `v1` and `v2` have the same property values as in the first case of example one.
• I need help, in the next challenge, on step one. I am writing the next `code`:
``mouseClicked = function (){    leaves.push(new Particle(new PVector(mouseX, mouseY)));};draw = function() {    background(194, 231, 255);    tree.display();    for (var i=0;i<leaves.length;i++){        leaves[i].run();        }   };``

It is working, leaves are falling, but the "beaver" don't pass me into the next part of the challenge. What is wrong, please someone can help me? • i need help on the next challenge... i looked in the comments and tried to use what they said, but am still not getting it. here is my code:

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

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

Particle.prototype.update = function(){
};

Particle.prototype.display = function() {
image(getImage("avatars/leaf-green"), this.position.x, this.position.y, 40, 40);
};

var Tree = function(position, options) {
this.position = position.get();
this.branchingFactor = 3;
this.angleBetweenBranches = 32;
this.scaleFactor = 0.7;
this.numLevels = 4;
this.baseBranchLength = 120;
};

Tree.prototype.display = function() {
var self = this;

var forward = function(distance) {
line(0, 0, 0, -distance);
translate(0, -distance);
};

var back = function(distance) {
forward(-distance);
};

var right = function(angle) {
rotate(angle * PI / 180);
};

var left = function(angle) {
right(-angle);
};

var drawTree = function(depth, length) {
if (depth === 0) {
image(getImage("avatars/leaf-green"), -10, -30, 40, 40);
return;
}
var totalAngle = self.angleBetweenBranches * (self.branchingFactor - 1);

strokeWeight(depth*5);
forward(length);
right(totalAngle / 2.0);
for (var i = 0; i < self.branchingFactor; i += 1) {
drawTree(depth - 1, length * self.scaleFactor);
left(self.angleBetweenBranches);
}
right(totalAngle / 2.0 + self.angleBetweenBranches);
back(length);
};

pushMatrix();
translate(this.position.x, this.position.y);
stroke(122, 112, 85);
drawTree(this.numLevels, this.baseBranchLength);
popMatrix();
};

var leaves = [];
var tree = new Tree(new PVector(width/2, 400));
mouseClicked = function(){
ds.push( new Particle(new PVector(mouseX,mouseY)));
};

draw = function() {
background(194, 231, 255);
tree.display();
for(var i = 0; i < leaves.length; i++) {
var fall = leaves[i];

}; • You are on the right track, you want to call the various methods on leaves[i] or fall (since that's the variable you have used to store leaves[i]) such as fall.display(), fall.run(), fall.update(). Also, you want to push the new particle values into the null leaves array or else when you call these methods on the leaves[i], it will be empty and nothing will happen.
(1 vote)
• In the next challenge, even though the grader lets me pass all steps, I can't make it so the leaves stop at the bottom of the screen while rotating during their fall. I think it's because I'm rotating the grid, so my
``if (leaf.position.y > height - 30)``
isn't checking the bottom of the screen anymore, but wherever that y is while being rotated, but I can't find how to make it so that the leaf rotates and still hits the bottom, lying still.

My code (I left out the Tree object):
``angleMode = "radians";var Particle = function(position) {    this.acceleration = new PVector(0, 0.05);    this.velocity = new PVector(random(0, 1), random(0, 0));    this.position = position;        this.angle = 0;    this.aVelocity = 0;    this.aAcceleration = 0.0005;};Particle.prototype.run = function() {    this.update();    this.display();};Particle.prototype.update = function(){    this.velocity.add(this.acceleration);    this.position.add(this.velocity);        this.aVelocity += this.aAcceleration;    this.angle += this.aVelocity;};Particle.prototype.display = function() {    pushMatrix();    rotate(this.angle);    image(getImage("avatars/leaf-green"), this.position.x, this.position.y, 40, 40);    popMatrix();};var leaves = [];var tree = new Tree(new PVector(width/2, 400));mouseClicked = function() {    var particle = new Particle(new PVector(mouseX, mouseY));    leaves.push(particle);};draw = function() {    background(194, 231, 255);    tree.display();    for (var i = 0; i < leaves.length; i++) {        var leaf = leaves[i];        leaf.run();        if (leaf.position.y >= height - 30) {            leaf.acceleration.set(0, 0);            leaf.velocity.set(0, 0);            resetMatrix();            leaf.aAcceleration = 0;            leaf.aVelocity = 0;        }    }};``  