-import Serpentity from '@serpentity/serpentity';
+import Config from './config';
+
+// Systems
+
+import ApplyForceSystem from './systems/apply_force';
+import CreateCouplingLineSystem from './systems/create_coupling_line';
+import ControlMapperSystem from './systems/control_mapper';
+import DashSystem from './systems/dash';
+import DetectPointsCollisionSystem from './systems/detect_points_collision';
+import DetectWinnerSystem from './systems/detect_winner';
+import DrawDashSystem from './systems/draw_dash';
+import DrawGrabSystem from './systems/draw_grab';
+import ElasticSystem from './systems/elastic';
+import GrabSystem from './systems/grab';
+import PhysicsWorldControlSystem from './systems/physics_world_control';
+import PhysicsToAttributesSystem from './systems/physics_to_attributes';
+import RenderPointsSystem from './systems/render_points';
+import RenderSystem from './systems/render';
+import RenderWinnerSystem from './systems/render_winner';
+import AttributesToRenderableSystem from './systems/attributes_to_renderable';
+
+// Factories
-/* global window document */
+import SumoFactory from './factories/sumo';
+
+// External Dependencies
+
+import Serpentity from '@serpentity/serpentity';
+import { Application } from 'pixi.js';
+import { Engine } from 'matter-js';
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({
+ const sumo = new internals.Sumo(Object.assign({
element: document.getElementById('sumo-app-entry-point')
- });
+ }, Config));
sumo.startLoop();
- internals.exports.sumo = sumo;
+ window.sumo = sumo;
}
};
constructor(config) {
+ // These defaults can get overridden by config
this.fps = 60;
this.aspectRatio = [2.76, 1];
this.verticalResolution = 224;
// Initialization functions
this._initializeCanvas();
+ this._initializeMatter();
+ this._initializePixi();
this._initializeSystems();
this._initializeEntities();
}
// 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._engine.update(currentFrameDuration);
this._previousTime = currentTime;
}
}
window.addEventListener('resize', this._resizeCanvas.bind(this));
}
+ // Initialize MatterJs
+
+ _initializeMatter() {
+
+ this._matterJs = Engine.create();
+
+ this._matterJs.world.gravity.y = 0;
+ }
+
+ // 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.
_initializeSystems() {
+ this._engine.addSystem(new ControlMapperSystem());
+
+ this._engine.addSystem(new DashSystem());
+
+ this._engine.addSystem(new GrabSystem({
+ engine: this._matterJs
+ }));
+
+ this._engine.addSystem(new ApplyForceSystem());
+
+ this._engine.addSystem(new PhysicsWorldControlSystem({
+ engine: this._matterJs
+ }));
+
+ this._engine.addSystem(new DetectPointsCollisionSystem());
+
+ this._engine.addSystem(new DetectWinnerSystem());
+
+ this._engine.addSystem(new RenderPointsSystem({
+ application: this._pixi
+ }));
+
+ this._engine.addSystem(new RenderWinnerSystem({
+ application: this._pixi
+ }));
+
+ this._engine.addSystem(new ElasticSystem());
+
+ this._engine.addSystem(new PhysicsToAttributesSystem());
+
+ this._engine.addSystem(new AttributesToRenderableSystem());
+
+ this._engine.addSystem(new CreateCouplingLineSystem());
+
+ this._engine.addSystem(new DrawDashSystem());
+
+ this._engine.addSystem(new DrawGrabSystem());
+
+ this._engine.addSystem(new RenderSystem({
+ application: this._pixi
+ }));
}
// Initializes the serpentity entities
_initializeEntities() {
+ SumoFactory.createArena(this._engine, {
+ position: {
+ x: this.horizontalResolution / 2,
+ y: this.verticalResolution / 2
+ }
+ });
+
+ const sumoA = SumoFactory.createPlayer1Sumo(null, {
+ position: {
+ x: this.horizontalResolution / 2 - 100,
+ y: this.verticalResolution / 2
+ }
+ });
+
+ const sumoB = SumoFactory.createPlayer2Sumo(null, {
+ position: {
+ x: this.horizontalResolution / 2 + 100,
+ y: this.verticalResolution / 2
+ }
+ });
+
+ const harness = SumoFactory.createHarness(null, {
+ position: {
+ x: this.horizontalResolution / 2,
+ y: this.verticalResolution / 2
+ }
+ });
+
+ SumoFactory.createRubberBand(this._engine, {
+ entityA: sumoA,
+ entityB: harness
+ });
+
+ SumoFactory.createRubberBand(this._engine, {
+ entityA: sumoB,
+ entityB: harness
+ });
+
+ // Walls
+
+ SumoFactory.createInvisibleBlock(this._engine, {
+ width: this.horizontalResolution * 2,
+ height: this.verticalResolution * 0.1,
+ position: {
+ x: this.horizontalResolution / 2,
+ y: -this.verticalResolution * 0.1
+ }
+ });
+
+ SumoFactory.createInvisibleBlock(this._engine, {
+ width: this.horizontalResolution * 2,
+ height: this.verticalResolution * 0.1,
+ position: {
+ x: this.horizontalResolution / 2,
+ y: this.verticalResolution + this.verticalResolution * 0.1
+ }
+ });
+
+ // Points Detector
+
+ SumoFactory.createPointsCollider(this._engine, {
+ collisionTarget: sumoA,
+ pointsTarget: 'red',
+ height: this.verticalResolution,
+ width: this.horizontalResolution,
+ position: {
+ x: this.horizontalResolution + this.horizontalResolution / 2,
+ y: this.verticalResolution / 2
+ }
+ });
+
+ SumoFactory.createPointsCollider(this._engine, {
+ collisionTarget: sumoB,
+ pointsTarget: 'blue',
+ height: this.verticalResolution,
+ width: this.horizontalResolution,
+ position: {
+ x: -this.horizontalResolution / 2,
+ y: this.verticalResolution / 2
+ }
+ });
+
+ // The game state
+ SumoFactory.createGameState(this._engine);
+
+ // To keep the coupling behind, we'll manually add the sumos later
+
+ this._engine.addEntity(sumoA);
+ this._engine.addEntity(sumoB);
+ this._engine.addEntity(harness);
}
};