diff options
| author | Rubén Beltrán del Río <ben@nsovocal.com> | 2018-04-20 16:41:25 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-04-20 16:41:25 -0500 |
| commit | 11be5ebabcdab8272d938f7b90ef0ea9be29a421 (patch) | |
| tree | b8ee06be115b2bbc1a74185711c96ba334bfdab4 /lib/sumo.js | |
| parent | 0ac89474ea22e706eb54c6ed4630a3337d438876 (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.js | 158 |
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); |