First pass at particle system
This commit is contained in:
parent
e620ff9c94
commit
9f53e28f35
2348
dist/es5.js
vendored
2348
dist/es5.js
vendored
File diff suppressed because one or more lines are too long
2
dist/es5.js.map
vendored
2
dist/es5.js.map
vendored
File diff suppressed because one or more lines are too long
2423
examples/particles/dist/particles.js
vendored
Normal file
2423
examples/particles/dist/particles.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
examples/particles/dist/particles.js.map
vendored
Normal file
1
examples/particles/dist/particles.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
10
examples/particles/index.html
Normal file
10
examples/particles/index.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Particles - MomentumEngine</title>
|
||||||
|
<script type="application/javascript" src="./dist/particles.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<canvas id="canvas"></canvas>
|
||||||
|
</body>
|
||||||
|
</html>
|
45
examples/particles/particles.js
Normal file
45
examples/particles/particles.js
Normal file
@ -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();
|
||||||
|
|
||||||
|
};
|
15
gulpfile.js
15
gulpfile.js
@ -26,7 +26,8 @@ var build = function (options, callback) {
|
|||||||
|
|
||||||
webpack({
|
webpack({
|
||||||
entry: {
|
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,
|
bail: !options.watch,
|
||||||
watch: options.watch,
|
watch: options.watch,
|
||||||
@ -41,7 +42,8 @@ var build = function (options, callback) {
|
|||||||
loader: "babel-loader",
|
loader: "babel-loader",
|
||||||
test: /\.js$/,
|
test: /\.js$/,
|
||||||
include: [
|
include: [
|
||||||
path.join(__dirname, "src")
|
path.join(__dirname, "src"),
|
||||||
|
path.join(__dirname, "examples")
|
||||||
],
|
],
|
||||||
query: {
|
query: {
|
||||||
plugins: ["transform-runtime"],
|
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) => {
|
gulp.task("build-dev", (callback) => {
|
||||||
build({
|
build({
|
||||||
watch: false,
|
watch: false,
|
||||||
|
16
package.json
16
package.json
@ -12,15 +12,15 @@
|
|||||||
"node": "^4.2.3"
|
"node": "^4.2.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-core": "6.3.17",
|
"babel-core": "6.5.2",
|
||||||
"babel-loader": "6.2.0",
|
"babel-loader": "6.2.2",
|
||||||
"babel-plugin-transform-runtime": "6.3.13",
|
"babel-plugin-transform-runtime": "6.5.2",
|
||||||
"babel-preset-es2015": "6.3.13",
|
"babel-preset-es2015": "6.5.0",
|
||||||
"babel-preset-stage-0": "6.3.13",
|
"babel-preset-stage-0": "6.5.0",
|
||||||
"babel-runtime": "6.3.19",
|
"babel-runtime": "6.5.0",
|
||||||
"gulp": "3.9.0",
|
"gulp": "3.9.1",
|
||||||
"gulp-util": "3.0.7",
|
"gulp-util": "3.0.7",
|
||||||
"webpack": "1.12.9"
|
"webpack": "1.12.13"
|
||||||
},
|
},
|
||||||
"dependencies": {}
|
"dependencies": {}
|
||||||
}
|
}
|
||||||
|
56
src/classes/emitter.js
Normal file
56
src/classes/emitter.js
Normal file
@ -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;
|
@ -8,6 +8,8 @@ class Entity {
|
|||||||
constructor (x, y) {
|
constructor (x, y) {
|
||||||
|
|
||||||
this.pos = new Vector2D(x || 0, y || 0);
|
this.pos = new Vector2D(x || 0, y || 0);
|
||||||
|
this.velocity = new Vector2D(0, 0);
|
||||||
|
this.acceleration = new Vector2D(0, 0);
|
||||||
|
|
||||||
this.state = {};
|
this.state = {};
|
||||||
this.children = [];
|
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 () {
|
createChildEntity () {
|
||||||
|
|
||||||
let child = new Entity();
|
let child = new Entity();
|
||||||
@ -46,7 +72,7 @@ class Entity {
|
|||||||
|
|
||||||
detachChildEntity (child) {
|
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) {
|
if (this.children[i] == child) {
|
||||||
|
|
||||||
this.children.splice(i, 1);
|
this.children.splice(i, 1);
|
||||||
@ -104,7 +130,19 @@ class Entity {
|
|||||||
|
|
||||||
_updateEntity (delta) {
|
_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")) {
|
if (updated || (typeof updated == "undefined") || (typeof this.update === "undefined")) {
|
||||||
|
|
||||||
@ -121,7 +159,7 @@ class Entity {
|
|||||||
|
|
||||||
this._preprocess();
|
this._preprocess();
|
||||||
|
|
||||||
var rendered = this.render && this.render();
|
let rendered = this.render && this.render();
|
||||||
|
|
||||||
if (rendered || (typeof rendered == "undefined") || (typeof this.render === "undefined")) {
|
if (rendered || (typeof rendered == "undefined") || (typeof this.render === "undefined")) {
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ class Game extends Entity {
|
|||||||
|
|
||||||
self._wantPause = false;
|
self._wantPause = false;
|
||||||
|
|
||||||
var requestFrame = (() => {
|
let requestFrame = (() => {
|
||||||
|
|
||||||
return (window.requestAnimationFrame ||
|
return (window.requestAnimationFrame ||
|
||||||
window.webkitRequestAnimationFrame ||
|
window.webkitRequestAnimationFrame ||
|
||||||
|
@ -46,9 +46,9 @@ class Sprite extends Entity {
|
|||||||
|
|
||||||
if (this.isReady() && this._game) {
|
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;
|
subHeight = imageObj.height - this._imagePos.y;
|
||||||
|
|
||||||
this._game.context.drawImage(
|
this._game.context.drawImage(
|
||||||
|
@ -101,6 +101,11 @@ class Vector2D {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
angle () {
|
||||||
|
return Math.atan2(this.x, this.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
toArray () {
|
toArray () {
|
||||||
return [this.x, this.y];
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
import Game from "./classes/game.js";
|
import Game from "./classes/game.js";
|
||||||
|
import Emitter from "./classes/emitter.js";
|
||||||
import Entity from "./classes/entity.js";
|
import Entity from "./classes/entity.js";
|
||||||
import Vector2D from "./classes/vector2d.js";
|
import Vector2D from "./classes/vector2d.js";
|
||||||
import Sprite from "./classes/sprite.js";
|
import Sprite from "./classes/sprite.js";
|
||||||
@ -13,6 +14,7 @@ import {KeyConsts} from "./classes/keyboardinput.js";
|
|||||||
|
|
||||||
const Classes = {
|
const Classes = {
|
||||||
Game: Game,
|
Game: Game,
|
||||||
|
Emitter: Emitter,
|
||||||
Entity: Entity,
|
Entity: Entity,
|
||||||
Sprite: Sprite,
|
Sprite: Sprite,
|
||||||
Rect: Rect,
|
Rect: Rect,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
import Game from "./classes/game.js";
|
import Game from "./classes/game.js";
|
||||||
|
import Emitter from "./classes/emitter.js";
|
||||||
import Entity from "./classes/entity.js";
|
import Entity from "./classes/entity.js";
|
||||||
import Vector2D from "./classes/vector2d.js";
|
import Vector2D from "./classes/vector2d.js";
|
||||||
import Sprite from "./classes/sprite.js";
|
import Sprite from "./classes/sprite.js";
|
||||||
@ -13,6 +14,7 @@ import {KeyConsts} from "./classes/keyboardinput.js";
|
|||||||
|
|
||||||
const Classes = {
|
const Classes = {
|
||||||
Game: Game,
|
Game: Game,
|
||||||
|
Emitter: Emitter,
|
||||||
Entity: Entity,
|
Entity: Entity,
|
||||||
Sprite: Sprite,
|
Sprite: Sprite,
|
||||||
Rect: Rect,
|
Rect: Rect,
|
||||||
@ -29,7 +31,7 @@ const Consts = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export {
|
export default {
|
||||||
Classes,
|
Classes,
|
||||||
Consts
|
Consts
|
||||||
};
|
};
|
Loading…
x
Reference in New Issue
Block a user