aboutsummaryrefslogtreecommitdiff
path: root/lib/sumo.js
diff options
context:
space:
mode:
authorRubén Beltrán del Río <ben@nsovocal.com>2018-04-20 16:41:25 -0500
committerGitHub <noreply@github.com>2018-04-20 16:41:25 -0500
commit11be5ebabcdab8272d938f7b90ef0ea9be29a421 (patch)
treeb8ee06be115b2bbc1a74185711c96ba334bfdab4 /lib/sumo.js
parent0ac89474ea22e706eb54c6ed4630a3337d438876 (diff)
Initial Project Setup (#2)
* 🔧 Add initial package.json * 🔧 Add eslint config * 🔧 Add assets target dir to gitignore * 🔧 Add webpack config * Add a contributing guide * Add the wrapper application * Add autogenerated docs * Add travis config * Add changelog
Diffstat (limited to 'lib/sumo.js')
-rw-r--r--lib/sumo.js158
1 files changed, 158 insertions, 0 deletions
diff --git a/lib/sumo.js b/lib/sumo.js
new file mode 100644
index 0000000..da72991
--- /dev/null
+++ b/lib/sumo.js
@@ -0,0 +1,158 @@
+import Serpentity from '@serpentity/serpentity';
+
+/* global window document */
+
+const internals = {
+ kNoElementError: 'No element found. Cannot render.',
+
+ // Handler for the window load event. Initializes and runs the app.
+
+ onLoad() {
+
+ const sumo = new internals.Sumo({
+ element: document.getElementById('sumo-app-entry-point')
+ });
+
+ sumo.startLoop();
+
+ internals.exports.sumo = sumo;
+ }
+};
+
+/**
+ * Sumo - main entry point. Attached to window->load
+ *
+ * @class Sumo
+ *
+ * @param {object} config the configuration to extend the object
+ *
+ * @property {HTMLElement} [element=null] the element in which to render.
+ * Required, will throw if not provided
+ * @property {Number} [fps=60] the fps target to maintain
+ * @property {Number} [verticalResolution=224] how many pixels to render in the vertical
+ * axis (gets scaled if the canvas is larger)
+ * @property {Array<Number>} [aspectRatio=[2.76, 1]] the aspect ratio experssed as
+ * an array of two numbers, where aspect ratio x:y is [x, y] (eg. [16, 9])
+ */
+
+internals.Sumo = class Sumo {
+
+ constructor(config) {
+
+ this.fps = 60;
+ this.aspectRatio = [2.76, 1];
+ this.verticalResolution = 224;
+
+ Object.assign(this, config);
+
+ if (!this.element) {
+ throw new Error(internals.kNoElementError);
+ }
+
+ this._engine = new Serpentity();
+
+ this._previousTime = 0;
+ this._looping = false;
+
+ // Initialization functions
+ this._initializeCanvas();
+ this._initializeSystems();
+ this._initializeEntities();
+ }
+
+ /**
+ * Starts the main loop. Resets the FPS (if you change it it won't go
+ * live until after you stop and start the loop)
+ *
+ * @function startLoop
+ * @instance
+ * @memberof Sumo
+ */
+ startLoop() {
+
+ this._looping = true;
+ this._frameDuration = 1000 / this.fps;
+ window.requestAnimationFrame(this._loop.bind(this));
+ }
+
+ /**
+ * Pauses the loop
+ *
+ * @function pauseLoop
+ * @instance
+ * @memberof Sumo
+ */
+ pauseLoop() {
+
+ this._looping = false;
+ }
+
+ // The main loop used above. Runs the serpentity update process and
+ // attempts to maintain FPS. The rest is handled by the engine.
+
+ _loop(currentTime) {
+
+ if (!this._looping) {
+ return;
+ }
+
+ window.requestAnimationFrame(this._loop.bind(this));
+
+ const currentFrameDuration = currentTime - this._previousTime;
+
+ if (currentFrameDuration > this._frameDuration) {
+
+ // We're sending the currentTime since it gives better results for
+ // this type of renderer, though usually we expect the delta
+ this._engine.update(currentTime);
+ this._previousTime = currentTime;
+ }
+ }
+
+ // Creates a canvas for rendering
+
+ _initializeCanvas() {
+
+ this._canvas = document.createElement('canvas');
+ this.element.appendChild(this._canvas);
+ this._resizeCanvas();
+ window.addEventListener('resize', this._resizeCanvas.bind(this));
+ }
+
+ // Resizes the canvas to a square the size of the smallest magnitude
+ // of the window.
+
+ _resizeCanvas() {
+
+ let width = window.innerWidth;
+ let height = Math.round(width * this.aspectRatio[1] / this.aspectRatio[0]);
+
+ if (window.innerHeight < height) {
+ height = window.innerHeight;
+ width = Math.round(height * this.aspectRatio[0] / this.aspectRatio[1]);
+ }
+
+ this._canvas.style.width = `${width}px`;
+ this._canvas.style.height = `${height}px`;
+
+ this._canvas.width = Math.round(this.verticalResolution * this.aspectRatio[0] / this.aspectRatio[1]);
+ this._canvas.height = this.verticalResolution;
+ }
+
+ // Initializes the serpentity systems
+
+ _initializeSystems() {
+
+ }
+
+ // Initializes the serpentity entities
+
+ _initializeEntities() {
+
+ }
+};
+
+export default internals.exports = {};
+
+// autorun.bat
+window.addEventListener('load', internals.onLoad);