aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/webpack.js2
-rw-r--r--lib/components/pixi_container.js25
-rw-r--r--lib/factories/pixi.js66
-rw-r--r--lib/factories/sumo.js51
-rw-r--r--lib/nodes/renderable.js27
-rw-r--r--lib/sumo.js33
-rw-r--r--lib/systems/render.js99
-rw-r--r--package-lock.json119
-rw-r--r--package.json7
9 files changed, 414 insertions, 15 deletions
diff --git a/config/webpack.js b/config/webpack.js
index db1837a..34cccbd 100644
--- a/config/webpack.js
+++ b/config/webpack.js
@@ -3,7 +3,7 @@
const Path = require('path');
module.exports = {
- entry: './lib/sumo',
+ entry: ['babel-polyfill', './lib/sumo'],
output: {
path: Path.resolve(__dirname, '../assets'),
diff --git a/lib/components/pixi_container.js b/lib/components/pixi_container.js
new file mode 100644
index 0000000..5e5cb1f
--- /dev/null
+++ b/lib/components/pixi_container.js
@@ -0,0 +1,25 @@
+import { Component } from '@serpentity/serpentity';
+
+/**
+ * Component that stores a pixi container
+ *
+ * @extends {external:Serpentity.Component}
+ * @class PixiContainerComponent
+ * @param {object} config a configuration object to extend.
+ */
+export default class PixiContainerComponent extends Component {
+ constructor(config) {
+
+ super(config);
+
+ /**
+ * The properthy that holds the pixi container
+ *
+ * @property {external:PixiJs.Container} container
+ * @name container
+ * @instance
+ * @memberof PixiContainerComponent
+ */
+ this.container = this.container || null;
+ }
+};
diff --git a/lib/factories/pixi.js b/lib/factories/pixi.js
new file mode 100644
index 0000000..e3c1b5a
--- /dev/null
+++ b/lib/factories/pixi.js
@@ -0,0 +1,66 @@
+import { Graphics } from 'pixi.js';
+
+/**
+ * Factory object that contains many methods to create prefab pixi
+ * objects
+ *
+ * @type object
+ * @name PixiFactory
+ */
+export default {
+
+ /**
+ * Creates a sumo container
+ *
+ * @function createSumo
+ * @memberof PixiFactory
+ * @return {external:CreateJs.Container} the created container
+ */
+ createSumo() {
+
+ const radius = 25;
+
+ // The body
+ const body = new Graphics();
+ body.beginFill(0x87c5ea)
+ .drawCircle(0, 0, radius)
+ .endFill();
+
+ // The mouth
+ const mouth = new Graphics();
+ mouth.lineStyle(10, 0xff0080, 1)
+ .arc(
+ 0, 0, // center
+ radius * 0.6,
+ Math.PI / 6,
+ 5 * Math.PI / 6
+ );
+
+ const leftEye = new Graphics();
+ leftEye.beginFill(0xffffff)
+ .drawCircle(-radius / 3 - radius / 8, -radius / 4, radius / 5)
+ .endFill();
+
+ const rightEye = new Graphics();
+ rightEye.beginFill(0xffffff)
+ .drawCircle(radius / 3 + radius / 8, -radius / 4, radius / 5);
+
+ const leftPupil = new Graphics();
+ leftPupil.beginFill(0x11)
+ .drawCircle(-radius / 3 - radius / 8, -radius / 4, radius / 10);
+
+ const rightPupil = new Graphics();
+ leftPupil.beginFill(0x11)
+ .drawCircle(radius / 3 + radius / 8, -radius / 4, radius / 10);
+
+ // The group
+ body.addChild(mouth);
+ body.addChild(leftEye);
+ body.addChild(rightEye);
+ body.addChild(leftPupil);
+ body.addChild(rightPupil);
+
+ return body;
+ }
+};
+
diff --git a/lib/factories/sumo.js b/lib/factories/sumo.js
new file mode 100644
index 0000000..b0e5416
--- /dev/null
+++ b/lib/factories/sumo.js
@@ -0,0 +1,51 @@
+import { Entity } from '@serpentity/serpentity';
+
+import PositionComponent from '@serpentity/components.position';
+import PixiContainerComponent from '../components/pixi_container';
+import PixiFactory from '../factories/pixi';
+
+/**
+ * Factory object that contains many methods to create prefab entities.
+ *
+ * @type object
+ * @name SumoFactory
+ */
+export default {
+
+ /**
+ * Creates a sumo entity and adds it to the engine. Can override
+ * position in the config object
+ *
+ * @function createSumo
+ * @memberof SumoFactory
+ * @param {external:Serpentity} [engine] the serpentity engine to attach
+ * to. If not sent, it will not be attached.
+ * @param {object} [config] the config to override the entity, accepts
+ * the key `position` as an object with an x and y property.
+ * @return {external:Serpentity.Entity} the created entity
+ */
+ createSumo(engine, config = {}) {
+
+ const entity = new Entity();
+
+ entity.addComponent(new PositionComponent(config.position));
+
+ const container = config.container || {
+ container: PixiFactory.createSumo()
+ };
+
+ // Match the symbol position with the entity position on init
+ // Otherwise it's up to systems
+ const position = entity.getComponent(PositionComponent);
+ container.container.position.x = position.x;
+ container.container.position.y = position.y;
+
+ entity.addComponent(new PixiContainerComponent(container));
+
+ if (engine) {
+ engine.addEntity(entity);
+ }
+
+ return entity;
+ }
+};
diff --git a/lib/nodes/renderable.js b/lib/nodes/renderable.js
new file mode 100644
index 0000000..0a3a111
--- /dev/null
+++ b/lib/nodes/renderable.js
@@ -0,0 +1,27 @@
+import { Node } from '@serpentity/serpentity';
+
+import PixiContainerComponent from '../components/pixi_container';
+import PositionComponent from '@serpentity/components.position';
+
+/**
+ * Node identifying a renderable entity, should have position and a
+ * symbol to render
+ *
+ * @extends {external:Serpentity.Node}
+ * @class RenderableNode
+ */
+export default class RenderableNode extends Node {
+
+};
+
+/**
+ * Holds the types that are used to identify a wave entity
+ *
+ * @property {object} types
+ * @name types
+ * @memberof WaveNode
+ */
+RenderableNode.types = {
+ position: PositionComponent,
+ container: PixiContainerComponent
+};
diff --git a/lib/sumo.js b/lib/sumo.js
index da72991..81f948f 100644
--- a/lib/sumo.js
+++ b/lib/sumo.js
@@ -1,8 +1,12 @@
+import RenderSystem from './systems/render';
+import SumoFactory from './factories/sumo';
import Serpentity from '@serpentity/serpentity';
+import { Application } from 'pixi.js';
/* global window document */
const internals = {
+ kBackgroundColor: 0xd8c590,
kNoElementError: 'No element found. Cannot render.',
// Handler for the window load event. Initializes and runs the app.
@@ -56,6 +60,7 @@ internals.Sumo = class Sumo {
// Initialization functions
this._initializeCanvas();
+ this._initializePixi();
this._initializeSystems();
this._initializeEntities();
}
@@ -119,6 +124,18 @@ internals.Sumo = class Sumo {
window.addEventListener('resize', this._resizeCanvas.bind(this));
}
+ // Initialize Pixi
+
+ _initializePixi() {
+
+ this._pixi = new Application({
+ backgroundColor: internals.kBackgroundColor,
+ view: this._canvas,
+ width: this._canvas.width,
+ height: this._canvas.height
+ });
+ }
+
// Resizes the canvas to a square the size of the smallest magnitude
// of the window.
@@ -143,12 +160,28 @@ internals.Sumo = class Sumo {
_initializeSystems() {
+ this._engine.addSystem(new RenderSystem({
+ application: this._pixi
+ }));
}
// Initializes the serpentity entities
_initializeEntities() {
+ SumoFactory.createSumo(this._engine, {
+ position: {
+ x: 50,
+ y: 50
+ }
+ });
+
+ SumoFactory.createSumo(this._engine, {
+ position: {
+ x: 309,
+ y: 112
+ }
+ });
}
};
diff --git a/lib/systems/render.js b/lib/systems/render.js
new file mode 100644
index 0000000..8d3d446
--- /dev/null
+++ b/lib/systems/render.js
@@ -0,0 +1,99 @@
+import { System } from '@serpentity/serpentity';
+
+import RenderableNode from '../nodes/renderable';
+
+const internals = {
+ kNoPixiError: 'No pixi application passed to render system. Make sure you set the `application` key in the config object when initializing.'
+};
+
+/**
+ * Renders renderable objects to console
+ *
+ * @extends {external:Serpentity.System}
+ * @class RenderSystem
+ * @param {object} config a configuration object to extend.
+ */
+export default class RenderSystem extends System {
+
+ constructor(config = {}) {
+
+ super();
+
+ /**
+ * The node collection of renderable entities
+ *
+ * @property {external:Serpentity.NodeCollection} renderables
+ * @instance
+ * @memberof RenderSystem
+ */
+ this.renderables = null;
+
+ /**
+ * The pixi engine we will use to render
+ *
+ * @property {external:PixiJs.Application} renderables
+ * @instance
+ * @memberof RenderSystem
+ */
+ this._application = config.application;
+
+ if (!this._application) {
+ throw new Error(internals.kNoPixiError);
+ }
+ }
+
+ /**
+ * Initializes system when added. Requests renderable nodes and
+ * attaches to event listeners to add / remove them to pixi stage
+ *
+ * @function added
+ * @memberof RenderSystem
+ * @instance
+ * @param {external:Serpentity.Engine} engine the serpentity engine to
+ * which we are getting added
+ */
+ added(engine) {
+
+ this.renderables = engine.getNodes(RenderableNode);
+ this.renderables.on('nodeAdded', (event) => {
+
+ this._application.stage.addChild(event.node.container.container);
+ });
+ this.renderables.on('nodeRemoved', (event) => {
+
+ this._application.stage.removeChild(event.node.container.container);
+ });
+ }
+
+ /**
+ * Clears system resources when removed.
+ *
+ * @function removed
+ * @instance
+ * @memberof RenderSystem
+ */
+ removed() {
+
+ this.renderables.removeAllListeners('nodeAdded');
+ this.renderables.removeAllListeners('nodeRemoved');
+ this.renderables = null;
+ }
+
+ /**
+ * Runs on every update of the loop. Prints the location of every
+ * renderable
+ *
+ * @function update
+ * @instance
+ * @param {Number} currentFrameDuration the duration of the current
+ * frame
+ * @memberof RenderSystem
+ */
+ update(currentFrameDuration) {
+
+ for (const renderable of this.renderables) {
+ renderable.container.container.position.x = renderable.position.x;
+ renderable.container.container.position.y = renderable.position.y;
+ }
+ }
+};
diff --git a/package-lock.json b/package-lock.json
index 8dc6d98..43c41d3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,14 +5,22 @@
"requires": true,
"dependencies": {
"@serpentity/components.debug": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@serpentity/components.debug/-/components.debug-1.0.0.tgz",
- "integrity": "sha1-1mPRCQcWxVf3ShZYRDZjijWIfj4="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@serpentity/components.debug/-/components.debug-2.0.0.tgz",
+ "integrity": "sha512-IYFPQYuwhSSL6+jfQ5H9IVgkGwX2336Mowuk+8jK1t8Bqc373uZv6CPR3MSh/tc+Bi6bHEn+pZp1FMUxS8o12g=="
},
- "@serpentity/serpentity": {
+ "@serpentity/components.position": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@serpentity/serpentity/-/serpentity-2.0.0.tgz",
- "integrity": "sha1-MEbOJKQ80vXLUbaVnkhXqZ6Bbl4="
+ "resolved": "https://registry.npmjs.org/@serpentity/components.position/-/components.position-2.0.0.tgz",
+ "integrity": "sha512-umCLx12S3dV8d23bBSnB5CAvmqSjh9iCl2/JyOZmtOex2BkUUjIf2aqA3ZWVwpgoDmbPJMnejvghwuWHlkV4ww=="
+ },
+ "@serpentity/serpentity": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@serpentity/serpentity/-/serpentity-2.1.0.tgz",
+ "integrity": "sha512-tt+WMauSRdi/bnem9pxHfoOtpi17RZjgB/tQuNCK8X6EMcoly5FgjJotpsa4FsjpWARJvq9P2zJFilNwYOZRYg==",
+ "requires": {
+ "events": "2.0.0"
+ }
},
"@sindresorhus/is": {
"version": "0.7.0",
@@ -926,6 +934,25 @@
"babel-types": "6.26.0"
}
},
+ "babel-polyfill": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz",
+ "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "core-js": "2.5.5",
+ "regenerator-runtime": "0.10.5"
+ },
+ "dependencies": {
+ "regenerator-runtime": {
+ "version": "0.10.5",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz",
+ "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=",
+ "dev": true
+ }
+ }
+ },
"babel-preset-env": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz",
@@ -1196,6 +1223,11 @@
"integrity": "sha512-XBaoWE9RW8pPdPQNibZsW2zh8TW6gcarXp1FZPwT8Uop8ScSNldJEWf2k9l3HeTqdrEwsOsFcq74RiJECW34yA==",
"dev": true
},
+ "bit-twiddle": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bit-twiddle/-/bit-twiddle-1.0.2.tgz",
+ "integrity": "sha1-DGwfq+KyPRcXPZpht7cJPrnhdp4="
+ },
"bluebird": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
@@ -2229,6 +2261,11 @@
"stream-shift": "1.0.0"
}
},
+ "earcut": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.1.3.tgz",
+ "integrity": "sha512-AxdCdWUk1zzK/NuZ7e1ljj6IGC+VAdC3Qb7QQDsXpfNrc5IM8tL9nNXUmEGE6jRHTfZ10zhzRhtDmWVsR5pd3A=="
+ },
"editions": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz",
@@ -2522,11 +2559,15 @@
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
"dev": true
},
+ "eventemitter3": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
+ "integrity": "sha1-teEHm1n7XhuidxwKmTvgYKWMmbo="
+ },
"events": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
- "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=",
- "dev": true
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-2.0.0.tgz",
+ "integrity": "sha512-r/M5YkNg9zwI8QbSf7tsDWWJvO3PGwZXyG7GpFAxtMASnHL2eblFd7iHiGPtyGKKFPZ59S63NeX10Ws6WqGDcg=="
},
"evp_bytestokey": {
"version": "1.0.3",
@@ -4708,6 +4749,11 @@
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"dev": true
},
+ "ismobilejs": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/ismobilejs/-/ismobilejs-0.4.1.tgz",
+ "integrity": "sha1-Gl8SbHD+05yT2jgPpiy65XI+fcI="
+ },
"isobject": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
@@ -5567,6 +5613,11 @@
"integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4=",
"dev": true
},
+ "mini-signals": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mini-signals/-/mini-signals-1.2.0.tgz",
+ "integrity": "sha1-RbCAE8X65RokqhqTXNMXye1yHXQ="
+ },
"minimalistic-assert": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
@@ -5822,6 +5873,12 @@
"vm-browserify": "0.0.4"
},
"dependencies": {
+ "events": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
+ "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=",
+ "dev": true
+ },
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
@@ -5939,8 +5996,7 @@
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
- "dev": true
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"object-copy": {
"version": "0.1.0",
@@ -6275,6 +6331,11 @@
"integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
"dev": true
},
+ "parse-uri": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/parse-uri/-/parse-uri-1.0.0.tgz",
+ "integrity": "sha1-KHLcwi8aeXrN4Vg9igrClVLdrCA="
+ },
"pascalcase": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
@@ -6366,6 +6427,26 @@
"pinkie": "2.0.4"
}
},
+ "pixi-gl-core": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/pixi-gl-core/-/pixi-gl-core-1.1.4.tgz",
+ "integrity": "sha1-i0tcQzsx5Bm8N53FZc4bg1qRs3I="
+ },
+ "pixi.js": {
+ "version": "4.7.3",
+ "resolved": "https://registry.npmjs.org/pixi.js/-/pixi.js-4.7.3.tgz",
+ "integrity": "sha512-uYCTtjYiqSpwN2kZLmjwAL+1yrdCL/pVI+waYlkVqAHBnuQCpOuGA/0UunbxZ4T13xVZ4wN+ftPlEjxWl0th3w==",
+ "requires": {
+ "bit-twiddle": "1.0.2",
+ "earcut": "2.1.3",
+ "eventemitter3": "2.0.3",
+ "ismobilejs": "0.4.1",
+ "object-assign": "4.1.1",
+ "pixi-gl-core": "1.1.4",
+ "remove-array-items": "1.0.0",
+ "resource-loader": "2.1.1"
+ }
+ },
"pkg-dir": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
@@ -6803,6 +6884,11 @@
}
}
},
+ "remove-array-items": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/remove-array-items/-/remove-array-items-1.0.0.tgz",
+ "integrity": "sha1-B79CyzMvTPboXq2DteToltIyayE="
+ },
"remove-trailing-separator": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
@@ -6923,6 +7009,15 @@
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
"dev": true
},
+ "resource-loader": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/resource-loader/-/resource-loader-2.1.1.tgz",
+ "integrity": "sha512-jRMGYUfa4AGk9ib45Wxc93lobhQVoiCUAUkWqsbb/fhGPge97YT1S8aC0xBEQpolMsrdmB3o7SH8VmIEvIDOLA==",
+ "requires": {
+ "mini-signals": "1.2.0",
+ "parse-uri": "1.0.0"
+ }
+ },
"responselike": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
diff --git a/package.json b/package.json
index c7d0054..50f2a47 100644
--- a/package.json
+++ b/package.json
@@ -21,12 +21,15 @@
},
"homepage": "https://github.com/rbdr/sumo#readme",
"dependencies": {
- "@serpentity/components.debug": "^1.0.0",
- "@serpentity/serpentity": "^2.0.0"
+ "@serpentity/components.debug": "^2.0.0",
+ "@serpentity/components.position": "^2.0.0",
+ "@serpentity/serpentity": "^2.1.0",
+ "pixi.js": "^4.7.3"
},
"browserslist": "last two versions",
"devDependencies": {
"babel-core": "^6.26.0",
+ "babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.6.1",
"babel-loader": "^7.1.4",
"code": "^5.2.0",