core2d 2.11.1 → 2.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/Engine.mjs CHANGED
@@ -19,452 +19,452 @@ const DEFAULT_FRAME_TIME = 16;
19
19
  const DEGRADATION_TOLERANCE = 10;
20
20
 
21
21
  export const Engine = (() => {
22
- const RENDER_STRATEGY = {
23
- DEFAULT: () => {
24
- ACL.window.requestAnimationFrame(render);
25
- },
26
-
27
- DEGRADED: () => {
28
- render();
29
- },
30
- };
31
-
32
- const RENDER_STRATEGIES = [RENDER_STRATEGY.DEFAULT, RENDER_STRATEGY.DEGRADED];
33
-
34
- let _autoScale = true;
35
- let _canvas =
36
- Static.getElement("app") || Static.getElements(CANVAS_ELEMENT)[0];
37
- let _context = _canvas.getContext(CONTEXT);
38
- let _degraded = 0;
39
- let _everyOther = true;
40
- let _frameTime = DEFAULT_FRAME_TIME;
41
- let _fullScreen = false;
42
- let _height = _canvas.height;
43
- let _imageCache = {};
44
- let _keepAspect = false;
45
- let _input = new Input();
46
- let _lastRender;
47
- let _name = "Game";
48
- let _realHeight = _canvas.height;
49
- let _realWidth = _canvas.width;
50
- let _renderableLists = [];
51
- let _renderStrategy = 0;
52
- let _scene;
53
- let _sound = new Sound();
54
- let _transition;
55
- let _width = _canvas.width;
56
-
57
- class Engine {
58
- static init(scene) {
59
- _scene = scene;
60
- boot(_canvas, _context);
61
- }
62
-
63
- static get bottom() {
64
- return _height - 1;
65
- }
66
-
67
- static get center() {
68
- return new Point(this.centerX, this.centerY);
69
- }
70
-
71
- static get centerX() {
72
- return Math.floor(_width / 2);
73
- }
74
-
75
- static get centerY() {
76
- return Math.floor(_height / 2);
77
- }
78
-
79
- static get height() {
80
- return _height;
81
- }
82
-
83
- static getName() {
84
- return _name;
85
- }
86
-
87
- static get offsetLeft() {
88
- return _canvas.offsetLeft;
89
- }
90
-
91
- static get offsetTop() {
92
- return _canvas.offsetTop;
93
- }
94
-
95
- static get right() {
96
- return _width - 1;
97
- }
98
-
99
- static get everyOther() {
100
- return _everyOther;
101
- }
102
-
103
- static get frameTime() {
104
- return _frameTime;
105
- }
106
-
107
- static get realHeight() {
108
- return _realHeight;
109
- }
110
-
111
- static get realWidth() {
112
- return _realWidth;
113
- }
114
-
115
- static get width() {
116
- return _width;
117
- }
118
-
119
- static addControllerDevice(device) {
120
- _input.addController(device);
121
- }
122
-
123
- static clear() {
124
- _context.clearRect(0, 0, _width, _height);
125
- }
126
-
127
- static colorize(
128
- image,
129
- fillStyle,
130
- compositeOperation = CompositeOperations.SOURCE_IN
131
- ) {
132
- const input = Static.getImage(image);
133
- const output = ACL.document.createElement(CANVAS_ELEMENT);
134
- output.width = input.width;
135
- output.height = input.height;
136
- const context = output.getContext(CONTEXT);
137
- context.drawImage(input, 0, 0);
138
- context.globalCompositeOperation = compositeOperation;
139
- context.fillStyle = fillStyle;
140
- context.fillRect(0, 0, output.width, output.height);
141
- return output;
142
- }
143
-
144
- static fadeOut() {
145
- _sound.fadeOut();
146
- }
147
-
148
- static flip(image) {
149
- return invert(image, false, true);
150
- }
151
-
152
- static getController(id) {
153
- return _input.getController(id);
154
- }
155
-
156
- static get controller() {
157
- return this.getController();
158
- }
159
-
160
- static getPointer(id) {
161
- return _input.getPointer(id);
162
- }
163
-
164
- static get pointer() {
165
- return this.getPointer();
166
- }
167
-
168
- static load(namespace) {
169
- const container = localStorage[namespace ?? Engine.getName()];
170
- let result;
171
-
172
- try {
173
- result = container && JSON.parse(container);
174
- } catch (error) {
175
- console.log("Could not load saved game: " + error);
176
- }
177
-
178
- return result;
179
- }
180
-
181
- static mirror(image) {
182
- return invert(image, true, false);
183
- }
184
-
185
- static mute() {
186
- _sound.mute();
187
- }
188
-
189
- static paint(renderable, index = 0) {
190
- if (index >= _renderableLists.length) {
191
- for (let i = _renderableLists.length; i <= index; ++i) {
192
- _renderableLists.push(new RenderableList());
193
- }
194
- }
195
-
196
- _renderableLists[index].add(renderable);
197
- }
198
-
199
- static play(id, volume) {
200
- _sound.play(id, volume);
201
- }
202
-
203
- static playTheme(name) {
204
- _sound.playTheme(name);
205
- }
206
-
207
- static random(max) {
208
- return Math.floor(Math.random() * (max + 1));
209
- }
210
-
211
- static rotate(image, degrees) {
212
- const input = Static.getImage(image);
213
- degrees = degrees % 360;
214
-
215
- if (degrees == 0) {
216
- return input;
217
- }
218
-
219
- const output = ACL.document.createElement(CANVAS_ELEMENT);
220
- output.width = input.width;
221
- output.height = input.height;
222
- const context = output.getContext(CONTEXT);
223
- context.translate(output.width / 2, output.height / 2);
224
- context.rotate(Static.toRadians(degrees));
225
- context.drawImage(input, -input.width / 2, -input.height / 2);
226
- return output;
227
- }
228
-
229
- static save(data, namespace) {
230
- try {
231
- localStorage[namespace || Engine.getName()] =
232
- data && JSON.stringify(data);
233
- } catch (error) {
234
- console.log("Could not save current game: " + error);
235
- }
236
- }
237
-
238
- static setAutoScale(customAutoScale = true) {
239
- _autoScale = customAutoScale;
240
- }
241
-
242
- static setFrameTime(frameTime) {
243
- _frameTime = frameTime ?? DEFAULT_FRAME_TIME;
244
- }
245
-
246
- static setFullScreen(customFullScreen = true) {
247
- _fullScreen = customFullScreen;
248
- }
249
-
250
- static setKeepAspect(customKeepAspect = true) {
251
- _keepAspect = customKeepAspect;
252
- }
253
-
254
- static setName(name) {
255
- _name = name;
256
- document && (ACL.document.title = _name);
257
- }
258
-
259
- static stopTheme() {
260
- _sound.stopTheme();
261
- }
262
-
263
- // factories
264
- static animation(frames) {
265
- return new Animation(frames);
266
- }
267
-
268
- static frame(image, duration) {
269
- return new Frame(image, duration);
270
- }
271
-
272
- static image(id, isMirror, isFlip) {
273
- if (isFlip && isMirror) {
274
- if (_imageCache[id] && _imageCache[id].flipMirror) {
275
- return _imageCache[id].flipMirror;
276
- }
277
-
278
- _imageCache[id] = _imageCache[id] || {};
279
- _imageCache[id].flipMirror = invert(Static.getElement(id), true, true);
280
- return _imageCache[id].flip;
281
- }
282
-
283
- if (isFlip) {
284
- if (_imageCache[id] && _imageCache[id].flip) {
285
- return _imageCache[id].flip;
286
- }
287
-
288
- _imageCache[id] = _imageCache[id] || {};
289
- _imageCache[id].flip = Engine.flip(Static.getElement(id));
290
- return _imageCache[id].flip;
291
- }
292
-
293
- if (isMirror) {
294
- if (_imageCache[id] && _imageCache[id].mirror) {
295
- return _imageCache[id].mirror;
296
- }
297
-
298
- _imageCache[id] = _imageCache[id] || {};
299
- _imageCache[id].mirror = Engine.mirror(Static.getElement(id));
300
- return _imageCache[id].mirror;
301
- }
302
-
303
- return Static.getElement(id);
304
- }
305
-
306
- static point(x, y) {
307
- return new Point(x, y);
308
- }
309
-
310
- static rect(x, y, width, height) {
311
- return new Rect(x, y, width, height);
312
- }
313
-
314
- static scene() {
315
- return new Scene();
316
- }
317
-
318
- static sprite(scene) {
319
- return new Sprite(scene);
320
- }
321
- }
322
-
323
- function boot(canvas, context) {
324
- _canvas.style.transform = "translateZ(0)";
325
- addEventListener("blur", focus, false);
326
- addEventListener("click", focus, false);
327
- addEventListener("focus", focus, false);
328
- addEventListener("load", focus, false);
329
- addEventListener("resize", scale, false);
330
- // focus(); // TODO: test all platforms before finally removing it
331
- scale();
332
- const images = Static.getElements("img");
333
- const total = images.length;
334
- let complete = 0;
335
-
336
- for (let i = 0; i < images.length; ++i) {
337
- const IMAGE = images[i];
338
-
339
- if (IMAGE.complete) {
340
- ++complete;
341
- }
342
- }
343
-
344
- context.fillStyle = Color.Blue;
345
- context.fillRect(0, 0, (canvas.width * complete) / total, canvas.height);
346
-
347
- if (complete < total) {
348
- setTimeout(() => {
349
- boot(canvas, context);
350
- }, 100);
351
-
352
- return;
353
- }
354
-
355
- initScene();
356
- _lastRender = Date.now();
357
- loop();
358
- }
359
-
360
- function focus() {
361
- ACL.window.focus();
362
-
363
- if (_fullScreen && _canvas.requestFullscreen) {
364
- _canvas.requestFullscreen().catch((error) => {
365
- console.warn("Could not request full screen", error);
366
- });
367
- }
368
- }
369
-
370
- function initScene() {
371
- if (!_scene) {
372
- throw new Error("Could not get the next scene");
373
- }
374
-
375
- _scene.scene = new Point();
376
- _scene.height = _scene.height || _height;
377
- _scene.width = _scene.width || _width;
378
- _scene.init();
379
- }
380
-
381
- function invert(image, isMirror, isFlip) {
382
- const input = Static.getImage(image);
383
- const output = ACL.document.createElement(CANVAS_ELEMENT);
384
- output.width = input.width;
385
- output.height = input.height;
386
- const context = output.getContext(CONTEXT);
387
- context.translate(isMirror ? output.width : 0, isFlip ? output.height : 0);
388
- context.scale(isMirror ? -1 : 1, isFlip ? -1 : 1);
389
- context.drawImage(input, 0, 0);
390
- return output;
391
- }
392
-
393
- function loop() {
394
- _everyOther = !_everyOther;
395
- _input.update();
396
-
397
- if (_transition != null) {
398
- if (_transition.sync()) {
399
- _transition = null;
400
- initScene();
401
- } else {
402
- Engine.paint(_transition);
403
- }
404
- } else {
405
- if (_scene.sync()) {
406
- _transition = _scene.transition;
407
-
408
- if (_transition) {
409
- _transition.scene = _scene;
410
- _transition.init();
411
- }
412
-
413
- _scene = _scene.next;
414
-
415
- if (!_transition) {
416
- initScene();
417
- }
418
- }
419
- }
420
-
421
- _sound.update();
422
- RENDER_STRATEGIES[_renderStrategy]();
423
- }
424
-
425
- function render() {
426
- for (let i = 0; i < _renderableLists.length; ++i) {
427
- _renderableLists[i].render(_context);
428
- }
429
-
430
- const timeout = _frameTime + _lastRender - Date.now();
431
-
432
- if (timeout < 0 && ++_degraded > DEGRADATION_TOLERANCE) {
433
- if (++_renderStrategy > RENDER_STRATEGIES.length - 1) {
434
- _renderStrategy = 0;
435
- }
436
- }
437
-
438
- setTimeout(loop, timeout);
439
- _lastRender = Date.now();
440
- }
441
-
442
- function scale() {
443
- if (!_autoScale) {
444
- return;
445
- }
446
-
447
- let width, height;
448
-
449
- if (_keepAspect) {
450
- let proportion = ACL.window.innerWidth / _canvas.width;
451
-
452
- if (ACL.window.innerHeight < _canvas.height * proportion) {
453
- proportion = ACL.window.innerHeight / _canvas.height;
454
- }
455
-
456
- width = _canvas.width * proportion;
457
- height = _canvas.height * proportion;
458
- } else {
459
- width = ACL.window.innerWidth;
460
- height = ACL.window.innerHeight;
461
- }
462
-
463
- _realWidth = width;
464
- _realHeight = height;
465
- _canvas.style.width = width + "px";
466
- _canvas.style.height = height + "px";
467
- }
468
-
469
- return Engine;
22
+ const RENDER_STRATEGY = {
23
+ DEFAULT: () => {
24
+ ACL.window.requestAnimationFrame(render);
25
+ },
26
+
27
+ DEGRADED: () => {
28
+ render();
29
+ },
30
+ };
31
+
32
+ const RENDER_STRATEGIES = [RENDER_STRATEGY.DEFAULT, RENDER_STRATEGY.DEGRADED];
33
+
34
+ let _autoScale = true;
35
+ let _canvas =
36
+ Static.getElement("app") || Static.getElements(CANVAS_ELEMENT)[0];
37
+ let _context = _canvas.getContext(CONTEXT);
38
+ let _degraded = 0;
39
+ let _everyOther = true;
40
+ let _frameTime = DEFAULT_FRAME_TIME;
41
+ let _fullScreen = false;
42
+ let _height = _canvas.height;
43
+ let _imageCache = {};
44
+ let _keepAspect = false;
45
+ let _input = new Input();
46
+ let _lastRender;
47
+ let _name = "Game";
48
+ let _realHeight = _canvas.height;
49
+ let _realWidth = _canvas.width;
50
+ let _renderableLists = [];
51
+ let _renderStrategy = 0;
52
+ let _scene;
53
+ let _sound = new Sound();
54
+ let _transition;
55
+ let _width = _canvas.width;
56
+
57
+ class Engine {
58
+ static init(scene) {
59
+ _scene = scene;
60
+ boot(_canvas, _context);
61
+ }
62
+
63
+ static get bottom() {
64
+ return _height - 1;
65
+ }
66
+
67
+ static get center() {
68
+ return new Point(this.centerX, this.centerY);
69
+ }
70
+
71
+ static get centerX() {
72
+ return Math.floor(_width / 2);
73
+ }
74
+
75
+ static get centerY() {
76
+ return Math.floor(_height / 2);
77
+ }
78
+
79
+ static get height() {
80
+ return _height;
81
+ }
82
+
83
+ static getName() {
84
+ return _name;
85
+ }
86
+
87
+ static get offsetLeft() {
88
+ return _canvas.offsetLeft;
89
+ }
90
+
91
+ static get offsetTop() {
92
+ return _canvas.offsetTop;
93
+ }
94
+
95
+ static get right() {
96
+ return _width - 1;
97
+ }
98
+
99
+ static get everyOther() {
100
+ return _everyOther;
101
+ }
102
+
103
+ static get frameTime() {
104
+ return _frameTime;
105
+ }
106
+
107
+ static get realHeight() {
108
+ return _realHeight;
109
+ }
110
+
111
+ static get realWidth() {
112
+ return _realWidth;
113
+ }
114
+
115
+ static get width() {
116
+ return _width;
117
+ }
118
+
119
+ static addControllerDevice(device) {
120
+ _input.addController(device);
121
+ }
122
+
123
+ static clear() {
124
+ _context.clearRect(0, 0, _width, _height);
125
+ }
126
+
127
+ static colorize(
128
+ image,
129
+ fillStyle,
130
+ compositeOperation = CompositeOperations.SOURCE_IN
131
+ ) {
132
+ const input = Static.getImage(image);
133
+ const output = ACL.document.createElement(CANVAS_ELEMENT);
134
+ output.width = input.width;
135
+ output.height = input.height;
136
+ const context = output.getContext(CONTEXT);
137
+ context.drawImage(input, 0, 0);
138
+ context.globalCompositeOperation = compositeOperation;
139
+ context.fillStyle = fillStyle;
140
+ context.fillRect(0, 0, output.width, output.height);
141
+ return output;
142
+ }
143
+
144
+ static fadeOut() {
145
+ _sound.fadeOut();
146
+ }
147
+
148
+ static flip(image) {
149
+ return invert(image, false, true);
150
+ }
151
+
152
+ static getController(id) {
153
+ return _input.getController(id);
154
+ }
155
+
156
+ static get controller() {
157
+ return this.getController();
158
+ }
159
+
160
+ static getPointer(id) {
161
+ return _input.getPointer(id);
162
+ }
163
+
164
+ static get pointer() {
165
+ return this.getPointer();
166
+ }
167
+
168
+ static load(namespace) {
169
+ const container = localStorage[namespace ?? Engine.getName()];
170
+ let result;
171
+
172
+ try {
173
+ result = container && JSON.parse(container);
174
+ } catch (error) {
175
+ console.log("Could not load saved game: " + error);
176
+ }
177
+
178
+ return result;
179
+ }
180
+
181
+ static mirror(image) {
182
+ return invert(image, true, false);
183
+ }
184
+
185
+ static mute() {
186
+ _sound.mute();
187
+ }
188
+
189
+ static paint(renderable, index = 0) {
190
+ if (index >= _renderableLists.length) {
191
+ for (let i = _renderableLists.length; i <= index; ++i) {
192
+ _renderableLists.push(new RenderableList());
193
+ }
194
+ }
195
+
196
+ _renderableLists[index].add(renderable);
197
+ }
198
+
199
+ static play(id, volume) {
200
+ _sound.play(id, volume);
201
+ }
202
+
203
+ static playTheme(name) {
204
+ _sound.playTheme(name);
205
+ }
206
+
207
+ static random(max) {
208
+ return Math.floor(Math.random() * (max + 1));
209
+ }
210
+
211
+ static rotate(image, degrees) {
212
+ const input = Static.getImage(image);
213
+ degrees = degrees % 360;
214
+
215
+ if (degrees == 0) {
216
+ return input;
217
+ }
218
+
219
+ const output = ACL.document.createElement(CANVAS_ELEMENT);
220
+ output.width = input.width;
221
+ output.height = input.height;
222
+ const context = output.getContext(CONTEXT);
223
+ context.translate(output.width / 2, output.height / 2);
224
+ context.rotate(Static.toRadians(degrees));
225
+ context.drawImage(input, -input.width / 2, -input.height / 2);
226
+ return output;
227
+ }
228
+
229
+ static save(data, namespace) {
230
+ try {
231
+ localStorage[namespace || Engine.getName()] =
232
+ data && JSON.stringify(data);
233
+ } catch (error) {
234
+ console.log("Could not save current game: " + error);
235
+ }
236
+ }
237
+
238
+ static setAutoScale(customAutoScale = true) {
239
+ _autoScale = customAutoScale;
240
+ }
241
+
242
+ static setFrameTime(frameTime) {
243
+ _frameTime = frameTime ?? DEFAULT_FRAME_TIME;
244
+ }
245
+
246
+ static setFullScreen(customFullScreen = true) {
247
+ _fullScreen = customFullScreen;
248
+ }
249
+
250
+ static setKeepAspect(customKeepAspect = true) {
251
+ _keepAspect = customKeepAspect;
252
+ }
253
+
254
+ static setName(name) {
255
+ _name = name;
256
+ document && (ACL.document.title = _name);
257
+ }
258
+
259
+ static stopTheme() {
260
+ _sound.stopTheme();
261
+ }
262
+
263
+ // factories
264
+ static animation(frames) {
265
+ return new Animation(frames);
266
+ }
267
+
268
+ static frame(image, duration) {
269
+ return new Frame(image, duration);
270
+ }
271
+
272
+ static image(id, isMirror, isFlip) {
273
+ if (isFlip && isMirror) {
274
+ if (_imageCache[id] && _imageCache[id].flipMirror) {
275
+ return _imageCache[id].flipMirror;
276
+ }
277
+
278
+ _imageCache[id] = _imageCache[id] || {};
279
+ _imageCache[id].flipMirror = invert(Static.getElement(id), true, true);
280
+ return _imageCache[id].flip;
281
+ }
282
+
283
+ if (isFlip) {
284
+ if (_imageCache[id] && _imageCache[id].flip) {
285
+ return _imageCache[id].flip;
286
+ }
287
+
288
+ _imageCache[id] = _imageCache[id] || {};
289
+ _imageCache[id].flip = Engine.flip(Static.getElement(id));
290
+ return _imageCache[id].flip;
291
+ }
292
+
293
+ if (isMirror) {
294
+ if (_imageCache[id] && _imageCache[id].mirror) {
295
+ return _imageCache[id].mirror;
296
+ }
297
+
298
+ _imageCache[id] = _imageCache[id] || {};
299
+ _imageCache[id].mirror = Engine.mirror(Static.getElement(id));
300
+ return _imageCache[id].mirror;
301
+ }
302
+
303
+ return Static.getElement(id);
304
+ }
305
+
306
+ static point(x, y) {
307
+ return new Point(x, y);
308
+ }
309
+
310
+ static rect(x, y, width, height) {
311
+ return new Rect(x, y, width, height);
312
+ }
313
+
314
+ static scene() {
315
+ return new Scene();
316
+ }
317
+
318
+ static sprite(scene) {
319
+ return new Sprite(scene);
320
+ }
321
+ }
322
+
323
+ function boot(canvas, context) {
324
+ _canvas.style.transform = "translateZ(0)";
325
+ addEventListener("blur", focus, false);
326
+ addEventListener("click", focus, false);
327
+ addEventListener("focus", focus, false);
328
+ addEventListener("load", focus, false);
329
+ addEventListener("resize", scale, false);
330
+ // focus(); // TODO: test all platforms before finally removing it
331
+ scale();
332
+ const images = Static.getElements("img");
333
+ const total = images.length;
334
+ let complete = 0;
335
+
336
+ for (let i = 0; i < images.length; ++i) {
337
+ const IMAGE = images[i];
338
+
339
+ if (IMAGE.complete) {
340
+ ++complete;
341
+ }
342
+ }
343
+
344
+ context.fillStyle = Color.Blue;
345
+ context.fillRect(0, 0, (canvas.width * complete) / total, canvas.height);
346
+
347
+ if (complete < total) {
348
+ setTimeout(() => {
349
+ boot(canvas, context);
350
+ }, 100);
351
+
352
+ return;
353
+ }
354
+
355
+ initScene();
356
+ _lastRender = Date.now();
357
+ loop();
358
+ }
359
+
360
+ function focus() {
361
+ ACL.window.focus();
362
+
363
+ if (_fullScreen && _canvas.requestFullscreen) {
364
+ _canvas.requestFullscreen().catch((error) => {
365
+ console.warn("Could not request full screen", error);
366
+ });
367
+ }
368
+ }
369
+
370
+ function initScene() {
371
+ if (!_scene) {
372
+ throw new Error("Could not get the next scene");
373
+ }
374
+
375
+ _scene.scene = new Point();
376
+ _scene.height = _scene.height || _height;
377
+ _scene.width = _scene.width || _width;
378
+ _scene.init();
379
+ }
380
+
381
+ function invert(image, isMirror, isFlip) {
382
+ const input = Static.getImage(image);
383
+ const output = ACL.document.createElement(CANVAS_ELEMENT);
384
+ output.width = input.width;
385
+ output.height = input.height;
386
+ const context = output.getContext(CONTEXT);
387
+ context.translate(isMirror ? output.width : 0, isFlip ? output.height : 0);
388
+ context.scale(isMirror ? -1 : 1, isFlip ? -1 : 1);
389
+ context.drawImage(input, 0, 0);
390
+ return output;
391
+ }
392
+
393
+ function loop() {
394
+ _everyOther = !_everyOther;
395
+ _input.update();
396
+
397
+ if (_transition != null) {
398
+ if (_transition.sync()) {
399
+ _transition = null;
400
+ initScene();
401
+ } else {
402
+ Engine.paint(_transition);
403
+ }
404
+ } else {
405
+ if (_scene.sync()) {
406
+ _transition = _scene.transition;
407
+
408
+ if (_transition) {
409
+ _transition.scene = _scene;
410
+ _transition.init();
411
+ }
412
+
413
+ _scene = _scene.next;
414
+
415
+ if (!_transition) {
416
+ initScene();
417
+ }
418
+ }
419
+ }
420
+
421
+ _sound.update();
422
+ RENDER_STRATEGIES[_renderStrategy]();
423
+ }
424
+
425
+ function render() {
426
+ for (let i = 0; i < _renderableLists.length; ++i) {
427
+ _renderableLists[i].render(_context);
428
+ }
429
+
430
+ const timeout = _frameTime + _lastRender - Date.now();
431
+
432
+ if (timeout < 0 && ++_degraded > DEGRADATION_TOLERANCE) {
433
+ if (++_renderStrategy > RENDER_STRATEGIES.length - 1) {
434
+ _renderStrategy = 0;
435
+ }
436
+ }
437
+
438
+ setTimeout(loop, timeout);
439
+ _lastRender = Date.now();
440
+ }
441
+
442
+ function scale() {
443
+ if (!_autoScale) {
444
+ return;
445
+ }
446
+
447
+ let width, height;
448
+
449
+ if (_keepAspect) {
450
+ let proportion = ACL.window.innerWidth / _canvas.width;
451
+
452
+ if (ACL.window.innerHeight < _canvas.height * proportion) {
453
+ proportion = ACL.window.innerHeight / _canvas.height;
454
+ }
455
+
456
+ width = _canvas.width * proportion;
457
+ height = _canvas.height * proportion;
458
+ } else {
459
+ width = ACL.window.innerWidth;
460
+ height = ACL.window.innerHeight;
461
+ }
462
+
463
+ _realWidth = width;
464
+ _realHeight = height;
465
+ _canvas.style.width = width + "px";
466
+ _canvas.style.height = height + "px";
467
+ }
468
+
469
+ return Engine;
470
470
  })();