diff --git a/examples/particles/index.html b/examples/particles/index.html
new file mode 100644
index 0000000..ccba0ee
--- /dev/null
+++ b/examples/particles/index.html
@@ -0,0 +1,10 @@
+
+
+
+ Particles - MomentumEngine
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/particles/particles.js b/examples/particles/particles.js
new file mode 100644
index 0000000..fcc3592
--- /dev/null
+++ b/examples/particles/particles.js
@@ -0,0 +1,45 @@
+"use strict";
+
+import MomentumEngine from "../../src/es6";
+
+let white = new MomentumEngine.Classes.Color(255, 255, 255);
+
+class BlueParticle extends MomentumEngine.Classes.Rect {
+
+ constructor (x, y) {
+ super(x, y, 1, 1, white);
+ }
+
+}
+
+
+window.onload = function () {
+
+ var width = 640,
+ height = 360,
+ baseSize = width / 64;
+
+ var particles = new MomentumEngine.Classes.Game({
+ canvas: document.getElementById("canvas"),
+ width: width,
+ height: height,
+ fixRatio: true,
+ desiredFps: 60
+ });
+
+ var black = new MomentumEngine.Classes.Color(0, 0, 0),
+ red = new MomentumEngine.Classes.Color(255, 0, 0);
+
+ var mainScene = new MomentumEngine.Classes.Rect(0, 0, width, height, black);
+ particles.addChildEntity(mainScene);
+
+ var rect = new MomentumEngine.Classes.Rect(width / 2 - baseSize, height / 2 - baseSize, baseSize * 2, baseSize * 2, red),
+ emitter = new MomentumEngine.Classes.Emitter(0, 0, new MomentumEngine.Classes.Vector2D(1, 1), BlueParticle);
+
+ mainScene.addChildEntity(rect);
+ rect.addChildEntity(emitter);
+
+ emitter.emitting = true;
+ particles.start();
+
+};
\ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
index e42da1b..57067f6 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -26,7 +26,8 @@ var build = function (options, callback) {
webpack({
entry: {
- "es5": path.join(__dirname, "src", "es5.js")
+ "es5": path.join(__dirname, "src", "es5.js"),
+ "particles": path.join(__dirname, "examples/particles", "particles.js")
},
bail: !options.watch,
watch: options.watch,
@@ -41,7 +42,8 @@ var build = function (options, callback) {
loader: "babel-loader",
test: /\.js$/,
include: [
- path.join(__dirname, "src")
+ path.join(__dirname, "src"),
+ path.join(__dirname, "examples")
],
query: {
plugins: ["transform-runtime"],
@@ -76,6 +78,15 @@ var build = function (options, callback) {
};
+gulp.task("move", () => {
+ gulp.src([
+ "./dist/particles.*"
+ ], {
+ base: "./dist"
+ }).pipe(gulp.dest("examples/particles/dist"));
+});
+
+
gulp.task("build-dev", (callback) => {
build({
watch: false,
diff --git a/package.json b/package.json
index cc7c0b7..bebcb7d 100644
--- a/package.json
+++ b/package.json
@@ -12,15 +12,15 @@
"node": "^4.2.3"
},
"devDependencies": {
- "babel-core": "6.3.17",
- "babel-loader": "6.2.0",
- "babel-plugin-transform-runtime": "6.3.13",
- "babel-preset-es2015": "6.3.13",
- "babel-preset-stage-0": "6.3.13",
- "babel-runtime": "6.3.19",
- "gulp": "3.9.0",
+ "babel-core": "6.5.2",
+ "babel-loader": "6.2.2",
+ "babel-plugin-transform-runtime": "6.5.2",
+ "babel-preset-es2015": "6.5.0",
+ "babel-preset-stage-0": "6.5.0",
+ "babel-runtime": "6.5.0",
+ "gulp": "3.9.1",
"gulp-util": "3.0.7",
- "webpack": "1.12.9"
+ "webpack": "1.12.13"
},
"dependencies": {}
}
diff --git a/src/classes/emitter.js b/src/classes/emitter.js
new file mode 100644
index 0000000..1755403
--- /dev/null
+++ b/src/classes/emitter.js
@@ -0,0 +1,56 @@
+"use strict";
+
+import Entity from "./entity.js";
+import Vector2D from "./vector2d.js";
+
+
+class Emitter extends Entity {
+
+
+ constructor (x, y, velocity, particle) {
+
+ super(x, y);
+
+ this.particleVelocity = velocity;
+ this.particleClass = particle;
+ this.emitting = false;
+
+ this.particles = [];
+
+ this.spread = function () {
+ return Math.PI / 32;
+ }
+
+ }
+
+
+ _emit () {
+
+ if (this.emitting) {
+
+ let ParticleClass = this.particleClass;
+
+ 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.pos.x, this.pos.y);
+ particle.velocity = velocity;
+
+ this.particles.push(particle);
+ this._parent.addChildEntity(particle);
+
+ }
+
+ }
+
+
+ update () {
+ this._emit();
+ }
+
+
+}
+
+
+export default Emitter;
\ No newline at end of file
diff --git a/src/classes/entity.js b/src/classes/entity.js
index 629cb15..705b028 100644
--- a/src/classes/entity.js
+++ b/src/classes/entity.js
@@ -8,6 +8,8 @@ class Entity {
constructor (x, y) {
this.pos = new Vector2D(x || 0, y || 0);
+ this.velocity = new Vector2D(0, 0);
+ this.acceleration = new Vector2D(0, 0);
this.state = {};
this.children = [];
@@ -20,6 +22,30 @@ class Entity {
}
+ setVelocity (x, y) {
+
+ if (x instanceof Vector2D) {
+ this.velocity = x;
+ } else {
+ this.velocity.x = x;
+ this.velocity.y = y;
+ }
+
+ }
+
+
+ setAcceleration (x, y) {
+
+ if (x instanceof Vector2D) {
+ this.acceleration = x;
+ } else {
+ this.acceleration.x = x;
+ this.acceleration.y = y;
+ }
+
+ }
+
+
createChildEntity () {
let child = new Entity();
@@ -46,7 +72,7 @@ class Entity {
detachChildEntity (child) {
- for (var i = 0; i < this.children.length; i++) {
+ for (let i = 0; i < this.children.length; i++) {
if (this.children[i] == child) {
this.children.splice(i, 1);
@@ -104,7 +130,19 @@ class Entity {
_updateEntity (delta) {
- var updated = this.update && this.update(delta);
+ // Calculate new position based on velocity and acceleration if there's one set
+ if (this.velocity) {
+
+ if (this.acceleration) {
+ this.velocity.add(this.acceleration);
+ }
+
+ this.pos.add(this.velocity);
+
+ }
+
+ // If there's an update method, call it
+ let updated = this.update && this.update(delta);
if (updated || (typeof updated == "undefined") || (typeof this.update === "undefined")) {
@@ -121,7 +159,7 @@ class Entity {
this._preprocess();
- var rendered = this.render && this.render();
+ let rendered = this.render && this.render();
if (rendered || (typeof rendered == "undefined") || (typeof this.render === "undefined")) {
diff --git a/src/classes/game.js b/src/classes/game.js
index 501dc2f..283a47d 100644
--- a/src/classes/game.js
+++ b/src/classes/game.js
@@ -123,7 +123,7 @@ class Game extends Entity {
self._wantPause = false;
- var requestFrame = (() => {
+ let requestFrame = (() => {
return (window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
diff --git a/src/classes/sprite.js b/src/classes/sprite.js
index 4a83ca9..3aa0048 100644
--- a/src/classes/sprite.js
+++ b/src/classes/sprite.js
@@ -46,9 +46,9 @@ class Sprite extends Entity {
if (this.isReady() && this._game) {
- var imageObj = this._image.getImageObj();
+ let imageObj = this._image.getImageObj();
- var subWidth = imageObj.width - this._imagePos.x,
+ let subWidth = imageObj.width - this._imagePos.x,
subHeight = imageObj.height - this._imagePos.y;
this._game.context.drawImage(
diff --git a/src/classes/vector2d.js b/src/classes/vector2d.js
index 507e22e..32309d8 100644
--- a/src/classes/vector2d.js
+++ b/src/classes/vector2d.js
@@ -101,6 +101,11 @@ class Vector2D {
}
+ angle () {
+ return Math.atan2(this.x, this.y);
+ }
+
+
toArray () {
return [this.x, this.y];
}
@@ -116,6 +121,11 @@ class Vector2D {
}
+ static fromAngle (angle, length) {
+ return new Vector2D(length * Math.cos(angle), length * Math.sin(angle));
+ }
+
+
}
diff --git a/src/es5.js b/src/es5.js
index d81b8ec..f2bcf63 100644
--- a/src/es5.js
+++ b/src/es5.js
@@ -1,6 +1,7 @@
"use strict";
import Game from "./classes/game.js";
+import Emitter from "./classes/emitter.js";
import Entity from "./classes/entity.js";
import Vector2D from "./classes/vector2d.js";
import Sprite from "./classes/sprite.js";
@@ -13,6 +14,7 @@ import {KeyConsts} from "./classes/keyboardinput.js";
const Classes = {
Game: Game,
+ Emitter: Emitter,
Entity: Entity,
Sprite: Sprite,
Rect: Rect,
diff --git a/src/es6.js b/src/es6.js
index 60008dd..5dafa0c 100644
--- a/src/es6.js
+++ b/src/es6.js
@@ -1,6 +1,7 @@
"use strict";
import Game from "./classes/game.js";
+import Emitter from "./classes/emitter.js";
import Entity from "./classes/entity.js";
import Vector2D from "./classes/vector2d.js";
import Sprite from "./classes/sprite.js";
@@ -13,6 +14,7 @@ import {KeyConsts} from "./classes/keyboardinput.js";
const Classes = {
Game: Game,
+ Emitter: Emitter,
Entity: Entity,
Sprite: Sprite,
Rect: Rect,
@@ -29,7 +31,7 @@ const Consts = {
};
-export {
+export default {
Classes,
Consts
};
\ No newline at end of file