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. 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} [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._initializePixi(); 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)); } // 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. _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() { 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 } }); } }; export default internals.exports = {}; // autorun.bat window.addEventListener('load', internals.onLoad);