Particles now emit at a specified rate and correctly obey parent positions
This commit is contained in:
parent
8735e06619
commit
246453a25e
@ -4,6 +4,7 @@ import MomentumEngine from "../../src/es6";
|
|||||||
|
|
||||||
let white = new MomentumEngine.Classes.Color(255, 255, 255);
|
let white = new MomentumEngine.Classes.Color(255, 255, 255);
|
||||||
|
|
||||||
|
|
||||||
class BlueParticle extends MomentumEngine.Classes.Rect {
|
class BlueParticle extends MomentumEngine.Classes.Rect {
|
||||||
|
|
||||||
constructor (x, y) {
|
constructor (x, y) {
|
||||||
@ -15,11 +16,11 @@ class BlueParticle extends MomentumEngine.Classes.Rect {
|
|||||||
|
|
||||||
window.onload = function () {
|
window.onload = function () {
|
||||||
|
|
||||||
var width = 640,
|
let width = 640,
|
||||||
height = 360,
|
height = 360,
|
||||||
baseSize = width / 64;
|
baseSize = width / 64;
|
||||||
|
|
||||||
var particles = new MomentumEngine.Classes.Game({
|
let particles = new MomentumEngine.Classes.Game({
|
||||||
canvas: document.getElementById("canvas"),
|
canvas: document.getElementById("canvas"),
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
@ -27,19 +28,23 @@ window.onload = function () {
|
|||||||
desiredFps: 60
|
desiredFps: 60
|
||||||
});
|
});
|
||||||
|
|
||||||
var black = new MomentumEngine.Classes.Color(0, 0, 0),
|
let black = new MomentumEngine.Classes.Color(0, 0, 0),
|
||||||
red = new MomentumEngine.Classes.Color(255, 0, 0);
|
red = new MomentumEngine.Classes.Color(255, 0, 0);
|
||||||
|
|
||||||
var mainScene = new MomentumEngine.Classes.Rect(0, 0, width, height, black);
|
let mainScene = new MomentumEngine.Classes.Rect(0, 0, width, height, black);
|
||||||
particles.addChildEntity(mainScene);
|
particles.addChildEntity(mainScene);
|
||||||
|
|
||||||
var rect = new MomentumEngine.Classes.Rect(width / 2 - baseSize, height / 2 - baseSize, baseSize * 2, baseSize * 2, red),
|
let rect = new MomentumEngine.Classes.Rect(width / 10 - baseSize, height - (baseSize * 10), baseSize * 2, baseSize * 2, red),
|
||||||
emitter = new MomentumEngine.Classes.Emitter(0, 0, new MomentumEngine.Classes.Vector2D(1, 1), BlueParticle);
|
emitter = new MomentumEngine.Classes.Emitter(baseSize, baseSize, 2, new MomentumEngine.Classes.Vector2D(1, 1), BlueParticle);
|
||||||
|
|
||||||
mainScene.addChildEntity(rect);
|
mainScene.addChildEntity(rect);
|
||||||
rect.addChildEntity(emitter);
|
rect.addChildEntity(emitter);
|
||||||
|
rect.setVelocity(0.01, 0);
|
||||||
|
rect.setAcceleration(0.01, 0);
|
||||||
|
|
||||||
|
emitter.setParticleParent(mainScene);
|
||||||
emitter.emitting = true;
|
emitter.emitting = true;
|
||||||
|
|
||||||
particles.start();
|
particles.start();
|
||||||
|
|
||||||
};
|
};
|
@ -7,46 +7,88 @@ import Vector2D from "./vector2d.js";
|
|||||||
class Emitter extends Entity {
|
class Emitter extends Entity {
|
||||||
|
|
||||||
|
|
||||||
constructor (x, y, velocity, particle) {
|
constructor (x, y, rate, velocity, particle) {
|
||||||
|
|
||||||
super(x, y);
|
super(x, y);
|
||||||
|
|
||||||
this.particleVelocity = velocity;
|
this.particleVelocity = velocity;
|
||||||
this.particleClass = particle;
|
this.particleClass = particle;
|
||||||
|
|
||||||
|
this.emitRate = rate;
|
||||||
this.emitting = false;
|
this.emitting = false;
|
||||||
|
this._lastEmitTime = this._creationTime;
|
||||||
|
this._wasEmitting = false;
|
||||||
|
|
||||||
this.particles = [];
|
this.particles = [];
|
||||||
|
|
||||||
this.spread = function () {
|
this.spread = function () {
|
||||||
return Math.PI / 32;
|
return Math.PI / 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
setParticleParent (entity) {
|
||||||
|
this._particleParent = entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
_emit () {
|
_emit () {
|
||||||
|
|
||||||
|
let ParticleClass = this.particleClass,
|
||||||
|
parent = this._particleParent || this._parent;
|
||||||
|
|
||||||
|
let angle = this.particleVelocity.angle() + this.spread() - (Math.random() * this.spread() * 2),
|
||||||
|
magnitude = this.particleVelocity.length(),
|
||||||
|
velocity = Vector2D.fromAngle(angle, magnitude);
|
||||||
|
|
||||||
|
let particle = new ParticleClass(this._calculatedPos.x, this._calculatedPos.y);
|
||||||
|
particle.velocity = velocity;
|
||||||
|
|
||||||
|
this.particles.push(particle);
|
||||||
|
parent.addChildEntity(particle);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_triggerEmissions () {
|
||||||
|
|
||||||
|
// We prematurely call preprocess so that child particles can spawn from the emitters permission but be children of a different parent
|
||||||
|
// NK: This might cause a bug where child renders have an incorrect position because preprocess should normally be called after the update function but before the render, here it is before update. We'll see.
|
||||||
|
this._preprocess();
|
||||||
|
|
||||||
if (this.emitting) {
|
if (this.emitting) {
|
||||||
|
|
||||||
let ParticleClass = this.particleClass;
|
let currentTime = +(new Date());
|
||||||
|
|
||||||
let angle = this.particleVelocity.angle() + this.spread() - (Math.random() * this.spread() * 2),
|
if (!this._wasEmitting) {
|
||||||
magnitude = this.particleVelocity.length(),
|
this._wasEmitting = true;
|
||||||
velocity = Vector2D.fromAngle(angle, magnitude);
|
this._lastEmitTime = currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
let particle = new ParticleClass(this.pos.x, this.pos.y);
|
// In honour the code of Alex Evans
|
||||||
particle.velocity = velocity;
|
let emitDelta = currentTime - this._lastEmitTime;
|
||||||
|
if (emitDelta > this.emitRate) {
|
||||||
|
|
||||||
this.particles.push(particle);
|
let emissions = ~~(emitDelta / this.emitRate);
|
||||||
this._parent.addChildEntity(particle);
|
|
||||||
|
|
||||||
|
this._lastEmitTime = currentTime + (emitDelta - (this.emitRate * emissions));
|
||||||
|
|
||||||
|
for (let i = 0; i < emissions; i++) {
|
||||||
|
this._emit();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this._wasEmitting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
update () {
|
update () {
|
||||||
this._emit();
|
this._triggerEmissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,6 +19,8 @@ class Entity {
|
|||||||
this._game = null;
|
this._game = null;
|
||||||
this._parent = null;
|
this._parent = null;
|
||||||
|
|
||||||
|
this._creationTime = +(new Date());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -130,6 +132,12 @@ class Entity {
|
|||||||
|
|
||||||
_updateEntity (delta) {
|
_updateEntity (delta) {
|
||||||
|
|
||||||
|
if (this.timeToLive) {
|
||||||
|
if (+(new Date()) - this._creationTime > this.timeToLive) {
|
||||||
|
this._parent.detachChildEntity(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate new position based on velocity and acceleration if there's one set
|
// Calculate new position based on velocity and acceleration if there's one set
|
||||||
if (this.velocity) {
|
if (this.velocity) {
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user