Hi,
I have made an array of particles and I initiate the particles in the draw function to get a particle stream.
But what I really want is to release the particles from the array at specific intervals. Like every second or so. The best would be if I could decide how many particles per interval.
I am working with particles attracted by the flowfield. Here is the full code I am working with:
sketch.js
var fr;
var inc = 0.06;
var scl = 33;
var cols, rows;
var zoff = 0;
var start = 0;
var flowfield;
let particles = [];
function setup() {
createCanvas(800, 800);
pixelDensity(1);
cols = floor(width / scl);
rows = floor(height / scl);
fr = createP("");
//particle array
// p = new Particle();
// for (var i = 0; i < 200; i++) {
// particles[i] = new Particle();
//flowfield array
flowfield = new Array(cols * rows);
}
function draw() {
background(20);
let p = new Particle();
particles.push(p);
var yoff = 0;
for (var y = 0; y < rows; y++) {
var xoff = 0;
for (var x = 0; x < cols; x++) {
var index = x + y * cols;
var angle = noise(xoff, yoff, zoff) * TWO_PI * 4;
var v = p5.Vector.fromAngle(angle);
v.setMag(0.1);
flowfield[index] = v;
xoff += inc;
strokeWeight(2);
stroke(70, 100, 0);
push();
translate(x * scl, y * scl);
rotate(v.heading());
line(0, 0, scl, 0);
pop();
}
yoff += inc;
zoff += 0.000045;
}
for (var i = particles.length-1; i >= 0; i--) {
particles[i].follow(flowfield);
particles[i].update();
particles[i].show();
particles[i].edges();
if (particles[i].finished()) {
//remove this particle
particles.splice(i, 1);
}
}
}
particle.js
function Particle() {
this.pos = createVector((mouseX+random(-20,20)),(mouseY+random(-20,20)));
this.vel = createVector(0.2,2);
this.acc = createVector(0, 0);
this.r = 30;
this.maxspeed = 5;
this.alpha = 255;
// when alpha less than 0 function is true
//for particle delete
this.finished = function () {
return this.alpha < 0;
}
this.update = function () {
this.vel.add(this.acc);
this.vel.limit(this.maxspeed);
this.pos.add(this.vel);
this.acc.mult(0);
this.alpha -= 1;
}
this.follow = function(vectors) {
var x = floor(this.pos.x / scl);
var y = floor(this.pos.y / scl);
var index = x +y * cols;
var force = vectors[index];
this.applyForce(force);
}
this.applyForce = function (force) {
this.acc.add(force);
};
this.show = function () {
noStroke();
fill(200, 50, 50, this.alpha);
circle(this.pos.x, this.pos.y, 10);
};
this.edges = function () {
if (this.pos.x > width) this.pos.x = 0;
if (this.pos.x < 0) this.pos.x = width;
if (this.pos.y > height) this.pos.y = 0;
if (this.pos.y < 0) this.pos.y = height;
};
}
One praticle every 5 seconds, comments in the code.
var fr;
var inc = 0.06;
var scl = 33;
var cols, rows;
var zoff = 0;
var start = 0;
var flowfield;
let particles = [];
// a var to track elapsed time
let elapsed = 0;
// one for how many particles
let particles_to_release = 1;
// and one for interval to release
// 1000 = 1seg (milliseconds)
let interval = 5000;
function setup() {
createCanvas(800, 800);
pixelDensity(1);
cols = floor(width / scl);
rows = floor(height / scl);
fr = createP("");
//particle array
// p = new Particle();
// for (var i = 0; i < 200; i++) {
// particles[i] = new Particle();
//flowfield array
flowfield = new Array(cols * rows);
//all set, lets reset our timer
elapsed = millis();
}
function draw() {
background(20);
//if current time minus stored is
// bigger than interval, release particles
if (millis() - elapsed > interval) {
//count released particles and stop after limit
for (let i = 0; i < particles_to_release; i++) {
let p = new Particle();
particles.push(p);
}
//reset de clock...
//voila :)
elapsed = millis();
}
var yoff = 0;
for (var y = 0; y < rows; y++) {
var xoff = 0;
for (var x = 0; x < cols; x++) {
var index = x + y * cols;
var angle = noise(xoff, yoff, zoff) * TWO_PI * 4;
var v = p5.Vector.fromAngle(angle);
v.setMag(0.1);
flowfield[index] = v;
xoff += inc;
strokeWeight(2);
stroke(70, 100, 0);
push();
translate(x * scl, y * scl);
rotate(v.heading());
line(0, 0, scl, 0);
pop();
}
yoff += inc;
zoff += 0.000045;
}
for (var i = particles.length - 1; i >= 0; i--) {
particles[i].follow(flowfield);
particles[i].update();
particles[i].show();
particles[i].edges();
if (particles[i].finished()) {
//remove this particle
particles.splice(i, 1);
}
}
}
Thanks a lot! This is what I was looking for. Now I tried to implement a lifespan for each particle and implemented your timer into the particle.js but did not succeed. Here is what I did:
sketch.js
var fr;
var inc = 0.04;
var scl = 40;
var cols, rows;
var zoff = 0;
var start = 0;
var flowfield;
let particles = [];
// a var to track elapsed time
let elapsed = 0;
// one for how many particles
let particles_to_release = 1;
// and one for interval to release
// 1000 = 1seg (milliseconds)
let interval = 500;
function setup() {
createCanvas(800, 800);
pixelDensity(1);
cols = floor(width / scl);
rows = floor(height / scl);
fr = createP("");
//particle array
// p = new Particle();
// for (var i = 0; i < 200; i++) {
// particles[i] = new Particle();
//flowfield array
flowfield = new Array(cols * rows);
//all set, lets reset our timer
elapsed = millis();
}
function draw() {
background(20);
if (millis() - elapsed > interval) {
for (let i = 0; i < particles_to_release; i++) {
let p = new Particle();
particles.push(p);
}
//reset de clock...
//voila :)
elapsed = millis();
}
var yoff = 0;
for (var y = 0; y < rows; y++) {
var xoff = 0;
for (var x = 0; x < cols; x++) {
var index = x + y * cols;
var angle = noise(xoff, yoff, zoff) * TWO_PI * 4;
var v = p5.Vector.fromAngle(angle);
v.setMag(0.6);
flowfield[index] = v;
xoff += inc;
strokeWeight(2);
stroke(70, 100, 0);
push();
translate(x * scl, y * scl);
rotate(v.heading());
line(0, 0, scl, 0);
pop();
}
yoff += inc;
zoff += 0.000445;
}
for (var i = particles.length-1; i >= 0; i--) {
particles[i].follow(flowfield);
particles[i].update();
particles[i].show();
particles[i].edges();
if (particles[i].finished()) {
//remove this particle
particles.splice(i, 1);
}
}
}
particle.js
// a var to track elapsed time
let particleelapsed = 0;
// and one for interval to release
//1000 = 1seg (milliseconds)
let particleinterval = 100;
function Particle() {
this.pos = createVector(mouseX + random(-20, 20), mouseY + random(-20, 20));
this.vel = createVector(0.2, 2);
this.acc = createVector(0, 0);
this.r = 30;
this.maxspeed = 20;
this.alpha = 255;
// when alpha less than 0 function is true
//for particle delete
//all set, lets reset our timer
particleelapsed = millis();
this.finished = function () {
return this.alpha < 0;
};
this.update = function () {
this.vel.add(this.acc);
this.vel.limit(this.maxspeed);
this.pos.add(this.vel);
this.acc.mult(0);
if (millis() - particleelapsed > particleinterval) {
this.alpha -= 10;
}
particleelapsed = millis();
};
this.follow = function (vectors) {
var x = floor(this.pos.x / scl);
var y = floor(this.pos.y / scl);
var index = x + y * cols;
var force = vectors[index];
this.applyForce(force);
};
this.applyForce = function (force) {
this.acc.add(force);
};
this.show = function () {
noStroke();
fill(200, 50, 50, this.alpha);
circle(this.pos.x, this.pos.y, 10);
};
this.edges = function () {
if (this.pos.x > width) this.pos.x = 0;
if (this.pos.x < 0) this.pos.x = width;
if (this.pos.y > height) this.pos.y = 0;
if (this.pos.y < 0) this.pos.y = height;
};
}
You missed the this. in some vars at particle.js so each one would know it’s own timer. And also have reset the timer outside the loop resetting the timer every frame, meaning time never will pass because elapsed is = milli() always.
function Particle() {
this.pos = createVector(mouseX + random(-20, 20), mouseY + random(-20, 20));
this.vel = createVector(0.2, 2);
this.acc = createVector(0, 0);
this.r = 30;
this.maxspeed = 20;
this.alpha = 255;
this.particleinterval = 100;
//all set, lets reset our timer
this.particleelapsed = millis();
this.finished = function () {
return this.alpha < 0;
};
this.update = function () {
this.vel.add(this.acc);
this.vel.limit(this.maxspeed);
this.pos.add(this.vel);
this.acc.mult(0);
if (millis() - this.particleelapsed > this.particleinterval) {
this.alpha -= 10;
this.particleelapsed = millis();
}
};
this.follow = function (vectors) {
var x = floor(this.pos.x / scl);
var y = floor(this.pos.y / scl);
var index = x + y * cols;
var force = vectors[index];
this.applyForce(force);
};
this.applyForce = function (force) {
this.acc.add(force);
};
this.show = function () {
noStroke();
fill(200, 50, 50, this.alpha);
circle(this.pos.x, this.pos.y, 10);
};
this.edges = function () {
if (this.pos.x > width) this.pos.x = 0;
if (this.pos.x < 0) this.pos.x = width;
if (this.pos.y > height) this.pos.y = 0;
if (this.pos.y < 0) this.pos.y = height;
};
}