https://jsfiddle.net/zwkdf0cg/12/
class Emitter {
constructor(settings) {
for (let key in settings) {
this[key] = settings[key];
}
this.particle = undefined;
this.parts = [];
}
grab_parts(particle_settings) {
this.particle = particle_settings;
return this.particle;
}
load_parts() {
if (this.counters.rate >= this.rate) {
for (let i = 0; i < this.particles.max; i++) {
this.parts.push(new Particle(this.particle));
}
this.counters.rate = 0;
}
this.counters.rate += this.timer();
}
draw_parts() {
for (let i = 0; i < this.parts.length; i++) {
let p = this.parts[i];
let can = this.canvas;
let con = this.context;
con.beginPath();
con.arc(p.x, p.y, p.radius, 0, 2 * Math.PI);
let gradient = con.createRadialGradient(p.x, p.y, p.radius, p.x, p.y, 0);
gradient.addColorStop(0,'hsla(20, 80%, 50%, 0)');
gradient.addColorStop(1,'hsla(20, 80%, 50%, 0.5)');
con.fillStyle = gradient;
con.fill();
}
}
update_parts() {
let can = this.canvas;
let con = this.context;
for (let i = 0; i < this.parts.length; i++) {
let p = this.parts[i];
if (p.x < -5 || p.x > can.width || p.y < -5 || p.y > can.height || p.counters.life < 0) {
let s = this.parts.splice(i, 1);
} else {
this.parts[i].update();
}
}
}
}
class Particle {
constructor(settings) {
for (let key in settings) {
this[key] = settings[key];
}
this.initialize = {
angle: false
}
this.life.range = number_range(this.life.min, this.life.max);
this.counters.life = this.life.range;
}
update() {
if (!this.initialize.angle) {
this.angle = radians(number_range(160, 180));
this.initialize.angle = true;
}
this.x += 1 * Math.cos(this.angle);
this.y += 1 * Math.sin(this.angle);
this.counters.life -= this.timer();
}
}
我将粒子的生命设置为2到8之间的数字。在粒子的update()方法中,从发射器的update_parts()方法调用,它的生命计数器被它的timer()属性所减少,该属性返回自那时起的时间。最后一次更新。发射器的update_parts()方法有一个条件,如果粒子超出界限,它会将粒子与发射器的部件[]阵列拼接在一起,或者它的寿命是&lt; 0.每当单个粒子的寿命<1时。 0,屏幕上的所有粒子都拼接起来,我无法弄清楚原因。我试过反转数组的迭代,创建一个只包含活粒子的新数组,并为此分配发射器的parts []数组,标记死粒子并创建一个新函数,在update_parts之后删除它们(被称为随机调整。我将particle_settings对象传递给粒子构造函数的方式有些麻烦,但我不知道这些是否相关。 ET手机回家。
答案 0 :(得分:0)
你在你正在迭代的数组上调用.splice()
,这是一个坏主意; splice()
changes the size of the array it's called on所以你的循环测试条件并不总是像你认为的那样工作。如果您使用以下内容替换for()
中的update_parts()
循环会发生什么:
this.parts = this.parts.filter(function(part) {
// filter out the ones we don't want...
return !(p.x < -5 || p.x > can.width || p.y < -5 || p.y > can.height || p.counters.life < 0);
}).forEach(function(part) {
// ...and update the rest
part.update();
});
答案 1 :(得分:0)
这段代码应该归咎于:
for (let key in settings) {
this[key] = settings[key];
}
当你在那里传递counters
个对象时,它不会被复制,而是在实例之间共享。
使用updated version&#39; cloneDeep
检查lodash:
_.assign(this, _.cloneDeep(settings));
_.assign
将属性分配给this
,类似于原始代码
_.cloneDeep
执行settings
对象的深层副本。