1 import 'babel-polyfill';
2 import PhysicsWorldControlSystem
from './systems/physics_world_control';
3 import PhysicsToAttributesSystem
from './systems/physics_to_attributes';
4 import CreateCouplingLineSystem
from './systems/create_coupling_line';
5 import RenderSystem
from './systems/render';
6 import AttributesToRenderableSystem
from './systems/attributes_to_renderable';
7 import SumoFactory
from './factories/sumo';
8 import Serpentity
from '@serpentity/serpentity';
9 import { Application
} from 'pixi.js';
10 import { Engine
} from 'matter-js';
12 /* global window document */
15 kBackgroundColor: 0xd8c590,
16 kNoElementError: 'No element found. Cannot render.',
18 // Handler for the window load event. Initializes and runs the app.
22 const sumo
= new internals
.Sumo({
23 element: document
.getElementById('sumo-app-entry-point')
28 internals
.exports
.sumo
= sumo
;
33 * Sumo - main entry point. Attached to window->load
37 * @param {object} config the configuration to extend the object
39 * @property {HTMLElement} [element=null] the element in which to render.
40 * Required, will throw if not provided
41 * @property {Number} [fps=60] the fps target to maintain
42 * @property {Number} [verticalResolution=224] how many pixels to render in the vertical
43 * axis (gets scaled if the canvas is larger)
44 * @property {Array<Number>} [aspectRatio=[2.76, 1]] the aspect ratio experssed as
45 * an array of two numbers, where aspect ratio x:y is [x, y] (eg. [16, 9])
48 internals
.Sumo
= class Sumo
{
53 this.aspectRatio
= [2.76, 1];
54 this.verticalResolution
= 224;
56 Object
.assign(this, config
);
59 throw new Error(internals
.kNoElementError
);
62 this._engine
= new Serpentity();
64 this._previousTime
= 0;
65 this._looping
= false;
67 // Initialization functions
68 this._initializeCanvas();
69 this._initializeMatter();
70 this._initializePixi();
71 this._initializeSystems();
72 this._initializeEntities();
76 * Starts the main loop. Resets the FPS (if you change it it won't go
77 * live until after you stop and start the loop)
86 this._frameDuration
= 1000 / this.fps
;
87 window
.requestAnimationFrame(this._loop
.bind(this));
99 this._looping
= false;
102 // The main loop used above. Runs the serpentity update process and
103 // attempts to maintain FPS. The rest is handled by the engine.
107 if (!this._looping
) {
111 window
.requestAnimationFrame(this._loop
.bind(this));
113 const currentFrameDuration
= currentTime
- this._previousTime
;
115 if (currentFrameDuration
> this._frameDuration
) {
117 // We're sending the currentTime since it gives better results for
118 // this type of renderer, though usually we expect the delta
119 this._engine
.update(currentTime
);
120 this._previousTime
= currentTime
;
124 // Creates a canvas for rendering
126 _initializeCanvas() {
128 this._canvas
= document
.createElement('canvas');
129 this.element
.appendChild(this._canvas
);
130 this._resizeCanvas();
131 window
.addEventListener('resize', this._resizeCanvas
.bind(this));
134 // Initialize MatterJs
136 _initializeMatter() {
138 this._matterJs
= Engine
.create();
140 this._matterJs
.world
.gravity
.y
= 0;
147 this._pixi
= new Application({
148 backgroundColor: internals
.kBackgroundColor
,
150 width: this._canvas
.width
,
151 height: this._canvas
.height
155 // Resizes the canvas to a square the size of the smallest magnitude
160 let width
= window
.innerWidth
;
161 let height
= Math
.round(width
* this.aspectRatio
[1] / this.aspectRatio
[0]);
163 if (window
.innerHeight
< height
) {
164 height
= window
.innerHeight
;
165 width
= Math
.round(height
* this.aspectRatio
[0] / this.aspectRatio
[1]);
168 this._canvas
.style
.width
= `${width}px`;
169 this._canvas
.style
.height
= `${height}px`;
171 this._canvas
.width
= Math
.round(this.verticalResolution
* this.aspectRatio
[0] / this.aspectRatio
[1]);
172 this._canvas
.height
= this.verticalResolution
;
175 // Initializes the serpentity systems
177 _initializeSystems() {
179 this._engine
.addSystem(new PhysicsWorldControlSystem({
180 engine: this._matterJs
183 this._engine
.addSystem(new PhysicsToAttributesSystem());
185 this._engine
.addSystem(new AttributesToRenderableSystem());
187 this._engine
.addSystem(new CreateCouplingLineSystem());
189 this._engine
.addSystem(new RenderSystem({
190 application: this._pixi
194 // Initializes the serpentity entities
196 _initializeEntities() {
198 const entityA
= SumoFactory
.createSumo(null, {
205 const entityB
= SumoFactory
.createSumo(null, {
212 const entityC
= SumoFactory
.createSumo(null, {
219 SumoFactory
.createRubberBand(this._engine
, {
224 SumoFactory
.createRubberBand(this._engine
, {
229 // To keep the coupling behind, we'll manually add the sumos later
231 this._engine
.addEntity(entityA
);
232 this._engine
.addEntity(entityB
);
233 this._engine
.addEntity(entityC
);
237 export default internals
.exports
= {};
240 window
.addEventListener('load', internals
.onLoad
);