javascript/jQuery How do I reuse objects in an array for a particle system -
i'm in process of building entity system canvas game. started simple particle emitter/updater altering accommodate multi-particle/entity generator. whilst ok javascript/jquery running limits of experience concerns arrays , gratefully accept on following:
when need new particle/entity current system calls function push object array contains variables entity updates.
then update function runs loop on array, checking on type variable update particle (position/colour/etc...). [array.splice] particle, based on condition. when needed further particles/entities push new particles.
what achieve here is:
in makeparticle function, check on particle array "dead" particles , if available resuse them, or push new particle if not have created particlealive var flag purpose.
var particles = []; var playing = false; function mousepressed(event) { playing = !playing; } if(playing) { makeparticle(1, 200, 200, 10, "blueflame"); makeparticle(1, 300, 200, 10, "redflame"); } function makeparticle(numparticles, xpos, ypos, pradius, ptype) { var i; (i = 0; < numparticles; i++) { var p = { type : ptype, x : xpos, y : ypos, xvel : random(-0.5, 0.5), yvel : random(-1, -3), particlealive : true, particlerender : true, size : pradius }; // close var p particles.push(p); // instead of pushing fresh particles time function, here, check free objects in array } // close loop } // close function makeparticle function runtime() { for(var i=0; i<particles.length; i++) { var p = particles[i]; var thistype = p.type; switch (thistype) { case "blueflame": c.fillstyle = rgb(100,100,255); c.fillcircle(p.x,p.y,p.size); p.x += p.xvel; p.y += p.yvel; p.size*=0.9; if (particles.size < 0.5) { particlealive = false; particlerender = false; } // close if break; case "redflame": c.fillstyle = rgb(255,100,100); c.fillcircle(p.x,p.y,p.size); p.x -= p.xvel; p.y -= p.yvel; p.size*=0.95; if (particles.size < 0.5) { particlealive = false; particlerender = false; } // close if break; } // close switch } // close function runtime
i've found previous answers relate questions, i've been unable working within makeparticle function, how assign attributes of p particle[j]:
var particleuseoldornew = function() { (var j = 0, len = particles.length; j < len; j++) { if (particles[j].particlealive === false) // particles[j] = p; return particle[j]; } return null; // no dead particles found, create new "particles.push(p);" perhaps? }
thanks in advance help
my personal opinion on matter if making new particle, should new object, not "re-using" of old 1 properties changed. each new object should have unique identifier, if need track them (for development purposes, debugging, or later re-use), easy do. or @ least keep counter of number of times you've re-used particle object represent "new" particle! though guess if you've found "re-using" improves performance (have you?), that's way go.
anyway, enough pontificating, here how you're asking (i assume speed main concern, did native js):
var particles = []; //function create brand spanking new particle function makenewparticle(xpos, ypos, pradius, ptype){ return { type : ptype, x : xpos, y : ypos, xvel : random(-0.5, 0.5), yvel : random(-1, -3), particlealive : true, particlerender : true, size : pradius }; }; //function change properties of old particle make psuedo-new particle (seriously, why want this?) function changeexistingparticle(existing, xpos, ypos, pradius, ptype){ existing.x = xpos; existing.y = ypos; existing.size = pradius; existing.type = ptype; return existing; }; //figure out keys of dead particles in particles[] array function getdeadparticlekeys() { var keys = []; for(var p = 0; p < particles.length; p++) { if (!particles[p].particlealive) { keys.push(p); } } }; function makeparticle(numparticles, xpos, ypos, pradius, ptype) { var d, i, deadparticles; //grab "dead" particle keys deadparticlekeys = getdeadparticlekeys(); numparticles -= deadparticlekeys.length; //replace each dead particle "live" 1 @ specified key (d = 0; d < deadparticlekeys.length; d++) { particles[ deadparticlekeys[d] ] = changeexistingparticle(particles[ deadparticlekeys[d] ], xpos, ypos, pradius, ptype) } //if had more particles there dead spaces available, add array (i = 0; < numparticles; i++) { particles.push( makenewparticle(xpos, ypos, pradius, ptype) ); } };
now, here's how recommend doing it: abandon idea or "re-using" particles, make separate constructor each particle (will immensely if add methods particles in future), , scrap dead particles every time 1 added:
//make constructor particle var particle = function(props){ if (typeof props === 'function') { props = props(); } this.type = props.type; this.x = props.x; this.y = props.y; this.size = props.size; }; paticle.prototype.particlealive = true; paticle.prototype.particlerender = true; //global particles list var particles = []; //remove dead element particlelist particles.clean = function(){ var p, keys; (p = this.length; p >= 0; p--) { if (!p.particlealive) { this.splice(p, 1); } } }; //method adding x amount of new particles - if num parameter isn't provided, assume 1 particles.add = function(props, num){ //first, clean out garbage! this.clean(); //now, append new particles end var n, limit = (num && typeof num === 'number') ? num : 1; (n = 0; n < limit; n++){ particles.push( new particle(props) ); } }; //a couple examples particles.add({ //add single blueflame type: "blueflame", size: 10, x: 200, y: 200 }); particles.add({ //add 4 redflames type: "redflame", size: 10, x: 300, y: 200 }, 4); particles.add(function(){//add 4 greenflames, randomized xy cooridinates this.x = math.round(math.random() * 1000); this.y = math.round(math.random() * 1000); this.size = 20; this.type = "greenflame"; }, 4);
way less code manage. i'm not sure way faster, i'd bet speed difference negligible. of course, check making quick jsperf.
Comments
Post a Comment