1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
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<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._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);
|