excalibur 0.26.0-alpha.310 → 0.26.0-alpha.314

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.
Files changed (104) hide show
  1. package/CHANGELOG.md +9 -2
  2. package/build/dist/Actor.js +3 -1
  3. package/build/dist/Actor.js.map +1 -1
  4. package/build/dist/Collision/Detection/DynamicTreeCollisionProcessor.d.ts +2 -2
  5. package/build/dist/Collision/Detection/DynamicTreeCollisionProcessor.js +9 -26
  6. package/build/dist/Collision/Detection/DynamicTreeCollisionProcessor.js.map +1 -1
  7. package/build/dist/Collision/Detection/Pair.d.ts +5 -0
  8. package/build/dist/Collision/Detection/Pair.js +19 -0
  9. package/build/dist/Collision/Detection/Pair.js.map +1 -1
  10. package/build/dist/Debug/Debug.d.ts +16 -0
  11. package/build/dist/Debug/Debug.js +35 -0
  12. package/build/dist/Debug/Debug.js.map +1 -1
  13. package/build/dist/Drawing/Animation.js +10 -1
  14. package/build/dist/Drawing/Animation.js.map +1 -1
  15. package/build/dist/Drawing/Polygon.js +11 -1
  16. package/build/dist/Drawing/Polygon.js.map +1 -1
  17. package/build/dist/Drawing/Sprite.js +24 -25
  18. package/build/dist/Drawing/Sprite.js.map +1 -1
  19. package/build/dist/Drawing/Texture.js +25 -36
  20. package/build/dist/Drawing/Texture.js.map +1 -1
  21. package/build/dist/Engine.d.ts +34 -1
  22. package/build/dist/Engine.js +114 -60
  23. package/build/dist/Engine.js.map +1 -1
  24. package/build/dist/EntityComponentSystem/SystemManager.d.ts +6 -0
  25. package/build/dist/EntityComponentSystem/SystemManager.js +12 -5
  26. package/build/dist/EntityComponentSystem/SystemManager.js.map +1 -1
  27. package/build/dist/Graphics/Animation.js +7 -1
  28. package/build/dist/Graphics/Animation.js.map +1 -1
  29. package/build/dist/Graphics/Canvas.js +5 -1
  30. package/build/dist/Graphics/Canvas.js.map +1 -1
  31. package/build/dist/Graphics/Circle.js +5 -1
  32. package/build/dist/Graphics/Circle.js.map +1 -1
  33. package/build/dist/Graphics/Context/ExcaliburGraphicsContextWebGL.js +4 -4
  34. package/build/dist/Graphics/Context/ExcaliburGraphicsContextWebGL.js.map +1 -1
  35. package/build/dist/Graphics/Font.js +14 -2
  36. package/build/dist/Graphics/Font.js.map +1 -1
  37. package/build/dist/Graphics/GraphicsComponent.js +6 -3
  38. package/build/dist/Graphics/GraphicsComponent.js.map +1 -1
  39. package/build/dist/Graphics/GraphicsGroup.js +4 -1
  40. package/build/dist/Graphics/GraphicsGroup.js.map +1 -1
  41. package/build/dist/Graphics/ImageSource.js +25 -36
  42. package/build/dist/Graphics/ImageSource.js.map +1 -1
  43. package/build/dist/Graphics/Polygon.js +5 -1
  44. package/build/dist/Graphics/Polygon.js.map +1 -1
  45. package/build/dist/Graphics/Rectangle.js +6 -1
  46. package/build/dist/Graphics/Rectangle.js.map +1 -1
  47. package/build/dist/Graphics/Sprite.js +6 -1
  48. package/build/dist/Graphics/Sprite.js.map +1 -1
  49. package/build/dist/Graphics/SpriteSheet.js +2 -2
  50. package/build/dist/Graphics/SpriteSheet.js.map +1 -1
  51. package/build/dist/Loader.d.ts +4 -1
  52. package/build/dist/Loader.js +47 -45
  53. package/build/dist/Loader.js.map +1 -1
  54. package/build/dist/Particles.js +1 -1
  55. package/build/dist/Particles.js.map +1 -1
  56. package/build/dist/Resources/Gif.js +8 -19
  57. package/build/dist/Resources/Gif.js.map +1 -1
  58. package/build/dist/Resources/Sound/Sound.js +42 -59
  59. package/build/dist/Resources/Sound/Sound.js.map +1 -1
  60. package/build/dist/Scene.js +1 -0
  61. package/build/dist/Scene.js.map +1 -1
  62. package/build/dist/Screen.js +3 -3
  63. package/build/dist/Screen.js.map +1 -1
  64. package/build/dist/ScreenElement.js +1 -1
  65. package/build/dist/ScreenElement.js.map +1 -1
  66. package/build/dist/Trigger.js +4 -1
  67. package/build/dist/Trigger.js.map +1 -1
  68. package/build/dist/Util/Clock.d.ts +117 -0
  69. package/build/dist/Util/Clock.js +209 -0
  70. package/build/dist/Util/Clock.js.map +1 -0
  71. package/build/dist/Util/Decorators.js +7 -2
  72. package/build/dist/Util/Decorators.js.map +1 -1
  73. package/build/dist/Util/Fps.d.ts +40 -0
  74. package/build/dist/Util/Fps.js +47 -0
  75. package/build/dist/Util/Fps.js.map +1 -0
  76. package/build/dist/Util/Util.d.ts +6 -1
  77. package/build/dist/Util/Util.js +9 -3
  78. package/build/dist/Util/Util.js.map +1 -1
  79. package/build/dist/Util/WebAudio.js.map +1 -1
  80. package/build/dist/excalibur.js +743 -346
  81. package/build/dist/excalibur.js.map +1 -1
  82. package/build/dist/excalibur.min.js +1 -1
  83. package/build/dist/excalibur.min.js.LICENSE.txt +1 -1
  84. package/build/dist/excalibur.min.js.map +1 -1
  85. package/build/dist/index.d.ts +3 -0
  86. package/build/dist/index.js +5 -2
  87. package/build/dist/index.js.map +1 -1
  88. package/build/esm/Collision/Detection/DynamicTreeCollisionProcessor.d.ts +2 -2
  89. package/build/esm/Collision/Detection/Pair.d.ts +5 -0
  90. package/build/esm/Debug/Debug.d.ts +16 -0
  91. package/build/esm/Engine.d.ts +34 -1
  92. package/build/esm/EntityComponentSystem/SystemManager.d.ts +6 -0
  93. package/build/esm/Loader.d.ts +4 -1
  94. package/build/esm/Util/Clock.d.ts +117 -0
  95. package/build/esm/Util/Fps.d.ts +40 -0
  96. package/build/esm/Util/Util.d.ts +6 -1
  97. package/build/esm/excalibur.js +749 -347
  98. package/build/esm/excalibur.js.map +1 -1
  99. package/build/esm/excalibur.min.js +1 -1
  100. package/build/esm/excalibur.min.js.LICENSE.txt +1 -1
  101. package/build/esm/excalibur.min.js.map +1 -1
  102. package/build/esm/index.d.ts +3 -0
  103. package/package.json +4 -4
  104. package/wallaby.js +1 -0
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * excalibur - 0.26.0-alpha.310+5f94c2f - 2021-11-27
2
+ * excalibur - 0.26.0-alpha.314+ff3f7ae - 2021-11-28
3
3
  * https://github.com/excaliburjs/Excalibur
4
4
  * Copyright (c) 2021 Excalibur.js <https://github.com/excaliburjs/Excalibur/graphs/contributors>
5
5
  * Licensed BSD-2-Clause
@@ -1898,6 +1898,7 @@ __webpack_require__.d(__webpack_exports__, {
1898
1898
  "Cdc": () => (/* reexport */ Circle),
1899
1899
  "FKn": () => (/* reexport */ CircleCollider),
1900
1900
  "wTW": () => (/* reexport */ Class),
1901
+ "SUY": () => (/* reexport */ Clock),
1901
1902
  "ab2": () => (/* reexport */ ClosestLine),
1902
1903
  "GfZ": () => (/* reexport */ ClosestLineJumpTable),
1903
1904
  "YMS": () => (/* reexport */ Collider),
@@ -1964,6 +1965,7 @@ __webpack_require__.d(__webpack_exports__, {
1964
1965
  "Zxw": () => (/* reexport */ Font),
1965
1966
  "Hdx": () => (/* reexport */ FontStyle),
1966
1967
  "Z$d": () => (/* reexport */ FontUnit),
1968
+ "iqV": () => (/* reexport */ FpsSampler),
1967
1969
  "o$7": () => (/* reexport */ FrameStats),
1968
1970
  "Zm$": () => (/* reexport */ GameEvent),
1969
1971
  "$QH": () => (/* reexport */ GameStartEvent),
@@ -2064,6 +2066,7 @@ __webpack_require__.d(__webpack_exports__, {
2064
2066
  "jyi": () => (/* reexport */ Sprite),
2065
2067
  "E03": () => (/* reexport */ SpriteFont_SpriteFont),
2066
2068
  "V6q": () => (/* reexport */ SpriteSheet),
2069
+ "rg2": () => (/* reexport */ StandardClock),
2067
2070
  "nVo": () => (/* reexport */ StrategyContainer),
2068
2071
  "F6N": () => (/* reexport */ Stream),
2069
2072
  "ad3": () => (/* reexport */ SubscribeEvent),
@@ -2071,6 +2074,7 @@ __webpack_require__.d(__webpack_exports__, {
2071
2074
  "Odq": () => (/* reexport */ SystemManager),
2072
2075
  "Zif": () => (/* reexport */ SystemType),
2073
2076
  "ZGJ": () => (/* reexport */ TagComponent),
2077
+ "MJk": () => (/* reexport */ TestClock),
2074
2078
  "xvT": () => (/* reexport */ Text),
2075
2079
  "PHM": () => (/* reexport */ TextAlign),
2076
2080
  "KwO": () => (/* reexport */ TileMap),
@@ -2084,6 +2088,7 @@ __webpack_require__.d(__webpack_exports__, {
2084
2088
  "OWs": () => (/* reexport */ Vector),
2085
2089
  "dF9": () => (/* reexport */ VectorView),
2086
2090
  "VHo": () => (/* reexport */ VisibleEvent),
2091
+ "ohE": () => (/* reexport */ WebAudio),
2087
2092
  "R$E": () => (/* reexport */ WebAudioInstance),
2088
2093
  "q3I": () => (/* reexport */ World),
2089
2094
  "Pab": () => (/* reexport */ canonicalizeAngle),
@@ -2644,7 +2649,12 @@ const logMessage = (message, options) => {
2644
2649
  * method do the deprecated one. Inspired by https://github.com/jayphelps/core-decorators.js
2645
2650
  */
2646
2651
  function obsolete(options) {
2647
- options = Object.assign({ message: 'This feature will be removed in future versions of Excalibur.', alternateMethod: null, showStackTrace: false }, options);
2652
+ options = {
2653
+ message: 'This feature will be removed in future versions of Excalibur.',
2654
+ alternateMethod: null,
2655
+ showStackTrace: false,
2656
+ ...options
2657
+ };
2648
2658
  return function (target, property, descriptor) {
2649
2659
  if (descriptor &&
2650
2660
  !(typeof descriptor.value === 'function' || typeof descriptor.get === 'function' || typeof descriptor.set === 'function')) {
@@ -2657,7 +2667,7 @@ function obsolete(options) {
2657
2667
  obsoleteMessage[message] = 0;
2658
2668
  }
2659
2669
  // If descriptor is null it is a class
2660
- const method = descriptor ? Object.assign({}, descriptor) : target;
2670
+ const method = descriptor ? { ...descriptor } : target;
2661
2671
  if (!descriptor) {
2662
2672
  // with es2015 classes we need to change our decoration tactic
2663
2673
  class DecoratedClass extends method {
@@ -4471,11 +4481,17 @@ function fail(message) {
4471
4481
  const range = (from, to) => Array.from(new Array(to - from + 1), (_x, i) => i + from);
4472
4482
  /**
4473
4483
  * Create a promise that resolves after a certain number of milliseconds
4484
+ *
4485
+ * It is strongly recommended you pass the excalibur clock so delays are bound to the
4486
+ * excalibur clock which would be unaffected by stop/pause.
4474
4487
  * @param milliseconds
4488
+ * @param clock
4475
4489
  */
4476
- function delay(milliseconds) {
4477
- return new Promise((resolve) => {
4478
- setTimeout(() => {
4490
+ function delay(milliseconds, clock) {
4491
+ var _a;
4492
+ const schedule = (_a = clock === null || clock === void 0 ? void 0 : clock.schedule.bind(clock)) !== null && _a !== void 0 ? _a : setTimeout;
4493
+ return new Promise(resolve => {
4494
+ schedule(() => {
4479
4495
  resolve();
4480
4496
  }, milliseconds);
4481
4497
  });
@@ -6527,7 +6543,11 @@ class Canvas extends Raster {
6527
6543
  return this._ctx;
6528
6544
  }
6529
6545
  clone() {
6530
- return new Canvas(Object.assign(Object.assign(Object.assign({}, this._options), this.cloneGraphicOptions()), this.cloneRasterOptions()));
6546
+ return new Canvas({
6547
+ ...this._options,
6548
+ ...this.cloneGraphicOptions(),
6549
+ ...this.cloneRasterOptions()
6550
+ });
6531
6551
  }
6532
6552
  execute(ctx) {
6533
6553
  var _a, _b;
@@ -7476,15 +7496,6 @@ Fill = SpriteEffects_decorate([
7476
7496
 
7477
7497
 
7478
7498
  ;// CONCATENATED MODULE: ./Drawing/Texture.ts
7479
- var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
7480
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7481
- return new (P || (P = Promise))(function (resolve, reject) {
7482
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
7483
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7484
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7485
- step((generator = generator.apply(thisArg, _arguments || [])).next());
7486
- });
7487
- };
7488
7499
 
7489
7500
 
7490
7501
  /**
@@ -7521,35 +7532,33 @@ class Texture {
7521
7532
  /**
7522
7533
  * Begins loading the texture and returns a promise to be resolved on completion
7523
7534
  */
7524
- load() {
7525
- return __awaiter(this, void 0, void 0, function* () {
7526
- try {
7527
- // Load base64 or blob if needed
7528
- let url;
7529
- if (!this.path.includes('data:image/')) {
7530
- const blob = yield this._resource.load();
7531
- url = URL.createObjectURL(blob);
7532
- }
7533
- else {
7534
- url = this.path;
7535
- }
7536
- // Decode the image
7537
- const image = new Image();
7538
- image.src = url;
7539
- yield image.decode();
7540
- // Set results
7541
- this.data = image;
7542
- this.width = this._sprite.width = image.naturalWidth;
7543
- this.height = this._sprite.height = image.naturalHeight;
7544
- this._sprite = new Sprite_Sprite(this, 0, 0, this.width, this.height);
7545
- }
7546
- catch (_a) {
7547
- yield Promise.reject('Error loading texture');
7535
+ async load() {
7536
+ try {
7537
+ // Load base64 or blob if needed
7538
+ let url;
7539
+ if (!this.path.includes('data:image/')) {
7540
+ const blob = await this._resource.load();
7541
+ url = URL.createObjectURL(blob);
7548
7542
  }
7549
- // todo emit complete
7550
- this._loadedResolve(this.data);
7551
- return this.data;
7552
- });
7543
+ else {
7544
+ url = this.path;
7545
+ }
7546
+ // Decode the image
7547
+ const image = new Image();
7548
+ image.src = url;
7549
+ await image.decode();
7550
+ // Set results
7551
+ this.data = image;
7552
+ this.width = this._sprite.width = image.naturalWidth;
7553
+ this.height = this._sprite.height = image.naturalHeight;
7554
+ this._sprite = new Sprite_Sprite(this, 0, 0, this.width, this.height);
7555
+ }
7556
+ catch (_a) {
7557
+ await Promise.reject('Error loading texture');
7558
+ }
7559
+ // todo emit complete
7560
+ this._loadedResolve(this.data);
7561
+ return this.data;
7553
7562
  }
7554
7563
  asSprite() {
7555
7564
  return this._sprite;
@@ -7596,15 +7605,6 @@ var Sprite_decorate = (undefined && undefined.__decorate) || function (decorator
7596
7605
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
7597
7606
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7598
7607
  };
7599
- var Sprite_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
7600
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7601
- return new (P || (P = Promise))(function (resolve, reject) {
7602
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
7603
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7604
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7605
- step((generator = generator.apply(thisArg, _arguments || [])).next());
7606
- });
7607
- };
7608
7608
 
7609
7609
 
7610
7610
 
@@ -7684,21 +7684,19 @@ class SpriteImpl {
7684
7684
  get drawHeight() {
7685
7685
  return Math.abs(this.height * this.scale.y);
7686
7686
  }
7687
- _initPixelsFromTexture() {
7688
- return Sprite_awaiter(this, void 0, void 0, function* () {
7689
- try {
7690
- const image = yield this.texture.loaded;
7691
- this.width = this.width || image.naturalWidth;
7692
- this.height = this.height || image.naturalHeight;
7693
- this._spriteCanvas.width = this._spriteCanvas.width || image.naturalWidth;
7694
- this._spriteCanvas.height = this._spriteCanvas.height || image.naturalHeight;
7695
- this._loadPixels();
7696
- this._dirtyEffect = true;
7697
- }
7698
- catch (e) {
7699
- this.logger.error('Error loading texture ', this.texture.path, e);
7700
- }
7701
- });
7687
+ async _initPixelsFromTexture() {
7688
+ try {
7689
+ const image = await this.texture.loaded;
7690
+ this.width = this.width || image.naturalWidth;
7691
+ this.height = this.height || image.naturalHeight;
7692
+ this._spriteCanvas.width = this._spriteCanvas.width || image.naturalWidth;
7693
+ this._spriteCanvas.height = this._spriteCanvas.height || image.naturalHeight;
7694
+ this._loadPixels();
7695
+ this._dirtyEffect = true;
7696
+ }
7697
+ catch (e) {
7698
+ this.logger.error('Error loading texture ', this.texture.path, e);
7699
+ }
7702
7700
  }
7703
7701
  _loadPixels() {
7704
7702
  if (this.texture.isLoaded() && !this._pixelsLoaded) {
@@ -7870,7 +7868,17 @@ class SpriteImpl {
7870
7868
  }
7871
7869
  _drawWithOptions(options) {
7872
7870
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
7873
- const { ctx, x, y, rotation, drawWidth, drawHeight, anchor, offset, opacity, flipHorizontal, flipVertical } = Object.assign(Object.assign({}, options), { rotation: (_a = options.rotation) !== null && _a !== void 0 ? _a : this.rotation, drawWidth: (_b = options.drawWidth) !== null && _b !== void 0 ? _b : this.width, drawHeight: (_c = options.drawHeight) !== null && _c !== void 0 ? _c : this.height, flipHorizontal: (_d = options.flipHorizontal) !== null && _d !== void 0 ? _d : this.flipHorizontal, flipVertical: (_e = options.flipVertical) !== null && _e !== void 0 ? _e : this.flipVertical, anchor: (_f = options.anchor) !== null && _f !== void 0 ? _f : this.anchor, offset: (_g = options.offset) !== null && _g !== void 0 ? _g : this.offset, opacity: ((_h = options.opacity) !== null && _h !== void 0 ? _h : 1) * ((_j = this._opacity) !== null && _j !== void 0 ? _j : 1) });
7871
+ const { ctx, x, y, rotation, drawWidth, drawHeight, anchor, offset, opacity, flipHorizontal, flipVertical } = {
7872
+ ...options,
7873
+ rotation: (_a = options.rotation) !== null && _a !== void 0 ? _a : this.rotation,
7874
+ drawWidth: (_b = options.drawWidth) !== null && _b !== void 0 ? _b : this.width,
7875
+ drawHeight: (_c = options.drawHeight) !== null && _c !== void 0 ? _c : this.height,
7876
+ flipHorizontal: (_d = options.flipHorizontal) !== null && _d !== void 0 ? _d : this.flipHorizontal,
7877
+ flipVertical: (_e = options.flipVertical) !== null && _e !== void 0 ? _e : this.flipVertical,
7878
+ anchor: (_f = options.anchor) !== null && _f !== void 0 ? _f : this.anchor,
7879
+ offset: (_g = options.offset) !== null && _g !== void 0 ? _g : this.offset,
7880
+ opacity: ((_h = options.opacity) !== null && _h !== void 0 ? _h : 1) * ((_j = this._opacity) !== null && _j !== void 0 ? _j : 1)
7881
+ };
7874
7882
  if (this._dirtyEffect) {
7875
7883
  this._applyEffects();
7876
7884
  }
@@ -8038,20 +8046,16 @@ class Sprite extends Graphic {
8038
8046
  return new Sprite_Sprite(tex, sprite.sourceView.x, sprite.sourceView.y, sprite.sourceView.width, sprite.sourceView.height);
8039
8047
  }
8040
8048
  clone() {
8041
- return new Sprite(Object.assign({ image: this.image, sourceView: Object.assign({}, this.sourceView), destSize: Object.assign({}, this.destSize) }, this.cloneGraphicOptions()));
8049
+ return new Sprite({
8050
+ image: this.image,
8051
+ sourceView: { ...this.sourceView },
8052
+ destSize: { ...this.destSize },
8053
+ ...this.cloneGraphicOptions()
8054
+ });
8042
8055
  }
8043
8056
  }
8044
8057
 
8045
8058
  ;// CONCATENATED MODULE: ./Graphics/ImageSource.ts
8046
- var ImageSource_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
8047
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
8048
- return new (P || (P = Promise))(function (resolve, reject) {
8049
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
8050
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
8051
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8052
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8053
- });
8054
- };
8055
8059
 
8056
8060
 
8057
8061
 
@@ -8100,35 +8104,33 @@ class ImageSource {
8100
8104
  /**
8101
8105
  * Begins loading the image and returns a promise that resolves when the image is loaded
8102
8106
  */
8103
- load() {
8104
- return ImageSource_awaiter(this, void 0, void 0, function* () {
8105
- if (this.isLoaded()) {
8106
- return this.data;
8107
- }
8108
- try {
8109
- // Load base64 or blob if needed
8110
- let url;
8111
- if (!this.path.includes('data:image/')) {
8112
- const blob = yield this._resource.load();
8113
- url = URL.createObjectURL(blob);
8114
- }
8115
- else {
8116
- url = this.path;
8117
- }
8118
- // Decode the image
8119
- const image = new Image();
8120
- image.src = url;
8121
- yield image.decode();
8122
- // Set results
8123
- this.data = image;
8124
- }
8125
- catch (error) {
8126
- throw `Error loading ImageSource from path '${this.path}' with error [${error.message}]`;
8127
- }
8128
- // todo emit complete
8129
- this._loadedResolve(this.data);
8107
+ async load() {
8108
+ if (this.isLoaded()) {
8130
8109
  return this.data;
8131
- });
8110
+ }
8111
+ try {
8112
+ // Load base64 or blob if needed
8113
+ let url;
8114
+ if (!this.path.includes('data:image/')) {
8115
+ const blob = await this._resource.load();
8116
+ url = URL.createObjectURL(blob);
8117
+ }
8118
+ else {
8119
+ url = this.path;
8120
+ }
8121
+ // Decode the image
8122
+ const image = new Image();
8123
+ image.src = url;
8124
+ await image.decode();
8125
+ // Set results
8126
+ this.data = image;
8127
+ }
8128
+ catch (error) {
8129
+ throw `Error loading ImageSource from path '${this.path}' with error [${error.message}]`;
8130
+ }
8131
+ // todo emit complete
8132
+ this._loadedResolve(this.data);
8133
+ return this.data;
8132
8134
  }
8133
8135
  /**
8134
8136
  * Build a sprite from this ImageSource
@@ -8401,7 +8403,16 @@ class AnimationImpl {
8401
8403
  }
8402
8404
  _drawWithOptions(options) {
8403
8405
  var _a, _b, _c, _d, _e, _f, _g, _h;
8404
- const animOptions = Object.assign(Object.assign({}, options), { rotation: (_a = options.rotation) !== null && _a !== void 0 ? _a : this.rotation, drawWidth: (_b = options.drawWidth) !== null && _b !== void 0 ? _b : this.drawWidth, drawHeight: (_c = options.drawHeight) !== null && _c !== void 0 ? _c : this.drawHeight, flipHorizontal: (_d = options.flipHorizontal) !== null && _d !== void 0 ? _d : this.flipHorizontal, flipVertical: (_e = options.flipVertical) !== null && _e !== void 0 ? _e : this.flipVertical, anchor: (_f = options.anchor) !== null && _f !== void 0 ? _f : this.anchor, opacity: ((_g = options.opacity) !== null && _g !== void 0 ? _g : 1) * ((_h = this._opacity) !== null && _h !== void 0 ? _h : 1) });
8406
+ const animOptions = {
8407
+ ...options,
8408
+ rotation: (_a = options.rotation) !== null && _a !== void 0 ? _a : this.rotation,
8409
+ drawWidth: (_b = options.drawWidth) !== null && _b !== void 0 ? _b : this.drawWidth,
8410
+ drawHeight: (_c = options.drawHeight) !== null && _c !== void 0 ? _c : this.drawHeight,
8411
+ flipHorizontal: (_d = options.flipHorizontal) !== null && _d !== void 0 ? _d : this.flipHorizontal,
8412
+ flipVertical: (_e = options.flipVertical) !== null && _e !== void 0 ? _e : this.flipVertical,
8413
+ anchor: (_f = options.anchor) !== null && _f !== void 0 ? _f : this.anchor,
8414
+ opacity: ((_g = options.opacity) !== null && _g !== void 0 ? _g : 1) * ((_h = this._opacity) !== null && _h !== void 0 ? _h : 1)
8415
+ };
8405
8416
  this._updateValues();
8406
8417
  let currSprite;
8407
8418
  if (this.currentFrame < this.sprites.length) {
@@ -9060,8 +9071,8 @@ class SpriteSheet {
9060
9071
  const sprites = [];
9061
9072
  options.spacing = (_a = options.spacing) !== null && _a !== void 0 ? _a : {};
9062
9073
  const { image, grid: { rows, columns: cols, spriteWidth, spriteHeight }, spacing: { originOffset, margin } } = options;
9063
- const offsetDefaults = Object.assign({ x: 0, y: 0 }, originOffset);
9064
- const marginDefaults = Object.assign({ x: 0, y: 0 }, margin);
9074
+ const offsetDefaults = { x: 0, y: 0, ...originOffset };
9075
+ const marginDefaults = { x: 0, y: 0, ...margin };
9065
9076
  for (let x = 0; x < cols; x++) {
9066
9077
  for (let y = 0; y < rows; y++) {
9067
9078
  sprites[x + y * cols] = new Sprite({
@@ -9277,10 +9288,10 @@ class ExcaliburGraphicsContextWebGLDebug {
9277
9288
  * @param height
9278
9289
  */
9279
9290
  drawRect(x, y, width, height, rectOptions = { color: Color.Black }) {
9280
- this.drawLine(vec(x, y), vec(x + width, y), Object.assign({}, rectOptions));
9281
- this.drawLine(vec(x + width, y), vec(x + width, y + height), Object.assign({}, rectOptions));
9282
- this.drawLine(vec(x + width, y + height), vec(x, y + height), Object.assign({}, rectOptions));
9283
- this.drawLine(vec(x, y + height), vec(x, y), Object.assign({}, rectOptions));
9291
+ this.drawLine(vec(x, y), vec(x + width, y), { ...rectOptions });
9292
+ this.drawLine(vec(x + width, y), vec(x + width, y + height), { ...rectOptions });
9293
+ this.drawLine(vec(x + width, y + height), vec(x, y + height), { ...rectOptions });
9294
+ this.drawLine(vec(x, y + height), vec(x, y), { ...rectOptions });
9284
9295
  }
9285
9296
  /**
9286
9297
  * Draw a debugging line to the context
@@ -9586,7 +9597,7 @@ class Screen {
9586
9597
  this._devicePixelRatio = this._calculateDevicePixelRatio();
9587
9598
  this._alreadyWarned = false;
9588
9599
  this.viewport = options.viewport;
9589
- this.resolution = (_a = options.resolution) !== null && _a !== void 0 ? _a : Object.assign({}, this.viewport);
9600
+ this.resolution = (_a = options.resolution) !== null && _a !== void 0 ? _a : { ...this.viewport };
9590
9601
  this._displayMode = (_b = options.displayMode) !== null && _b !== void 0 ? _b : DisplayMode.Fixed;
9591
9602
  this._canvas = options.canvas;
9592
9603
  this._ctx = options.context;
@@ -9682,8 +9693,8 @@ class Screen {
9682
9693
  pushResolutionAndViewport() {
9683
9694
  this._resolutionStack.push(this.resolution);
9684
9695
  this._viewportStack.push(this.viewport);
9685
- this.resolution = Object.assign({}, this.resolution);
9686
- this.viewport = Object.assign({}, this.viewport);
9696
+ this.resolution = { ...this.resolution };
9697
+ this.viewport = { ...this.viewport };
9687
9698
  }
9688
9699
  peekViewport() {
9689
9700
  return this._viewportStack[this._viewportStack.length - 1];
@@ -10351,15 +10362,6 @@ function circle(ctx, x, y, radius, stroke = Color.White, fill = null) {
10351
10362
  // EXTERNAL MODULE: ./Loader.css
10352
10363
  var Loader_0 = __webpack_require__(1388);
10353
10364
  ;// CONCATENATED MODULE: ./Loader.ts
10354
- var Loader_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
10355
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
10356
- return new (P || (P = Promise))(function (resolve, reject) {
10357
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
10358
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10359
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
10360
- step((generator = generator.apply(thisArg, _arguments || [])).next());
10361
- });
10362
- };
10363
10365
 
10364
10366
 
10365
10367
 
@@ -10483,6 +10485,9 @@ class Loader extends Class {
10483
10485
  buttonElement.style.display = 'none';
10484
10486
  return buttonElement;
10485
10487
  };
10488
+ this._isLoadedPromise = new Promise(resolve => {
10489
+ this._isLoadedResolve = resolve;
10490
+ });
10486
10491
  if (loadables) {
10487
10492
  this.addResources(loadables);
10488
10493
  }
@@ -10558,17 +10563,18 @@ class Loader extends Class {
10558
10563
  /**
10559
10564
  * Shows the play button and returns a promise that resolves when clicked
10560
10565
  */
10561
- showPlayButton() {
10562
- var _a;
10566
+ async showPlayButton() {
10567
+ var _a, _b;
10563
10568
  if (this.suppressPlayButton) {
10564
10569
  this.hidePlayButton();
10565
- return Promise.resolve();
10570
+ // Delay is to give the logo a chance to show, otherwise don't delay
10571
+ await delay(500, (_a = this._engine) === null || _a === void 0 ? void 0 : _a.clock);
10566
10572
  }
10567
10573
  else {
10568
10574
  const resizeHandler = () => {
10569
10575
  this._positionPlayButton();
10570
10576
  };
10571
- if ((_a = this._engine) === null || _a === void 0 ? void 0 : _a.browser) {
10577
+ if ((_b = this._engine) === null || _b === void 0 ? void 0 : _b.browser) {
10572
10578
  this._engine.browser.window.on('resize', resizeHandler);
10573
10579
  }
10574
10580
  this._playButtonShown = true;
@@ -10578,7 +10584,8 @@ class Loader extends Class {
10578
10584
  this._playButton.click();
10579
10585
  }
10580
10586
  });
10581
- const promise = new Promise((resolve) => {
10587
+ this._positionPlayButton();
10588
+ const playButtonClicked = new Promise((resolve) => {
10582
10589
  const startButtonHandler = (e) => {
10583
10590
  var _a;
10584
10591
  // We want to stop propogation to keep bubbling to the engine pointer handlers
@@ -10594,7 +10601,7 @@ class Loader extends Class {
10594
10601
  this._playButton.addEventListener('touchend', startButtonHandler);
10595
10602
  this._playButton.addEventListener('pointerup', startButtonHandler);
10596
10603
  });
10597
- return promise;
10604
+ return await playButtonClicked;
10598
10605
  }
10599
10606
  }
10600
10607
  hidePlayButton() {
@@ -10617,25 +10624,29 @@ class Loader extends Class {
10617
10624
  update(_engine, _delta) {
10618
10625
  // override me
10619
10626
  }
10627
+ areResourcesLoaded() {
10628
+ return this._isLoadedPromise;
10629
+ }
10620
10630
  /**
10621
10631
  * Begin loading all of the supplied resources, returning a promise
10622
- * that resolves when loading of all is complete
10632
+ * that resolves when loading of all is complete AND the user has clicked the "Play button"
10623
10633
  */
10624
- load() {
10625
- return Loader_awaiter(this, void 0, void 0, function* () {
10626
- yield Promise.all(this._resourceList.map((r) => r.load().finally(() => {
10627
- // capture progress
10628
- this._numLoaded++;
10629
- })));
10630
- // short delay in showing the button for aesthetics
10631
- yield delay(200);
10632
- yield this.showPlayButton();
10633
- // Unlock browser AudioContext in after user gesture
10634
- // See: https://github.com/excaliburjs/Excalibur/issues/262
10635
- // See: https://github.com/excaliburjs/Excalibur/issues/1031
10636
- yield WebAudio.unlock();
10637
- return (this.data = this._resourceList);
10638
- });
10634
+ async load() {
10635
+ var _a, _b;
10636
+ await ((_a = this._image) === null || _a === void 0 ? void 0 : _a.decode()); // decode logo if it exists
10637
+ await Promise.all(this._resourceList.map((r) => r.load().finally(() => {
10638
+ // capture progress
10639
+ this._numLoaded++;
10640
+ })));
10641
+ this._isLoadedResolve();
10642
+ // short delay in showing the button for aesthetics
10643
+ await delay(200, (_b = this._engine) === null || _b === void 0 ? void 0 : _b.clock);
10644
+ await this.showPlayButton();
10645
+ // Unlock browser AudioContext in after user gesture
10646
+ // See: https://github.com/excaliburjs/Excalibur/issues/262
10647
+ // See: https://github.com/excaliburjs/Excalibur/issues/1031
10648
+ await WebAudio.unlock();
10649
+ return (this.data = this._resourceList);
10639
10650
  }
10640
10651
  markResourceComplete() {
10641
10652
  this._numLoaded++;
@@ -10647,20 +10658,22 @@ class Loader extends Class {
10647
10658
  return this._resourceCount > 0 ? clamp(this._numLoaded, 0, this._resourceCount) / this._resourceCount : 1;
10648
10659
  }
10649
10660
  _positionPlayButton() {
10650
- const screenHeight = this._engine.screen.viewport.height;
10651
- const screenWidth = this._engine.screen.viewport.width;
10652
- if (this._playButtonRootElement) {
10653
- const left = this._engine.canvas.offsetLeft;
10654
- const top = this._engine.canvas.offsetTop;
10655
- const buttonWidth = this._playButton.clientWidth;
10656
- const buttonHeight = this._playButton.clientHeight;
10657
- if (this.playButtonPosition) {
10658
- this._playButtonRootElement.style.left = `${this.playButtonPosition.x}px`;
10659
- this._playButtonRootElement.style.top = `${this.playButtonPosition.y}px`;
10660
- }
10661
- else {
10662
- this._playButtonRootElement.style.left = `${left + screenWidth / 2 - buttonWidth / 2}px`;
10663
- this._playButtonRootElement.style.top = `${top + screenHeight / 2 - buttonHeight / 2 + 100}px`;
10661
+ if (this._engine) {
10662
+ const screenHeight = this._engine.screen.viewport.height;
10663
+ const screenWidth = this._engine.screen.viewport.width;
10664
+ if (this._playButtonRootElement) {
10665
+ const left = this._engine.canvas.offsetLeft;
10666
+ const top = this._engine.canvas.offsetTop;
10667
+ const buttonWidth = this._playButton.clientWidth;
10668
+ const buttonHeight = this._playButton.clientHeight;
10669
+ if (this.playButtonPosition) {
10670
+ this._playButtonRootElement.style.left = `${this.playButtonPosition.x}px`;
10671
+ this._playButtonRootElement.style.top = `${this.playButtonPosition.y}px`;
10672
+ }
10673
+ else {
10674
+ this._playButtonRootElement.style.left = `${left + screenWidth / 2 - buttonWidth / 2}px`;
10675
+ this._playButtonRootElement.style.top = `${top + screenHeight / 2 - buttonHeight / 2 + 100}px`;
10676
+ }
10664
10677
  }
10665
10678
  }
10666
10679
  }
@@ -11645,10 +11658,29 @@ class Pair {
11645
11658
  this.id = null;
11646
11659
  this.id = Pair.calculatePairHash(colliderA.id, colliderB.id);
11647
11660
  }
11661
+ /**
11662
+ * Returns whether a it is allowed for 2 colliders in a Pair to collide
11663
+ * @param colliderA
11664
+ * @param colliderB
11665
+ */
11648
11666
  static canCollide(colliderA, colliderB) {
11649
11667
  var _a, _b;
11650
11668
  const bodyA = (_a = colliderA === null || colliderA === void 0 ? void 0 : colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);
11651
11669
  const bodyB = (_b = colliderB === null || colliderB === void 0 ? void 0 : colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);
11670
+ // Prevent self collision
11671
+ if (colliderA.id === colliderB.id) {
11672
+ return false;
11673
+ }
11674
+ // Colliders with the same owner do not collide (composite colliders)
11675
+ if (colliderA.owner &&
11676
+ colliderB.owner &&
11677
+ colliderA.owner.id === colliderB.owner.id) {
11678
+ return false;
11679
+ }
11680
+ // if the pair has a member with zero dimension don't collide
11681
+ if (colliderA.localBounds.hasZeroDimensions() || colliderB.localBounds.hasZeroDimensions()) {
11682
+ return false;
11683
+ }
11652
11684
  // Body's needed for collision in the current state
11653
11685
  // TODO can we collide without a body?
11654
11686
  if (!bodyA || !bodyB) {
@@ -12245,7 +12277,7 @@ class Ray {
12245
12277
  class DynamicTreeCollisionProcessor {
12246
12278
  constructor() {
12247
12279
  this._dynamicCollisionTree = new DynamicTree();
12248
- this._collisions = new Set();
12280
+ this._pairs = new Set();
12249
12281
  this._collisionPairCache = [];
12250
12282
  this._colliders = [];
12251
12283
  }
@@ -12299,27 +12331,10 @@ class DynamicTreeCollisionProcessor {
12299
12331
  this._dynamicCollisionTree.untrackCollider(target);
12300
12332
  }
12301
12333
  }
12302
- _shouldGenerateCollisionPair(colliderA, colliderB) {
12303
- // if the collision pair must be 2 separate colliders
12304
- // Also separate owners for composite colliders
12305
- if ((colliderA.id !== null &&
12306
- colliderB.id !== null &&
12307
- colliderA.id === colliderB.id) ||
12308
- (colliderA.owner !== null &&
12309
- colliderB.owner !== null &&
12310
- colliderA.owner === colliderB.owner)) {
12311
- return false;
12312
- }
12334
+ _pairExists(colliderA, colliderB) {
12313
12335
  // if the collision pair has been calculated already short circuit
12314
12336
  const hash = Pair.calculatePairHash(colliderA.id, colliderB.id);
12315
- if (this._collisions.has(hash)) {
12316
- return false; // pair exists easy exit return false
12317
- }
12318
- // if the pair has a member with zero dimension
12319
- if (colliderA.localBounds.hasZeroDimensions() || colliderB.localBounds.hasZeroDimensions()) {
12320
- return false;
12321
- }
12322
- return Pair.canCollide(colliderA, colliderB);
12337
+ return this._pairs.has(hash);
12323
12338
  }
12324
12339
  /**
12325
12340
  * Detects potential collision pairs in a broadphase approach with the dynamic aabb tree strategy
@@ -12334,16 +12349,16 @@ class DynamicTreeCollisionProcessor {
12334
12349
  });
12335
12350
  // clear old list of collision pairs
12336
12351
  this._collisionPairCache = [];
12337
- this._collisions.clear();
12352
+ this._pairs.clear();
12338
12353
  // check for normal collision pairs
12339
12354
  let collider;
12340
12355
  for (let j = 0, l = potentialColliders.length; j < l; j++) {
12341
12356
  collider = potentialColliders[j];
12342
12357
  // Query the collision tree for potential colliders
12343
12358
  this._dynamicCollisionTree.query(collider, (other) => {
12344
- if (this._shouldGenerateCollisionPair(collider, other)) {
12359
+ if (!this._pairExists(collider, other) && Pair.canCollide(collider, other)) {
12345
12360
  const pair = new Pair(collider, other);
12346
- this._collisions.add(pair.id);
12361
+ this._pairs.add(pair.id);
12347
12362
  this._collisionPairCache.push(pair);
12348
12363
  }
12349
12364
  // Always return false, to query whole tree. Returning true in the query method stops searching
@@ -12383,7 +12398,7 @@ class DynamicTreeCollisionProcessor {
12383
12398
  let minCollider;
12384
12399
  let minTranslate = new Vector(Infinity, Infinity);
12385
12400
  this._dynamicCollisionTree.rayCastQuery(ray, updateDistance + Physics.surfaceEpsilon * 2, (other) => {
12386
- if (collider !== other && Pair.canCollide(collider, other)) {
12401
+ if (!this._pairExists(collider, other) && Pair.canCollide(collider, other)) {
12387
12402
  const hitPoint = other.rayCast(ray, updateDistance + Physics.surfaceEpsilon * 10);
12388
12403
  if (hitPoint) {
12389
12404
  const translate = hitPoint.sub(origin);
@@ -12397,8 +12412,8 @@ class DynamicTreeCollisionProcessor {
12397
12412
  });
12398
12413
  if (minCollider && Vector.isValid(minTranslate)) {
12399
12414
  const pair = new Pair(collider, minCollider);
12400
- if (!this._collisions.has(pair.id)) {
12401
- this._collisions.add(pair.id);
12415
+ if (!this._pairs.has(pair.id)) {
12416
+ this._pairs.add(pair.id);
12402
12417
  this._collisionPairCache.push(pair);
12403
12418
  }
12404
12419
  // move the fast moving object to the other body
@@ -15710,7 +15725,7 @@ class GraphicsLayer {
15710
15725
  * @param options
15711
15726
  */
15712
15727
  show(nameOrGraphic, options) {
15713
- options = Object.assign({}, options);
15728
+ options = { ...options };
15714
15729
  let gfx;
15715
15730
  if (nameOrGraphic instanceof Graphic) {
15716
15731
  gfx = this._graphics.copyGraphics ? nameOrGraphic.clone() : nameOrGraphic;
@@ -15735,7 +15750,7 @@ class GraphicsLayer {
15735
15750
  * @param options
15736
15751
  */
15737
15752
  use(nameOrGraphic, options) {
15738
- options = Object.assign({}, options);
15753
+ options = { ...options };
15739
15754
  this.hide();
15740
15755
  return this.show(nameOrGraphic, options);
15741
15756
  }
@@ -15842,7 +15857,10 @@ class GraphicsComponent extends Component {
15842
15857
  this.copyGraphics = false;
15843
15858
  this._bounds = null;
15844
15859
  // Defaults
15845
- options = Object.assign({ visible: this.visible }, options);
15860
+ options = {
15861
+ visible: this.visible,
15862
+ ...options
15863
+ };
15846
15864
  const { current, anchor, opacity, visible, graphics, offset, copyGraphics, onPreDraw, onPostDraw } = options;
15847
15865
  this._graphics = graphics || {};
15848
15866
  this.offset = offset !== null && offset !== void 0 ? offset : this.offset;
@@ -15966,7 +15984,12 @@ class Rectangle extends Raster {
15966
15984
  this.rasterize();
15967
15985
  }
15968
15986
  clone() {
15969
- return new Rectangle(Object.assign(Object.assign({ width: this.width, height: this.height }, this.cloneGraphicOptions()), this.cloneRasterOptions()));
15987
+ return new Rectangle({
15988
+ width: this.width,
15989
+ height: this.height,
15990
+ ...this.cloneGraphicOptions(),
15991
+ ...this.cloneRasterOptions()
15992
+ });
15970
15993
  }
15971
15994
  execute(ctx) {
15972
15995
  if (this.color) {
@@ -16002,7 +16025,11 @@ class Circle extends Raster {
16002
16025
  this.flagDirty();
16003
16026
  }
16004
16027
  clone() {
16005
- return new Circle(Object.assign(Object.assign({ radius: this.radius }, this.cloneGraphicOptions()), this.cloneRasterOptions()));
16028
+ return new Circle({
16029
+ radius: this.radius,
16030
+ ...this.cloneGraphicOptions(),
16031
+ ...this.cloneRasterOptions()
16032
+ });
16006
16033
  }
16007
16034
  execute(ctx) {
16008
16035
  if (this.radius > 0) {
@@ -17686,7 +17713,9 @@ class Actor extends Entity {
17686
17713
  * @deprecated will be removed in v0.26.0
17687
17714
  */
17688
17715
  this.traits = [];
17689
- const { name, x, y, pos, scale, width, height, radius, collider, vel, acc, rotation, angularVelocity, z, color, visible, anchor, collisionType, collisionGroup } = Object.assign({}, config);
17716
+ const { name, x, y, pos, scale, width, height, radius, collider, vel, acc, rotation, angularVelocity, z, color, visible, anchor, collisionType, collisionGroup } = {
17717
+ ...config
17718
+ };
17690
17719
  this._setName(name);
17691
17720
  this.anchor = anchor !== null && anchor !== void 0 ? anchor : Actor.defaults.anchor.clone();
17692
17721
  this.addComponent(new TransformComponent());
@@ -18405,7 +18434,7 @@ Actor_decorate([
18405
18434
  */
18406
18435
  class ScreenElement_ScreenElement extends Actor {
18407
18436
  constructor(config) {
18408
- super(Object.assign({}, config));
18437
+ super({ ...config });
18409
18438
  this.get(TransformComponent).coordPlane = CoordPlane.Screen;
18410
18439
  this.anchor = vec(0, 0);
18411
18440
  this.body.collisionType = CollisionType.PreventCollision;
@@ -19789,7 +19818,10 @@ class Trigger_Trigger extends Actor {
19789
19818
  * Number of times to repeat before killing the trigger,
19790
19819
  */
19791
19820
  this.repeat = -1;
19792
- opts = Object.assign(Object.assign({}, triggerDefaults), opts);
19821
+ opts = {
19822
+ ...triggerDefaults,
19823
+ ...opts
19824
+ };
19793
19825
  this.filter = opts.filter || this.filter;
19794
19826
  this.repeat = opts.repeat || this.repeat;
19795
19827
  this.action = opts.action || this.action;
@@ -20299,12 +20331,11 @@ class SystemManager {
20299
20331
  }
20300
20332
  }
20301
20333
  /**
20302
- * Updates all systems
20303
- * @param type whether this is an update or draw system
20304
- * @param context context reference
20305
- * @param delta time in milliseconds
20334
+ * Initialize all systems in the manager
20335
+ *
20336
+ * Systems added after initialize() will be initialized on add
20306
20337
  */
20307
- updateSystems(type, context, delta) {
20338
+ initialize() {
20308
20339
  if (!this.initialized) {
20309
20340
  this.initialized = true;
20310
20341
  for (const s of this.systems) {
@@ -20313,6 +20344,14 @@ class SystemManager {
20313
20344
  }
20314
20345
  }
20315
20346
  }
20347
+ }
20348
+ /**
20349
+ * Updates all systems
20350
+ * @param type whether this is an update or draw system
20351
+ * @param context context reference
20352
+ * @param delta time in milliseconds
20353
+ */
20354
+ updateSystems(type, context, delta) {
20316
20355
  const systems = this.systems.filter((s) => s.systemType === type);
20317
20356
  for (const s of systems) {
20318
20357
  if (s.preupdate) {
@@ -21108,7 +21147,13 @@ class Animation extends Graphic {
21108
21147
  this.goToFrame(0);
21109
21148
  }
21110
21149
  clone() {
21111
- return new Animation(Object.assign({ frames: this.frames.map((f) => (Object.assign({}, f))), frameDuration: this.frameDuration, reverse: this._reversed, strategy: this.strategy }, this.cloneGraphicOptions()));
21150
+ return new Animation({
21151
+ frames: this.frames.map((f) => ({ ...f })),
21152
+ frameDuration: this.frameDuration,
21153
+ reverse: this._reversed,
21154
+ strategy: this.strategy,
21155
+ ...this.cloneGraphicOptions()
21156
+ });
21112
21157
  }
21113
21158
  /**
21114
21159
  * Create an Animation from a [[SpriteSheet]], a list of indices into the sprite sheet, a duration per frame
@@ -21354,7 +21399,10 @@ class GraphicsGroup extends Graphic {
21354
21399
  this._updateDimensions();
21355
21400
  }
21356
21401
  clone() {
21357
- return new GraphicsGroup(Object.assign({ members: [...this.members] }, this.cloneGraphicOptions()));
21402
+ return new GraphicsGroup({
21403
+ members: [...this.members],
21404
+ ...this.cloneGraphicOptions()
21405
+ });
21358
21406
  }
21359
21407
  _updateDimensions() {
21360
21408
  let bb = new BoundingBox();
@@ -21695,7 +21743,7 @@ class ParticleEmitter extends Actor {
21695
21743
  * Indicates whether particles should start with a random rotation
21696
21744
  */
21697
21745
  this.randomRotation = false;
21698
- const { x, y, pos, isEmitting, minVel, maxVel, acceleration, minAngle, maxAngle, emitRate, particleLife, opacity, fadeFlag, focus, focusAccel, startSize, endSize, minSize, maxSize, beginColor, endColor, particleSprite, emitterType, radius, particleRotationalVelocity, randomRotation, random } = Object.assign({}, config);
21746
+ const { x, y, pos, isEmitting, minVel, maxVel, acceleration, minAngle, maxAngle, emitRate, particleLife, opacity, fadeFlag, focus, focusAccel, startSize, endSize, minSize, maxSize, beginColor, endColor, particleSprite, emitterType, radius, particleRotationalVelocity, randomRotation, random } = { ...config };
21699
21747
  this.pos = pos !== null && pos !== void 0 ? pos : vec(x !== null && x !== void 0 ? x : 0, y !== null && y !== void 0 ? y : 0);
21700
21748
  this.isEmitting = isEmitting !== null && isEmitting !== void 0 ? isEmitting : this.isEmitting;
21701
21749
  this.minVel = minVel !== null && minVel !== void 0 ? minVel : this.minVel;
@@ -22765,6 +22813,7 @@ class Scene extends Class {
22765
22813
  this.engine = engine;
22766
22814
  // Initialize camera first
22767
22815
  this.camera._initialize(engine);
22816
+ this.world.systemManager.initialize();
22768
22817
  // This order is important! we want to be sure any custom init that add actors
22769
22818
  // fire before the actor init
22770
22819
  this.onInitialize.call(this, engine);
@@ -23354,6 +23403,41 @@ class Debug {
23354
23403
  this._engine = engine;
23355
23404
  this.colorBlindMode = new ColorBlindFlags(this._engine);
23356
23405
  }
23406
+ /**
23407
+ * Switch the current excalibur clock with the [[TestClock]] and return
23408
+ * it in the same running state.
23409
+ *
23410
+ * This is useful when you need to debug frame by frame.
23411
+ */
23412
+ useTestClock() {
23413
+ const clock = this._engine.clock;
23414
+ const wasRunning = clock.isRunning();
23415
+ clock.stop();
23416
+ const testClock = clock.toTestClock();
23417
+ if (wasRunning) {
23418
+ testClock.start();
23419
+ }
23420
+ this._engine.clock = testClock;
23421
+ return testClock;
23422
+ }
23423
+ /**
23424
+ * Switch the current excalibur clock with the [[StandardClock]] and
23425
+ * return it in the same runnign state.
23426
+ *
23427
+ * This is useful when you need to switch back to normal mode after
23428
+ * debugging.
23429
+ */
23430
+ useStandardClock() {
23431
+ const currentClock = this._engine.clock;
23432
+ const wasRunning = currentClock.isRunning();
23433
+ currentClock.stop();
23434
+ const standardClock = currentClock.toStandardClock();
23435
+ if (wasRunning) {
23436
+ standardClock.start();
23437
+ }
23438
+ this._engine.clock = standardClock;
23439
+ return standardClock;
23440
+ }
23357
23441
  }
23358
23442
  /**
23359
23443
  * Implementation of a frame's stats. Meant to have values copied via [[FrameStats.reset]], avoid
@@ -25028,6 +25112,264 @@ class PointerEventReceiver extends Class {
25028
25112
  }
25029
25113
  }
25030
25114
 
25115
+ ;// CONCATENATED MODULE: ./Util/Fps.ts
25116
+ class FpsSampler {
25117
+ constructor(options) {
25118
+ var _a;
25119
+ this._samplePeriod = 100;
25120
+ this._currentFrameTime = 0;
25121
+ this._frames = 0;
25122
+ this._previousSampleTime = 0;
25123
+ this._beginFrameTime = 0;
25124
+ this._fps = options.initialFps;
25125
+ this._samplePeriod = (_a = options.samplePeriod) !== null && _a !== void 0 ? _a : this._samplePeriod;
25126
+ this._currentFrameTime = 1000 / options.initialFps;
25127
+ this._nowFn = options.nowFn;
25128
+ this._previousSampleTime = this._nowFn();
25129
+ }
25130
+ /**
25131
+ * Start of code block to sample FPS for
25132
+ */
25133
+ start() {
25134
+ this._beginFrameTime = this._nowFn();
25135
+ }
25136
+ /**
25137
+ * End of code block to sample FPS for
25138
+ */
25139
+ end() {
25140
+ this._frames++;
25141
+ const time = this._nowFn();
25142
+ this._currentFrameTime = time - this._beginFrameTime;
25143
+ if (time >= this._previousSampleTime + this._samplePeriod) {
25144
+ this._fps = (this._frames * 1000) / (time - this._previousSampleTime);
25145
+ this._previousSampleTime = time;
25146
+ this._frames = 0;
25147
+ }
25148
+ }
25149
+ /**
25150
+ * Return the currenty sampled fps over the last sample period, by default every 100ms
25151
+ */
25152
+ get fps() {
25153
+ return this._fps;
25154
+ }
25155
+ /**
25156
+ * Return the instantanteous fps, this can be less useful because it will fluctuate given the current frames time
25157
+ */
25158
+ get instant() {
25159
+ return 1000 / this._currentFrameTime;
25160
+ }
25161
+ }
25162
+
25163
+ ;// CONCATENATED MODULE: ./Util/Clock.ts
25164
+
25165
+
25166
+ /**
25167
+ * Abstract Clock is the base type of all Clocks
25168
+ *
25169
+ * It has a few opinions
25170
+ * 1. It manages the calculation of what "elapsed" time means and thus maximum fps
25171
+ * 2. The default timing api is implemented in now()
25172
+ *
25173
+ * To implement your own clock, extend Clock and override start/stop to start and stop the clock, then call update() with whatever
25174
+ * method is unique to your clock implementation.
25175
+ */
25176
+ class Clock {
25177
+ constructor(options) {
25178
+ var _a, _b, _c;
25179
+ this._onFatalException = () => { };
25180
+ this._maxFps = Infinity;
25181
+ this._lastTime = 0;
25182
+ this._elapsed = 1;
25183
+ this._scheduledCbs = [];
25184
+ this._totalElapsed = 0;
25185
+ this._options = options;
25186
+ this.tick = options.tick;
25187
+ this._lastTime = (_a = this.now()) !== null && _a !== void 0 ? _a : 0;
25188
+ this._maxFps = (_b = options.maxFps) !== null && _b !== void 0 ? _b : this._maxFps;
25189
+ this._onFatalException = (_c = options.onFatalException) !== null && _c !== void 0 ? _c : this._onFatalException;
25190
+ this.fpsSampler = new FpsSampler({
25191
+ initialFps: 60,
25192
+ nowFn: () => this.now()
25193
+ });
25194
+ }
25195
+ /**
25196
+ * Get the elapsed time for the last completed frame
25197
+ */
25198
+ elapsed() {
25199
+ return this._elapsed;
25200
+ }
25201
+ /**
25202
+ * Get the current time in milliseconds
25203
+ */
25204
+ now() {
25205
+ return performance.now();
25206
+ }
25207
+ toTestClock() {
25208
+ const testClock = new TestClock({
25209
+ ...this._options,
25210
+ defaultUpdateMs: 16.6
25211
+ });
25212
+ return testClock;
25213
+ }
25214
+ toStandardClock() {
25215
+ const clock = new StandardClock({
25216
+ ...this._options
25217
+ });
25218
+ return clock;
25219
+ }
25220
+ /**
25221
+ * Schedule a callback to fire given a timeout in milliseconds using the excalibur [[Clock]]
25222
+ *
25223
+ * This is useful to use over the built in browser `setTimeout` because callbacks will be tied to the
25224
+ * excalibur update clock, instead of browser time, this means that callbacks wont fire if the game is
25225
+ * stopped or paused.
25226
+ *
25227
+ * @param cb callback to fire
25228
+ * @param timeoutMs Optionally specify a timeout in milliseconds from now, default is 0ms which means the next possible tick
25229
+ */
25230
+ schedule(cb, timeoutMs = 0) {
25231
+ const scheduledTime = this.now() + timeoutMs;
25232
+ this._scheduledCbs.push([cb, scheduledTime]);
25233
+ }
25234
+ _runScheduledCbs() {
25235
+ // walk backwards to delete items as we loop
25236
+ for (let i = this._scheduledCbs.length - 1; i > -1; i--) {
25237
+ if (this._scheduledCbs[i][1] <= this._totalElapsed) {
25238
+ this._scheduledCbs[i][0]();
25239
+ this._scheduledCbs.splice(i, 1);
25240
+ }
25241
+ }
25242
+ }
25243
+ update(overrideUpdateMs) {
25244
+ try {
25245
+ this.fpsSampler.start();
25246
+ // Get the time to calculate time-elapsed
25247
+ const now = this.now();
25248
+ let elapsed = now - this._lastTime || 1; // first frame
25249
+ // Constrain fps
25250
+ const fpsInterval = this._maxFps === Infinity ? 0 : 1000 / this._maxFps;
25251
+ if (elapsed <= fpsInterval) {
25252
+ return; // too fast 😎 skip this frame
25253
+ }
25254
+ // Resolves issue #138 if the game has been paused, or blurred for
25255
+ // more than a 200 milliseconds, reset elapsed time to 1. This improves reliability
25256
+ // and provides more expected behavior when the engine comes back
25257
+ // into focus
25258
+ if (elapsed > 200) {
25259
+ elapsed = 1;
25260
+ }
25261
+ // tick the mainloop and run scheduled callbacks
25262
+ this._elapsed = overrideUpdateMs || elapsed;
25263
+ this._totalElapsed += this._elapsed;
25264
+ this._runScheduledCbs();
25265
+ this.tick(overrideUpdateMs || elapsed);
25266
+ // if fps interval is not a multple
25267
+ if (fpsInterval > 0) {
25268
+ this._lastTime = now - (elapsed % fpsInterval);
25269
+ }
25270
+ else {
25271
+ this._lastTime = now;
25272
+ }
25273
+ this.fpsSampler.end();
25274
+ }
25275
+ catch (e) {
25276
+ this._onFatalException(e);
25277
+ this.stop();
25278
+ }
25279
+ }
25280
+ }
25281
+ /**
25282
+ * The [[StandardClock]] implements the requestAnimationFrame browser api to run the tick()
25283
+ */
25284
+ class StandardClock extends Clock {
25285
+ constructor(options) {
25286
+ super(options);
25287
+ this._running = false;
25288
+ }
25289
+ isRunning() {
25290
+ return this._running;
25291
+ }
25292
+ start() {
25293
+ this._running = true;
25294
+ const mainloop = () => {
25295
+ // stop the loop
25296
+ if (!this._running) {
25297
+ return;
25298
+ }
25299
+ try {
25300
+ // request next loop
25301
+ this._requestId = window.requestAnimationFrame(mainloop);
25302
+ this.update();
25303
+ }
25304
+ catch (e) {
25305
+ window.cancelAnimationFrame(this._requestId);
25306
+ throw e;
25307
+ }
25308
+ };
25309
+ // begin the first frame
25310
+ mainloop();
25311
+ }
25312
+ stop() {
25313
+ this._running = false;
25314
+ }
25315
+ }
25316
+ /**
25317
+ * The TestClock is meant for debugging interactions in excalibur that require precise timing to replicate or test
25318
+ */
25319
+ class TestClock extends Clock {
25320
+ constructor(options) {
25321
+ super({
25322
+ ...options
25323
+ });
25324
+ this._logger = Logger.getInstance();
25325
+ this._running = false;
25326
+ this._currentTime = 0;
25327
+ this._updateMs = options.defaultUpdateMs;
25328
+ }
25329
+ /**
25330
+ * Get the current time in milliseconds
25331
+ */
25332
+ now() {
25333
+ var _a;
25334
+ return (_a = this._currentTime) !== null && _a !== void 0 ? _a : 0;
25335
+ }
25336
+ isRunning() {
25337
+ return this._running;
25338
+ }
25339
+ start() {
25340
+ this._running = true;
25341
+ }
25342
+ stop() {
25343
+ this._running = false;
25344
+ }
25345
+ /**
25346
+ * Manually step the clock forward 1 tick, optionally specify an elapsed time in milliseconds
25347
+ * @param overrideUpdateMs
25348
+ */
25349
+ step(overrideUpdateMs) {
25350
+ const time = overrideUpdateMs !== null && overrideUpdateMs !== void 0 ? overrideUpdateMs : this._updateMs;
25351
+ if (this._running) {
25352
+ // to be comparable to RAF this needs to be a full blown Task
25353
+ // For example, images cannot decode syncronously in a single step
25354
+ this.update(time);
25355
+ this._currentTime += time;
25356
+ }
25357
+ else {
25358
+ this._logger.warn('The clock is not running, no step will be performed');
25359
+ }
25360
+ }
25361
+ /**
25362
+ * Run a number of steps that tick the clock, optionally specify an elapsed time in milliseconds
25363
+ * @param numberOfSteps
25364
+ * @param overrideUpdateMs
25365
+ */
25366
+ run(numberOfSteps, overrideUpdateMs) {
25367
+ for (let i = 0; i < numberOfSteps; i++) {
25368
+ this.step(overrideUpdateMs !== null && overrideUpdateMs !== void 0 ? overrideUpdateMs : this._updateMs);
25369
+ }
25370
+ }
25371
+ }
25372
+
25031
25373
  ;// CONCATENATED MODULE: ./Engine.ts
25032
25374
  var Engine_decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
25033
25375
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -25054,6 +25396,8 @@ polyfill();
25054
25396
 
25055
25397
 
25056
25398
 
25399
+
25400
+
25057
25401
  /**
25058
25402
  * Enum representing the different mousewheel event bubble prevention
25059
25403
  */
@@ -25105,8 +25449,15 @@ class Engine extends Class {
25105
25449
  * ```
25106
25450
  */
25107
25451
  constructor(options) {
25108
- var _a, _b, _c;
25452
+ var _a, _b, _c, _d;
25109
25453
  super();
25454
+ /**
25455
+ * Optionally set the maximum fps if not set Excalibur will go as fast as the device allows.
25456
+ *
25457
+ * You may want to constrain max fps if your game cannot maintain fps consistenly, it can look and feel better to have a 30fps game than
25458
+ * one that bounces between 30fps and 60fps
25459
+ */
25460
+ this.maxFps = Number.POSITIVE_INFINITY;
25110
25461
  this._hasStarted = false;
25111
25462
  /**
25112
25463
  * Gets or sets the list of post processors to apply at the end of drawing a frame (such as [[ColorBlindCorrector]])
@@ -25142,11 +25493,14 @@ class Engine extends Class {
25142
25493
  Logger.getInstance().fatal(e);
25143
25494
  };
25144
25495
  this._timescale = 1.0;
25145
- this._isLoading = false;
25146
25496
  this._isInitialized = false;
25147
25497
  this._deferredGoTo = null;
25148
25498
  this._loadingComplete = false;
25149
- options = Object.assign(Object.assign({}, Engine._DEFAULT_ENGINE_OPTIONS), options);
25499
+ this._isReady = false;
25500
+ this._isReadyPromise = new Promise(resolve => {
25501
+ this._isReadyResolve = resolve;
25502
+ });
25503
+ options = { ...Engine._DEFAULT_ENGINE_OPTIONS, ...options };
25150
25504
  Flags.freeze();
25151
25505
  // Initialize browser events facade
25152
25506
  this.browser = new BrowserEvents(window, document);
@@ -25255,6 +25609,12 @@ O|===|* >________________>\n\
25255
25609
  if (options.backgroundColor) {
25256
25610
  this.backgroundColor = options.backgroundColor.clone();
25257
25611
  }
25612
+ this.maxFps = (_d = options.maxFps) !== null && _d !== void 0 ? _d : this.maxFps;
25613
+ this.clock = new StandardClock({
25614
+ maxFps: this.maxFps,
25615
+ tick: this._mainloop.bind(this),
25616
+ onFatalException: (e) => this.onFatalException(e)
25617
+ });
25258
25618
  this.enableCanvasTransparency = options.enableCanvasTransparency;
25259
25619
  this._loader = new Loader();
25260
25620
  this.debug = new Debug(this);
@@ -25608,7 +25968,7 @@ O|===|* >________________>\n\
25608
25968
  * @param delta Number of milliseconds elapsed since the last update.
25609
25969
  */
25610
25970
  _update(delta) {
25611
- if (this._isLoading) {
25971
+ if (!this.ready) {
25612
25972
  // suspend updates until loading is finished
25613
25973
  this._loader.update(this, delta);
25614
25974
  // Update input listeners
@@ -25616,7 +25976,6 @@ O|===|* >________________>\n\
25616
25976
  this.input.gamepads.update();
25617
25977
  return;
25618
25978
  }
25619
- this._overrideInitialize(this);
25620
25979
  // Publish preupdate events
25621
25980
  this._preupdate(delta);
25622
25981
  // process engine level events
@@ -25659,10 +26018,10 @@ O|===|* >________________>\n\
25659
26018
  _draw(delta) {
25660
26019
  const ctx = this.ctx;
25661
26020
  this._predraw(ctx, delta);
25662
- if (this._isLoading) {
26021
+ // Drawing nothing else while loading
26022
+ if (!this._isReady) {
25663
26023
  this._loader.canvas.draw(this.graphicsContext, 0, 0);
25664
26024
  this.graphicsContext.flush();
25665
- // Drawing nothing else while loading
25666
26025
  return;
25667
26026
  }
25668
26027
  // TODO move to graphics systems?
@@ -25731,64 +26090,105 @@ O|===|* >________________>\n\
25731
26090
  get loadingComplete() {
25732
26091
  return this._loadingComplete;
25733
26092
  }
26093
+ get ready() {
26094
+ return this._isReady;
26095
+ }
26096
+ isReady() {
26097
+ return this._isReadyPromise;
26098
+ }
25734
26099
  /**
25735
26100
  * Starts the internal game loop for Excalibur after loading
25736
26101
  * any provided assets.
25737
26102
  * @param loader Optional [[Loader]] to use to load resources. The default loader is [[Loader]], override to provide your own
25738
26103
  * custom loader.
26104
+ *
26105
+ * Note: start() only resolves AFTER the user has clicked the play button
25739
26106
  */
25740
- start(loader) {
26107
+ async start(loader) {
25741
26108
  if (!this._compatible) {
25742
- return Promise.reject('Excalibur is incompatible with your browser');
25743
- }
25744
- let loadingComplete;
25745
- // Push the current user entered resolution/viewport
25746
- this.screen.pushResolutionAndViewport();
25747
- // Configure resolution for loader
25748
- this.screen.resolution = this.screen.viewport;
25749
- this.screen.applyResolutionAndViewport();
25750
- this.graphicsContext.updateViewport();
26109
+ throw new Error('Excalibur is incompatible with your browser');
26110
+ }
26111
+ // Wire loader if we have it
25751
26112
  if (loader) {
26113
+ // Push the current user entered resolution/viewport
26114
+ this.screen.pushResolutionAndViewport();
26115
+ // Configure resolution for loader, it expects resolution === viewport
26116
+ this.screen.resolution = this.screen.viewport;
26117
+ this.screen.applyResolutionAndViewport();
26118
+ this.graphicsContext.updateViewport();
25752
26119
  this._loader = loader;
25753
26120
  this._loader.suppressPlayButton = this._suppressPlayButton || this._loader.suppressPlayButton;
25754
26121
  this._loader.wireEngine(this);
25755
- loadingComplete = this.load(this._loader);
25756
- }
25757
- else {
25758
- loadingComplete = Promise.resolve();
25759
26122
  }
25760
- loadingComplete.then(() => {
26123
+ // Start the excalibur clock which drives the mainloop
26124
+ // has started is a slight misnomer, it's really mainloop started
26125
+ this._logger.debug('Starting game clock...');
26126
+ this.browser.resume();
26127
+ this.clock.start();
26128
+ this._logger.debug('Game clock started');
26129
+ if (loader) {
26130
+ await this.load(this._loader);
26131
+ this._loadingComplete = true;
26132
+ // reset back to previous user resolution/viewport
25761
26133
  this.screen.popResolutionAndViewport();
25762
26134
  this.screen.applyResolutionAndViewport();
25763
26135
  this.graphicsContext.updateViewport();
25764
- this.emit('start', new GameStartEvent(this));
25765
- this._loadingComplete = true;
25766
- });
25767
- if (!this._hasStarted) {
25768
- // has started is a slight misnomer, it's really mainloop started
25769
- this._hasStarted = true;
25770
- this._logger.debug('Starting game...');
25771
- this.browser.resume();
25772
- Engine.createMainLoop(this, window.requestAnimationFrame, Date.now)();
25773
- this._logger.debug('Game started');
25774
- }
25775
- else {
25776
- // Game already started;
25777
26136
  }
25778
- return loadingComplete;
26137
+ this._loadingComplete = true;
26138
+ // Initialize before ready
26139
+ this._overrideInitialize(this);
26140
+ this._isReady = true;
26141
+ this._isReadyResolve();
26142
+ this.emit('start', new GameStartEvent(this));
26143
+ return this._isReadyPromise;
26144
+ }
26145
+ _mainloop(elapsed) {
26146
+ this.emit('preframe', new PreFrameEvent(this, this.stats.prevFrame));
26147
+ const delta = elapsed * this.timescale;
26148
+ // reset frame stats (reuse existing instances)
26149
+ const frameId = this.stats.prevFrame.id + 1;
26150
+ this.stats.currFrame.reset();
26151
+ this.stats.currFrame.id = frameId;
26152
+ this.stats.currFrame.delta = delta;
26153
+ this.stats.currFrame.fps = this.clock.fpsSampler.fps;
26154
+ const beforeUpdate = this.clock.now();
26155
+ this._update(delta);
26156
+ const afterUpdate = this.clock.now();
26157
+ this._draw(delta);
26158
+ const afterDraw = this.clock.now();
26159
+ this.stats.currFrame.duration.update = afterUpdate - beforeUpdate;
26160
+ this.stats.currFrame.duration.draw = afterDraw - afterUpdate;
26161
+ this.emit('postframe', new PostFrameEvent(this, this.stats.currFrame));
25779
26162
  }
26163
+ /**
26164
+ *
26165
+ * @param game
26166
+ * @param raf
26167
+ * @param nowFn
26168
+ * @deprecated Use [[Clock]] to run the mainloop, will be removed in v0.26.0
26169
+ */
25780
26170
  static createMainLoop(game, raf, nowFn) {
25781
26171
  let lastTime = nowFn();
26172
+ const fpsSampler = new FpsSampler({
26173
+ nowFn,
26174
+ initialFps: game.maxFps === Infinity ? 60 : game.maxFps
26175
+ });
25782
26176
  return function mainloop() {
25783
26177
  if (!game._hasStarted) {
25784
26178
  return;
25785
26179
  }
25786
26180
  try {
25787
26181
  game._requestId = raf(mainloop);
26182
+ fpsSampler.start();
25788
26183
  game.emit('preframe', new PreFrameEvent(game, game.stats.prevFrame));
25789
26184
  // Get the time to calculate time-elapsed
25790
26185
  const now = nowFn();
25791
- let elapsed = Math.floor(now - lastTime) || 1;
26186
+ let elapsed = now - lastTime || 1; // first frame
26187
+ // Constrain fps
26188
+ const fpsInterval = game.maxFps === Number.POSITIVE_INFINITY ? 0 : 1000 / game.maxFps;
26189
+ if (elapsed <= fpsInterval) {
26190
+ return; // too fast 😎 skip this frame
26191
+ }
25792
26192
  // Resolves issue #138 if the game has been paused, or blurred for
25793
26193
  // more than a 200 milliseconds, reset elapsed time to 1. This improves reliability
25794
26194
  // and provides more expected behavior when the engine comes back
@@ -25802,7 +26202,7 @@ O|===|* >________________>\n\
25802
26202
  game.stats.currFrame.reset();
25803
26203
  game.stats.currFrame.id = frameId;
25804
26204
  game.stats.currFrame.delta = delta;
25805
- game.stats.currFrame.fps = 1.0 / (delta / 1000);
26205
+ game.stats.currFrame.fps = fpsSampler.fps;
25806
26206
  const beforeUpdate = nowFn();
25807
26207
  game._update(delta);
25808
26208
  const afterUpdate = nowFn();
@@ -25810,8 +26210,15 @@ O|===|* >________________>\n\
25810
26210
  const afterDraw = nowFn();
25811
26211
  game.stats.currFrame.duration.update = afterUpdate - beforeUpdate;
25812
26212
  game.stats.currFrame.duration.draw = afterDraw - afterUpdate;
25813
- lastTime = now;
26213
+ // if fps interval is not a multple
26214
+ if (fpsInterval > 0) {
26215
+ lastTime = now - (elapsed % fpsInterval);
26216
+ }
26217
+ else {
26218
+ lastTime = now;
26219
+ }
25814
26220
  game.emit('postframe', new PostFrameEvent(game, game.stats.currFrame));
26221
+ fpsSampler.end();
25815
26222
  game.stats.prevFrame.reset(game.stats.currFrame);
25816
26223
  }
25817
26224
  catch (e) {
@@ -25825,10 +26232,10 @@ O|===|* >________________>\n\
25825
26232
  * Stops Excalibur's main loop, useful for pausing the game.
25826
26233
  */
25827
26234
  stop() {
25828
- if (this._hasStarted) {
26235
+ if (this.clock.isRunning()) {
25829
26236
  this.emit('stop', new GameStopEvent(this));
25830
26237
  this.browser.pause();
25831
- this._hasStarted = false;
26238
+ this.clock.stop();
25832
26239
  this._logger.debug('Game stopped');
25833
26240
  }
25834
26241
  }
@@ -25836,7 +26243,7 @@ O|===|* >________________>\n\
25836
26243
  * Returns the Engine's Running status, Useful for checking whether engine is running or paused.
25837
26244
  */
25838
26245
  isPaused() {
25839
- return !this._hasStarted;
26246
+ return !this.clock.isRunning();
25840
26247
  }
25841
26248
  /**
25842
26249
  * Takes a screen shot of the current viewport and returns it as an
@@ -25854,24 +26261,13 @@ O|===|* >________________>\n\
25854
26261
  * will appear.
25855
26262
  * @param loader Some [[Loadable]] such as a [[Loader]] collection, [[Sound]], or [[Texture]].
25856
26263
  */
25857
- load(loader) {
25858
- const complete = new Promise((resolve) => {
25859
- this._isLoading = true;
25860
- loader.load().then(() => {
25861
- if (this._suppressPlayButton) {
25862
- setTimeout(() => {
25863
- this._isLoading = false;
25864
- resolve();
25865
- // Delay is to give the logo a chance to show, otherwise don't delay
25866
- }, 500);
25867
- }
25868
- else {
25869
- this._isLoading = false;
25870
- resolve();
25871
- }
25872
- });
25873
- });
25874
- return complete;
26264
+ async load(loader) {
26265
+ try {
26266
+ await loader.load();
26267
+ }
26268
+ catch (_a) {
26269
+ await Promise.resolve();
26270
+ }
25875
26271
  }
25876
26272
  }
25877
26273
  /**
@@ -26050,13 +26446,25 @@ class Font extends Raster {
26050
26446
  this.flagDirty();
26051
26447
  }
26052
26448
  clone() {
26053
- return new Font(Object.assign(Object.assign(Object.assign({}, this.cloneGraphicOptions()), this.cloneRasterOptions()), { size: this.size, unit: this.unit, family: this.family, style: this.style, bold: this.bold, textAlign: this.textAlign, baseAlign: this.baseAlign, direction: this.direction, shadow: this.shadow
26449
+ return new Font({
26450
+ ...this.cloneGraphicOptions(),
26451
+ ...this.cloneRasterOptions(),
26452
+ size: this.size,
26453
+ unit: this.unit,
26454
+ family: this.family,
26455
+ style: this.style,
26456
+ bold: this.bold,
26457
+ textAlign: this.textAlign,
26458
+ baseAlign: this.baseAlign,
26459
+ direction: this.direction,
26460
+ shadow: this.shadow
26054
26461
  ? {
26055
26462
  blur: this.shadow.blur,
26056
26463
  offset: this.shadow.offset,
26057
26464
  color: this.shadow.color
26058
26465
  }
26059
- : null }));
26466
+ : null
26467
+ });
26060
26468
  }
26061
26469
  get fontString() {
26062
26470
  return `${this.style} ${this.bold ? 'bold' : ''} ${this.size}${this.unit} ${this.family}`;
@@ -26746,7 +27154,17 @@ let Polygon = class Polygon {
26746
27154
  }
26747
27155
  _drawWithOptions(options) {
26748
27156
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
26749
- const { ctx, x, y, rotation, drawWidth, drawHeight, anchor, offset, opacity, flipHorizontal, flipVertical } = Object.assign(Object.assign({}, options), { rotation: (_a = options.rotation) !== null && _a !== void 0 ? _a : this.rotation, drawWidth: (_b = options.drawWidth) !== null && _b !== void 0 ? _b : this.drawWidth, drawHeight: (_c = options.drawHeight) !== null && _c !== void 0 ? _c : this.drawHeight, flipHorizontal: (_d = options.flipHorizontal) !== null && _d !== void 0 ? _d : this.flipHorizontal, flipVertical: (_e = options.flipVertical) !== null && _e !== void 0 ? _e : this.flipVertical, anchor: (_f = options.anchor) !== null && _f !== void 0 ? _f : this.anchor, offset: (_g = options.offset) !== null && _g !== void 0 ? _g : this.offset, opacity: ((_h = options.opacity) !== null && _h !== void 0 ? _h : 1) * ((_j = this.opacity) !== null && _j !== void 0 ? _j : 1) });
27157
+ const { ctx, x, y, rotation, drawWidth, drawHeight, anchor, offset, opacity, flipHorizontal, flipVertical } = {
27158
+ ...options,
27159
+ rotation: (_a = options.rotation) !== null && _a !== void 0 ? _a : this.rotation,
27160
+ drawWidth: (_b = options.drawWidth) !== null && _b !== void 0 ? _b : this.drawWidth,
27161
+ drawHeight: (_c = options.drawHeight) !== null && _c !== void 0 ? _c : this.drawHeight,
27162
+ flipHorizontal: (_d = options.flipHorizontal) !== null && _d !== void 0 ? _d : this.flipHorizontal,
27163
+ flipVertical: (_e = options.flipVertical) !== null && _e !== void 0 ? _e : this.flipVertical,
27164
+ anchor: (_f = options.anchor) !== null && _f !== void 0 ? _f : this.anchor,
27165
+ offset: (_g = options.offset) !== null && _g !== void 0 ? _g : this.offset,
27166
+ opacity: ((_h = options.opacity) !== null && _h !== void 0 ? _h : 1) * ((_j = this.opacity) !== null && _j !== void 0 ? _j : 1)
27167
+ };
26750
27168
  const xpoint = drawWidth * anchor.x + offset.x + x;
26751
27169
  const ypoint = drawHeight * anchor.y + offset.y + y;
26752
27170
  ctx.save();
@@ -27068,15 +27486,6 @@ function canPlayFile(file) {
27068
27486
  }
27069
27487
 
27070
27488
  ;// CONCATENATED MODULE: ./Resources/Sound/Sound.ts
27071
- var Sound_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
27072
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27073
- return new (P || (P = Promise))(function (resolve, reject) {
27074
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
27075
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
27076
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27077
- step((generator = generator.apply(thisArg, _arguments || [])).next());
27078
- });
27079
- };
27080
27489
 
27081
27490
 
27082
27491
 
@@ -27167,30 +27576,26 @@ class Sound extends Class {
27167
27576
  isLoaded() {
27168
27577
  return !!this.data;
27169
27578
  }
27170
- load() {
27171
- return Sound_awaiter(this, void 0, void 0, function* () {
27172
- if (this.data) {
27173
- return this.data;
27174
- }
27175
- const arraybuffer = yield this._resource.load();
27176
- const audiobuffer = yield this.decodeAudio(arraybuffer.slice(0));
27177
- this._duration = typeof audiobuffer === 'object' ? audiobuffer.duration : undefined;
27178
- this.emit('processed', new NativeSoundProcessedEvent(this, audiobuffer));
27179
- return this.data = audiobuffer;
27180
- });
27579
+ async load() {
27580
+ if (this.data) {
27581
+ return this.data;
27582
+ }
27583
+ const arraybuffer = await this._resource.load();
27584
+ const audiobuffer = await this.decodeAudio(arraybuffer.slice(0));
27585
+ this._duration = typeof audiobuffer === 'object' ? audiobuffer.duration : undefined;
27586
+ this.emit('processed', new NativeSoundProcessedEvent(this, audiobuffer));
27587
+ return this.data = audiobuffer;
27181
27588
  }
27182
- decodeAudio(data) {
27183
- return Sound_awaiter(this, void 0, void 0, function* () {
27184
- try {
27185
- return yield this._audioContext.decodeAudioData(data.slice(0));
27186
- }
27187
- catch (e) {
27188
- this.logger.error('Unable to decode ' +
27189
- ' this browser may not fully support this format, or the file may be corrupt, ' +
27190
- 'if this is an mp3 try removing id3 tags and album art from the file.');
27191
- return yield Promise.reject();
27192
- }
27193
- });
27589
+ async decodeAudio(data) {
27590
+ try {
27591
+ return await this._audioContext.decodeAudioData(data.slice(0));
27592
+ }
27593
+ catch (e) {
27594
+ this.logger.error('Unable to decode ' +
27595
+ ' this browser may not fully support this format, or the file may be corrupt, ' +
27596
+ 'if this is an mp3 try removing id3 tags and album art from the file.');
27597
+ return await Promise.reject();
27598
+ }
27194
27599
  }
27195
27600
  wireEngine(engine) {
27196
27601
  if (engine) {
@@ -27282,38 +27687,34 @@ class Sound extends Class {
27282
27687
  getTrackId(track) {
27283
27688
  return this._tracks.indexOf(track);
27284
27689
  }
27285
- _resumePlayback() {
27286
- return Sound_awaiter(this, void 0, void 0, function* () {
27287
- if (this._isPaused) {
27288
- const resumed = [];
27289
- // ensure we resume *current* tracks (if paused)
27290
- for (const track of this._tracks) {
27291
- resumed.push(track.play());
27292
- }
27293
- this._isPaused = false;
27294
- this.emit('resume', new NativeSoundEvent(this));
27295
- this.logger.debug('Resuming paused instances for sound', this.path, this._tracks);
27296
- // resolve when resumed tracks are done
27297
- yield Promise.all(resumed);
27690
+ async _resumePlayback() {
27691
+ if (this._isPaused) {
27692
+ const resumed = [];
27693
+ // ensure we resume *current* tracks (if paused)
27694
+ for (const track of this._tracks) {
27695
+ resumed.push(track.play());
27298
27696
  }
27299
- return true;
27300
- });
27697
+ this._isPaused = false;
27698
+ this.emit('resume', new NativeSoundEvent(this));
27699
+ this.logger.debug('Resuming paused instances for sound', this.path, this._tracks);
27700
+ // resolve when resumed tracks are done
27701
+ await Promise.all(resumed);
27702
+ }
27703
+ return true;
27301
27704
  }
27302
27705
  /**
27303
27706
  * Starts playback, returns a promise that resolves when playback is complete
27304
27707
  */
27305
- _startPlayback() {
27306
- return Sound_awaiter(this, void 0, void 0, function* () {
27307
- const track = yield this._getTrackInstance(this.data);
27308
- const complete = yield track.play(() => {
27309
- this.emit('playbackstart', new NativeSoundEvent(this, track));
27310
- this.logger.debug('Playing new instance for sound', this.path);
27311
- });
27312
- // when done, remove track
27313
- this.emit('playbackend', new NativeSoundEvent(this, track));
27314
- this._tracks.splice(this.getTrackId(track), 1);
27315
- return complete;
27708
+ async _startPlayback() {
27709
+ const track = await this._getTrackInstance(this.data);
27710
+ const complete = await track.play(() => {
27711
+ this.emit('playbackstart', new NativeSoundEvent(this, track));
27712
+ this.logger.debug('Playing new instance for sound', this.path);
27316
27713
  });
27714
+ // when done, remove track
27715
+ this.emit('playbackend', new NativeSoundEvent(this, track));
27716
+ this._tracks.splice(this.getTrackId(track), 1);
27717
+ return complete;
27317
27718
  }
27318
27719
  _getTrackInstance(data) {
27319
27720
  const newTrack = new WebAudioInstance(data);
@@ -27331,15 +27732,6 @@ class Sound extends Class {
27331
27732
 
27332
27733
 
27333
27734
  ;// CONCATENATED MODULE: ./Resources/Gif.ts
27334
- var Gif_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
27335
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27336
- return new (P || (P = Promise))(function (resolve, reject) {
27337
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
27338
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
27339
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27340
- step((generator = generator.apply(thisArg, _arguments || [])).next());
27341
- });
27342
- };
27343
27735
 
27344
27736
 
27345
27737
 
@@ -27373,16 +27765,14 @@ class Gif {
27373
27765
  /**
27374
27766
  * Begins loading the texture and returns a promise to be resolved on completion
27375
27767
  */
27376
- load() {
27377
- return Gif_awaiter(this, void 0, void 0, function* () {
27378
- const arraybuffer = yield this._resource.load();
27379
- this._stream = new Stream(arraybuffer);
27380
- this._gif = new ParseGif(this._stream, this._transparentColor);
27381
- const images = this._gif.images.map(i => new ImageSource(i.src, false));
27382
- // Load all textures
27383
- yield Promise.all(images.map(t => t.load()));
27384
- return this.data = this._textures = images;
27385
- });
27768
+ async load() {
27769
+ const arraybuffer = await this._resource.load();
27770
+ this._stream = new Stream(arraybuffer);
27771
+ this._gif = new ParseGif(this._stream, this._transparentColor);
27772
+ const images = this._gif.images.map(i => new ImageSource(i.src, false));
27773
+ // Load all textures
27774
+ await Promise.all(images.map(t => t.load()));
27775
+ return this.data = this._textures = images;
27386
27776
  }
27387
27777
  isLoaded() {
27388
27778
  return !!this.data;
@@ -27866,7 +28256,11 @@ class Polygon_Polygon extends Raster {
27866
28256
  return vec(minX, minY);
27867
28257
  }
27868
28258
  clone() {
27869
- return new Polygon_Polygon(Object.assign(Object.assign({ points: this.points.map((p) => p.clone()) }, this.cloneGraphicOptions()), this.cloneRasterOptions()));
28259
+ return new Polygon_Polygon({
28260
+ points: this.points.map((p) => p.clone()),
28261
+ ...this.cloneGraphicOptions(),
28262
+ ...this.cloneRasterOptions()
28263
+ });
27870
28264
  }
27871
28265
  execute(ctx) {
27872
28266
  if (this.points && this.points.length) {
@@ -28426,7 +28820,7 @@ Promises_Promise = Promise_1 = Promises_decorate([
28426
28820
  * The current Excalibur version string
28427
28821
  * @description `process.env.__EX_VERSION` gets replaced by Webpack on build
28428
28822
  */
28429
- const EX_VERSION = "0.26.0-alpha.310+5f94c2f";
28823
+ const EX_VERSION = "0.26.0-alpha.314+ff3f7ae";
28430
28824
 
28431
28825
  polyfill();
28432
28826
  // This file is used as the bundle entry point and exports everything
@@ -28488,6 +28882,9 @@ polyfill();
28488
28882
 
28489
28883
 
28490
28884
 
28885
+
28886
+
28887
+
28491
28888
  // ex.Deprecated
28492
28889
 
28493
28890
  // import * as deprecated from './Deprecated';
@@ -28524,6 +28921,7 @@ var __webpack_exports__Cell = __webpack_exports__.bLd;
28524
28921
  var __webpack_exports__Circle = __webpack_exports__.Cdc;
28525
28922
  var __webpack_exports__CircleCollider = __webpack_exports__.FKn;
28526
28923
  var __webpack_exports__Class = __webpack_exports__.wTW;
28924
+ var __webpack_exports__Clock = __webpack_exports__.SUY;
28527
28925
  var __webpack_exports__ClosestLine = __webpack_exports__.ab2;
28528
28926
  var __webpack_exports__ClosestLineJumpTable = __webpack_exports__.GfZ;
28529
28927
  var __webpack_exports__Collider = __webpack_exports__.YMS;
@@ -28590,6 +28988,7 @@ var __webpack_exports__Follow = __webpack_exports__.j9l;
28590
28988
  var __webpack_exports__Font = __webpack_exports__.Zxw;
28591
28989
  var __webpack_exports__FontStyle = __webpack_exports__.Hdx;
28592
28990
  var __webpack_exports__FontUnit = __webpack_exports__.Z$d;
28991
+ var __webpack_exports__FpsSampler = __webpack_exports__.iqV;
28593
28992
  var __webpack_exports__FrameStats = __webpack_exports__.o$7;
28594
28993
  var __webpack_exports__GameEvent = __webpack_exports__.Zm$;
28595
28994
  var __webpack_exports__GameStartEvent = __webpack_exports__.$QH;
@@ -28690,6 +29089,7 @@ var __webpack_exports__Sound = __webpack_exports__.$uU;
28690
29089
  var __webpack_exports__Sprite = __webpack_exports__.jyi;
28691
29090
  var __webpack_exports__SpriteFont = __webpack_exports__.E03;
28692
29091
  var __webpack_exports__SpriteSheet = __webpack_exports__.V6q;
29092
+ var __webpack_exports__StandardClock = __webpack_exports__.rg2;
28693
29093
  var __webpack_exports__StrategyContainer = __webpack_exports__.nVo;
28694
29094
  var __webpack_exports__Stream = __webpack_exports__.F6N;
28695
29095
  var __webpack_exports__SubscribeEvent = __webpack_exports__.ad3;
@@ -28697,6 +29097,7 @@ var __webpack_exports__System = __webpack_exports__.xP7;
28697
29097
  var __webpack_exports__SystemManager = __webpack_exports__.Odq;
28698
29098
  var __webpack_exports__SystemType = __webpack_exports__.Zif;
28699
29099
  var __webpack_exports__TagComponent = __webpack_exports__.ZGJ;
29100
+ var __webpack_exports__TestClock = __webpack_exports__.MJk;
28700
29101
  var __webpack_exports__Text = __webpack_exports__.xvT;
28701
29102
  var __webpack_exports__TextAlign = __webpack_exports__.PHM;
28702
29103
  var __webpack_exports__TileMap = __webpack_exports__.KwO;
@@ -28710,6 +29111,7 @@ var __webpack_exports__Util = __webpack_exports__.ZrN;
28710
29111
  var __webpack_exports__Vector = __webpack_exports__.OWs;
28711
29112
  var __webpack_exports__VectorView = __webpack_exports__.dF9;
28712
29113
  var __webpack_exports__VisibleEvent = __webpack_exports__.VHo;
29114
+ var __webpack_exports__WebAudio = __webpack_exports__.ohE;
28713
29115
  var __webpack_exports__WebAudioInstance = __webpack_exports__.R$E;
28714
29116
  var __webpack_exports__World = __webpack_exports__.q3I;
28715
29117
  var __webpack_exports__canonicalizeAngle = __webpack_exports__.Pab;
@@ -28737,6 +29139,6 @@ var __webpack_exports__resetObsoleteCounter = __webpack_exports__.Q4c;
28737
29139
  var __webpack_exports__toDegrees = __webpack_exports__.Uxb;
28738
29140
  var __webpack_exports__toRadians = __webpack_exports__.Yr5;
28739
29141
  var __webpack_exports__vec = __webpack_exports__.Bhw;
28740
- export { __webpack_exports__ActionContext as ActionContext, __webpack_exports__ActionQueue as ActionQueue, __webpack_exports__ActionsComponent as ActionsComponent, __webpack_exports__ActionsSystem as ActionsSystem, __webpack_exports__ActivateEvent as ActivateEvent, __webpack_exports__Actor as Actor, __webpack_exports__AddedComponent as AddedComponent, __webpack_exports__AddedEntity as AddedEntity, __webpack_exports__Animation as Animation, __webpack_exports__AnimationDirection as AnimationDirection, __webpack_exports__AnimationStrategy as AnimationStrategy, __webpack_exports__ArcadeSolver as ArcadeSolver, __webpack_exports__AudioContextFactory as AudioContextFactory, __webpack_exports__Axis as Axis, __webpack_exports__BaseAlign as BaseAlign, __webpack_exports__BinaryTreeNode as BinaryTreeNode, __webpack_exports__Blink as Blink, __webpack_exports__BodyComponent as BodyComponent, __webpack_exports__BoundingBox as BoundingBox, __webpack_exports__BroadphaseStrategy as BroadphaseStrategy, __webpack_exports__BrowserComponent as BrowserComponent, __webpack_exports__BrowserEvents as BrowserEvents, __webpack_exports__Camera as Camera, __webpack_exports__Canvas as Canvas, __webpack_exports__Cell as Cell, __webpack_exports__Circle as Circle, __webpack_exports__CircleCollider as CircleCollider, __webpack_exports__Class as Class, __webpack_exports__ClosestLine as ClosestLine, __webpack_exports__ClosestLineJumpTable as ClosestLineJumpTable, __webpack_exports__Collider as Collider, __webpack_exports__ColliderComponent as ColliderComponent, __webpack_exports__CollisionContact as CollisionContact, __webpack_exports__CollisionEndEvent as CollisionEndEvent, __webpack_exports__CollisionGroup as CollisionGroup, __webpack_exports__CollisionGroupManager as CollisionGroupManager, __webpack_exports__CollisionJumpTable as CollisionJumpTable, __webpack_exports__CollisionPostSolveEvent as CollisionPostSolveEvent, __webpack_exports__CollisionPreSolveEvent as CollisionPreSolveEvent, __webpack_exports__CollisionResolutionStrategy as CollisionResolutionStrategy, __webpack_exports__CollisionSolver as CollisionSolver, __webpack_exports__CollisionStartEvent as CollisionStartEvent, __webpack_exports__CollisionSystem as CollisionSystem, __webpack_exports__CollisionType as CollisionType, __webpack_exports__Color as Color, __webpack_exports__ColorBlindCorrector as ColorBlindCorrector, __webpack_exports__ColorBlindFlags as ColorBlindFlags, __webpack_exports__ColorBlindness as ColorBlindness, __webpack_exports__Component as Component, __webpack_exports__CompositeCollider as CompositeCollider, __webpack_exports__Configurable as Configurable, __webpack_exports__ConsoleAppender as ConsoleAppender, __webpack_exports__ContactConstraintPoint as ContactConstraintPoint, __webpack_exports__ContactEndEvent as ContactEndEvent, __webpack_exports__ContactStartEvent as ContactStartEvent, __webpack_exports__CoordPlane as CoordPlane, __webpack_exports__CullingBox as CullingBox, __webpack_exports__DeactivateEvent as DeactivateEvent, __webpack_exports__Debug as Debug, __webpack_exports__DebugSystem as DebugSystem, __webpack_exports__DebugText as DebugText, __webpack_exports__DegreeOfFreedom as DegreeOfFreedom, __webpack_exports__Detector as Detector, __webpack_exports__Die as Die, __webpack_exports__Direction as Direction, __webpack_exports__DisplayMode as DisplayMode, __webpack_exports__DynamicTree as DynamicTree, __webpack_exports__DynamicTreeCollisionProcessor as DynamicTreeCollisionProcessor, __webpack_exports__EX_VERSION as EX_VERSION, __webpack_exports__EaseTo as EaseTo, __webpack_exports__EasingFunctions as EasingFunctions, __webpack_exports__EdgeCollider as EdgeCollider, __webpack_exports__ElasticToActorStrategy as ElasticToActorStrategy, __webpack_exports__EmitterType as EmitterType, __webpack_exports__Engine as Engine, __webpack_exports__EnterTriggerEvent as EnterTriggerEvent, __webpack_exports__EnterViewPortEvent as EnterViewPortEvent, __webpack_exports__Entity as Entity, __webpack_exports__EntityManager as EntityManager, __webpack_exports__EventDispatcher as EventDispatcher, __webpack_exports__EventTypes as EventTypes, __webpack_exports__Events as Events, __webpack_exports__ExResponse as ExResponse, __webpack_exports__ExcaliburGraphicsContext2DCanvas as ExcaliburGraphicsContext2DCanvas, __webpack_exports__ExcaliburGraphicsContextWebGL as ExcaliburGraphicsContextWebGL, __webpack_exports__ExitTriggerEvent as ExitTriggerEvent, __webpack_exports__ExitViewPortEvent as ExitViewPortEvent, __webpack_exports__Experiments as Experiments, __webpack_exports__Fade as Fade, __webpack_exports__Flags as Flags, __webpack_exports__Follow as Follow, __webpack_exports__Font as Font, __webpack_exports__FontStyle as FontStyle, __webpack_exports__FontUnit as FontUnit, __webpack_exports__FrameStats as FrameStats, __webpack_exports__GameEvent as GameEvent, __webpack_exports__GameStartEvent as GameStartEvent, __webpack_exports__GameStopEvent as GameStopEvent, __webpack_exports__GamepadAxisEvent as GamepadAxisEvent, __webpack_exports__GamepadButtonEvent as GamepadButtonEvent, __webpack_exports__GamepadConnectEvent as GamepadConnectEvent, __webpack_exports__GamepadDisconnectEvent as GamepadDisconnectEvent, __webpack_exports__Gif as Gif, __webpack_exports__GlobalCoordinates as GlobalCoordinates, __webpack_exports__Graphic as Graphic, __webpack_exports__GraphicsComponent as GraphicsComponent, __webpack_exports__GraphicsGroup as GraphicsGroup, __webpack_exports__GraphicsLayer as GraphicsLayer, __webpack_exports__GraphicsLayers as GraphicsLayers, __webpack_exports__GraphicsSystem as GraphicsSystem, __webpack_exports__HiddenEvent as HiddenEvent, __webpack_exports__ImageSource as ImageSource, __webpack_exports__InitializeEvent as InitializeEvent, __webpack_exports__Input as Input, __webpack_exports__Integrator as Integrator, __webpack_exports__KillEvent as KillEvent, __webpack_exports__Label as Label, __webpack_exports__Legacy as Legacy, __webpack_exports__LegacyDrawing as LegacyDrawing, __webpack_exports__LimitCameraBoundsStrategy as LimitCameraBoundsStrategy, __webpack_exports__Line as Line, __webpack_exports__Loader as Loader, __webpack_exports__LockCameraToActorAxisStrategy as LockCameraToActorAxisStrategy, __webpack_exports__LockCameraToActorStrategy as LockCameraToActorStrategy, __webpack_exports__LogLevel as LogLevel, __webpack_exports__Logger as Logger, __webpack_exports__Matrix as Matrix, __webpack_exports__MatrixLocations as MatrixLocations, __webpack_exports__MediaEvent as MediaEvent, __webpack_exports__Meet as Meet, __webpack_exports__MockedElement as MockedElement, __webpack_exports__MotionComponent as MotionComponent, __webpack_exports__MotionSystem as MotionSystem, __webpack_exports__MoveBy as MoveBy, __webpack_exports__MoveTo as MoveTo, __webpack_exports__NativeSoundEvent as NativeSoundEvent, __webpack_exports__NativeSoundProcessedEvent as NativeSoundProcessedEvent, __webpack_exports__Observable as Observable, __webpack_exports__Pair as Pair, __webpack_exports__ParseGif as ParseGif, __webpack_exports__Particle as Particle, __webpack_exports__ParticleEmitter as ParticleEmitter, __webpack_exports__Physics as Physics, __webpack_exports__PhysicsStats as PhysicsStats, __webpack_exports__PointerComponent as PointerComponent, __webpack_exports__Polygon as Polygon, __webpack_exports__PolygonCollider as PolygonCollider, __webpack_exports__Pool as Pool, __webpack_exports__PostCollisionEvent as PostCollisionEvent, __webpack_exports__PostDebugDrawEvent as PostDebugDrawEvent, __webpack_exports__PostDrawEvent as PostDrawEvent, __webpack_exports__PostFrameEvent as PostFrameEvent, __webpack_exports__PostKillEvent as PostKillEvent, __webpack_exports__PostUpdateEvent as PostUpdateEvent, __webpack_exports__PreCollisionEvent as PreCollisionEvent, __webpack_exports__PreDebugDrawEvent as PreDebugDrawEvent, __webpack_exports__PreDrawEvent as PreDrawEvent, __webpack_exports__PreFrameEvent as PreFrameEvent, __webpack_exports__PreKillEvent as PreKillEvent, __webpack_exports__PreUpdateEvent as PreUpdateEvent, __webpack_exports__Projection as Projection, __webpack_exports__Promise as Promise, __webpack_exports__PromiseState as PromiseState, __webpack_exports__Query as Query, __webpack_exports__QueryManager as QueryManager, __webpack_exports__RadiusAroundActorStrategy as RadiusAroundActorStrategy, __webpack_exports__Random as Random, __webpack_exports__Raster as Raster, __webpack_exports__Ray as Ray, __webpack_exports__RealisticSolver as RealisticSolver, __webpack_exports__Rectangle as Rectangle, __webpack_exports__RemovedComponent as RemovedComponent, __webpack_exports__RemovedEntity as RemovedEntity, __webpack_exports__Repeat as Repeat, __webpack_exports__RepeatForever as RepeatForever, __webpack_exports__Resolution as Resolution, __webpack_exports__Resource as Resource, __webpack_exports__RotateBy as RotateBy, __webpack_exports__RotateTo as RotateTo, __webpack_exports__RotationType as RotationType, __webpack_exports__ScaleBy as ScaleBy, __webpack_exports__ScaleTo as ScaleTo, __webpack_exports__Scene as Scene, __webpack_exports__Screen as Screen, __webpack_exports__ScreenAppender as ScreenAppender, __webpack_exports__ScreenElement as ScreenElement, __webpack_exports__ScrollPreventionMode as ScrollPreventionMode, __webpack_exports__Shape as Shape, __webpack_exports__Side as Side, __webpack_exports__SortedList as SortedList, __webpack_exports__Sound as Sound, __webpack_exports__Sprite as Sprite, __webpack_exports__SpriteFont as SpriteFont, __webpack_exports__SpriteSheet as SpriteSheet, __webpack_exports__StrategyContainer as StrategyContainer, __webpack_exports__Stream as Stream, __webpack_exports__SubscribeEvent as SubscribeEvent, __webpack_exports__System as System, __webpack_exports__SystemManager as SystemManager, __webpack_exports__SystemType as SystemType, __webpack_exports__TagComponent as TagComponent, __webpack_exports__Text as Text, __webpack_exports__TextAlign as TextAlign, __webpack_exports__TileMap as TileMap, __webpack_exports__Timer as Timer, __webpack_exports__Traits as Traits, __webpack_exports__TransformComponent as TransformComponent, __webpack_exports__TreeNode as TreeNode, __webpack_exports__Trigger as Trigger, __webpack_exports__UnsubscribeEvent as UnsubscribeEvent, __webpack_exports__Util as Util, __webpack_exports__Vector as Vector, __webpack_exports__VectorView as VectorView, __webpack_exports__VisibleEvent as VisibleEvent, __webpack_exports__WebAudioInstance as WebAudioInstance, __webpack_exports__World as World, __webpack_exports__canonicalizeAngle as canonicalizeAngle, __webpack_exports__clamp as clamp, __webpack_exports__createId as createId, __webpack_exports__hasGraphicsTick as hasGraphicsTick, __webpack_exports__hasOnInitialize as hasOnInitialize, __webpack_exports__hasOnPostUpdate as hasOnPostUpdate, __webpack_exports__hasOnPreUpdate as hasOnPreUpdate, __webpack_exports__hasPostDraw as hasPostDraw, __webpack_exports__hasPreDraw as hasPreDraw, __webpack_exports__has_initialize as has_initialize, __webpack_exports__has_postupdate as has_postupdate, __webpack_exports__has_preupdate as has_preupdate, __webpack_exports__isAddedComponent as isAddedComponent, __webpack_exports__isAddedSystemEntity as isAddedSystemEntity, __webpack_exports__isRemoveSystemEntity as isRemoveSystemEntity, __webpack_exports__isRemovedComponent as isRemovedComponent, __webpack_exports__maxMessages as maxMessages, __webpack_exports__obsolete as obsolete, __webpack_exports__randomInRange as randomInRange, __webpack_exports__randomIntInRange as randomIntInRange, __webpack_exports__range as range, __webpack_exports__resetObsoleteCounter as resetObsoleteCounter, __webpack_exports__toDegrees as toDegrees, __webpack_exports__toRadians as toRadians, __webpack_exports__vec as vec };
29142
+ export { __webpack_exports__ActionContext as ActionContext, __webpack_exports__ActionQueue as ActionQueue, __webpack_exports__ActionsComponent as ActionsComponent, __webpack_exports__ActionsSystem as ActionsSystem, __webpack_exports__ActivateEvent as ActivateEvent, __webpack_exports__Actor as Actor, __webpack_exports__AddedComponent as AddedComponent, __webpack_exports__AddedEntity as AddedEntity, __webpack_exports__Animation as Animation, __webpack_exports__AnimationDirection as AnimationDirection, __webpack_exports__AnimationStrategy as AnimationStrategy, __webpack_exports__ArcadeSolver as ArcadeSolver, __webpack_exports__AudioContextFactory as AudioContextFactory, __webpack_exports__Axis as Axis, __webpack_exports__BaseAlign as BaseAlign, __webpack_exports__BinaryTreeNode as BinaryTreeNode, __webpack_exports__Blink as Blink, __webpack_exports__BodyComponent as BodyComponent, __webpack_exports__BoundingBox as BoundingBox, __webpack_exports__BroadphaseStrategy as BroadphaseStrategy, __webpack_exports__BrowserComponent as BrowserComponent, __webpack_exports__BrowserEvents as BrowserEvents, __webpack_exports__Camera as Camera, __webpack_exports__Canvas as Canvas, __webpack_exports__Cell as Cell, __webpack_exports__Circle as Circle, __webpack_exports__CircleCollider as CircleCollider, __webpack_exports__Class as Class, __webpack_exports__Clock as Clock, __webpack_exports__ClosestLine as ClosestLine, __webpack_exports__ClosestLineJumpTable as ClosestLineJumpTable, __webpack_exports__Collider as Collider, __webpack_exports__ColliderComponent as ColliderComponent, __webpack_exports__CollisionContact as CollisionContact, __webpack_exports__CollisionEndEvent as CollisionEndEvent, __webpack_exports__CollisionGroup as CollisionGroup, __webpack_exports__CollisionGroupManager as CollisionGroupManager, __webpack_exports__CollisionJumpTable as CollisionJumpTable, __webpack_exports__CollisionPostSolveEvent as CollisionPostSolveEvent, __webpack_exports__CollisionPreSolveEvent as CollisionPreSolveEvent, __webpack_exports__CollisionResolutionStrategy as CollisionResolutionStrategy, __webpack_exports__CollisionSolver as CollisionSolver, __webpack_exports__CollisionStartEvent as CollisionStartEvent, __webpack_exports__CollisionSystem as CollisionSystem, __webpack_exports__CollisionType as CollisionType, __webpack_exports__Color as Color, __webpack_exports__ColorBlindCorrector as ColorBlindCorrector, __webpack_exports__ColorBlindFlags as ColorBlindFlags, __webpack_exports__ColorBlindness as ColorBlindness, __webpack_exports__Component as Component, __webpack_exports__CompositeCollider as CompositeCollider, __webpack_exports__Configurable as Configurable, __webpack_exports__ConsoleAppender as ConsoleAppender, __webpack_exports__ContactConstraintPoint as ContactConstraintPoint, __webpack_exports__ContactEndEvent as ContactEndEvent, __webpack_exports__ContactStartEvent as ContactStartEvent, __webpack_exports__CoordPlane as CoordPlane, __webpack_exports__CullingBox as CullingBox, __webpack_exports__DeactivateEvent as DeactivateEvent, __webpack_exports__Debug as Debug, __webpack_exports__DebugSystem as DebugSystem, __webpack_exports__DebugText as DebugText, __webpack_exports__DegreeOfFreedom as DegreeOfFreedom, __webpack_exports__Detector as Detector, __webpack_exports__Die as Die, __webpack_exports__Direction as Direction, __webpack_exports__DisplayMode as DisplayMode, __webpack_exports__DynamicTree as DynamicTree, __webpack_exports__DynamicTreeCollisionProcessor as DynamicTreeCollisionProcessor, __webpack_exports__EX_VERSION as EX_VERSION, __webpack_exports__EaseTo as EaseTo, __webpack_exports__EasingFunctions as EasingFunctions, __webpack_exports__EdgeCollider as EdgeCollider, __webpack_exports__ElasticToActorStrategy as ElasticToActorStrategy, __webpack_exports__EmitterType as EmitterType, __webpack_exports__Engine as Engine, __webpack_exports__EnterTriggerEvent as EnterTriggerEvent, __webpack_exports__EnterViewPortEvent as EnterViewPortEvent, __webpack_exports__Entity as Entity, __webpack_exports__EntityManager as EntityManager, __webpack_exports__EventDispatcher as EventDispatcher, __webpack_exports__EventTypes as EventTypes, __webpack_exports__Events as Events, __webpack_exports__ExResponse as ExResponse, __webpack_exports__ExcaliburGraphicsContext2DCanvas as ExcaliburGraphicsContext2DCanvas, __webpack_exports__ExcaliburGraphicsContextWebGL as ExcaliburGraphicsContextWebGL, __webpack_exports__ExitTriggerEvent as ExitTriggerEvent, __webpack_exports__ExitViewPortEvent as ExitViewPortEvent, __webpack_exports__Experiments as Experiments, __webpack_exports__Fade as Fade, __webpack_exports__Flags as Flags, __webpack_exports__Follow as Follow, __webpack_exports__Font as Font, __webpack_exports__FontStyle as FontStyle, __webpack_exports__FontUnit as FontUnit, __webpack_exports__FpsSampler as FpsSampler, __webpack_exports__FrameStats as FrameStats, __webpack_exports__GameEvent as GameEvent, __webpack_exports__GameStartEvent as GameStartEvent, __webpack_exports__GameStopEvent as GameStopEvent, __webpack_exports__GamepadAxisEvent as GamepadAxisEvent, __webpack_exports__GamepadButtonEvent as GamepadButtonEvent, __webpack_exports__GamepadConnectEvent as GamepadConnectEvent, __webpack_exports__GamepadDisconnectEvent as GamepadDisconnectEvent, __webpack_exports__Gif as Gif, __webpack_exports__GlobalCoordinates as GlobalCoordinates, __webpack_exports__Graphic as Graphic, __webpack_exports__GraphicsComponent as GraphicsComponent, __webpack_exports__GraphicsGroup as GraphicsGroup, __webpack_exports__GraphicsLayer as GraphicsLayer, __webpack_exports__GraphicsLayers as GraphicsLayers, __webpack_exports__GraphicsSystem as GraphicsSystem, __webpack_exports__HiddenEvent as HiddenEvent, __webpack_exports__ImageSource as ImageSource, __webpack_exports__InitializeEvent as InitializeEvent, __webpack_exports__Input as Input, __webpack_exports__Integrator as Integrator, __webpack_exports__KillEvent as KillEvent, __webpack_exports__Label as Label, __webpack_exports__Legacy as Legacy, __webpack_exports__LegacyDrawing as LegacyDrawing, __webpack_exports__LimitCameraBoundsStrategy as LimitCameraBoundsStrategy, __webpack_exports__Line as Line, __webpack_exports__Loader as Loader, __webpack_exports__LockCameraToActorAxisStrategy as LockCameraToActorAxisStrategy, __webpack_exports__LockCameraToActorStrategy as LockCameraToActorStrategy, __webpack_exports__LogLevel as LogLevel, __webpack_exports__Logger as Logger, __webpack_exports__Matrix as Matrix, __webpack_exports__MatrixLocations as MatrixLocations, __webpack_exports__MediaEvent as MediaEvent, __webpack_exports__Meet as Meet, __webpack_exports__MockedElement as MockedElement, __webpack_exports__MotionComponent as MotionComponent, __webpack_exports__MotionSystem as MotionSystem, __webpack_exports__MoveBy as MoveBy, __webpack_exports__MoveTo as MoveTo, __webpack_exports__NativeSoundEvent as NativeSoundEvent, __webpack_exports__NativeSoundProcessedEvent as NativeSoundProcessedEvent, __webpack_exports__Observable as Observable, __webpack_exports__Pair as Pair, __webpack_exports__ParseGif as ParseGif, __webpack_exports__Particle as Particle, __webpack_exports__ParticleEmitter as ParticleEmitter, __webpack_exports__Physics as Physics, __webpack_exports__PhysicsStats as PhysicsStats, __webpack_exports__PointerComponent as PointerComponent, __webpack_exports__Polygon as Polygon, __webpack_exports__PolygonCollider as PolygonCollider, __webpack_exports__Pool as Pool, __webpack_exports__PostCollisionEvent as PostCollisionEvent, __webpack_exports__PostDebugDrawEvent as PostDebugDrawEvent, __webpack_exports__PostDrawEvent as PostDrawEvent, __webpack_exports__PostFrameEvent as PostFrameEvent, __webpack_exports__PostKillEvent as PostKillEvent, __webpack_exports__PostUpdateEvent as PostUpdateEvent, __webpack_exports__PreCollisionEvent as PreCollisionEvent, __webpack_exports__PreDebugDrawEvent as PreDebugDrawEvent, __webpack_exports__PreDrawEvent as PreDrawEvent, __webpack_exports__PreFrameEvent as PreFrameEvent, __webpack_exports__PreKillEvent as PreKillEvent, __webpack_exports__PreUpdateEvent as PreUpdateEvent, __webpack_exports__Projection as Projection, __webpack_exports__Promise as Promise, __webpack_exports__PromiseState as PromiseState, __webpack_exports__Query as Query, __webpack_exports__QueryManager as QueryManager, __webpack_exports__RadiusAroundActorStrategy as RadiusAroundActorStrategy, __webpack_exports__Random as Random, __webpack_exports__Raster as Raster, __webpack_exports__Ray as Ray, __webpack_exports__RealisticSolver as RealisticSolver, __webpack_exports__Rectangle as Rectangle, __webpack_exports__RemovedComponent as RemovedComponent, __webpack_exports__RemovedEntity as RemovedEntity, __webpack_exports__Repeat as Repeat, __webpack_exports__RepeatForever as RepeatForever, __webpack_exports__Resolution as Resolution, __webpack_exports__Resource as Resource, __webpack_exports__RotateBy as RotateBy, __webpack_exports__RotateTo as RotateTo, __webpack_exports__RotationType as RotationType, __webpack_exports__ScaleBy as ScaleBy, __webpack_exports__ScaleTo as ScaleTo, __webpack_exports__Scene as Scene, __webpack_exports__Screen as Screen, __webpack_exports__ScreenAppender as ScreenAppender, __webpack_exports__ScreenElement as ScreenElement, __webpack_exports__ScrollPreventionMode as ScrollPreventionMode, __webpack_exports__Shape as Shape, __webpack_exports__Side as Side, __webpack_exports__SortedList as SortedList, __webpack_exports__Sound as Sound, __webpack_exports__Sprite as Sprite, __webpack_exports__SpriteFont as SpriteFont, __webpack_exports__SpriteSheet as SpriteSheet, __webpack_exports__StandardClock as StandardClock, __webpack_exports__StrategyContainer as StrategyContainer, __webpack_exports__Stream as Stream, __webpack_exports__SubscribeEvent as SubscribeEvent, __webpack_exports__System as System, __webpack_exports__SystemManager as SystemManager, __webpack_exports__SystemType as SystemType, __webpack_exports__TagComponent as TagComponent, __webpack_exports__TestClock as TestClock, __webpack_exports__Text as Text, __webpack_exports__TextAlign as TextAlign, __webpack_exports__TileMap as TileMap, __webpack_exports__Timer as Timer, __webpack_exports__Traits as Traits, __webpack_exports__TransformComponent as TransformComponent, __webpack_exports__TreeNode as TreeNode, __webpack_exports__Trigger as Trigger, __webpack_exports__UnsubscribeEvent as UnsubscribeEvent, __webpack_exports__Util as Util, __webpack_exports__Vector as Vector, __webpack_exports__VectorView as VectorView, __webpack_exports__VisibleEvent as VisibleEvent, __webpack_exports__WebAudio as WebAudio, __webpack_exports__WebAudioInstance as WebAudioInstance, __webpack_exports__World as World, __webpack_exports__canonicalizeAngle as canonicalizeAngle, __webpack_exports__clamp as clamp, __webpack_exports__createId as createId, __webpack_exports__hasGraphicsTick as hasGraphicsTick, __webpack_exports__hasOnInitialize as hasOnInitialize, __webpack_exports__hasOnPostUpdate as hasOnPostUpdate, __webpack_exports__hasOnPreUpdate as hasOnPreUpdate, __webpack_exports__hasPostDraw as hasPostDraw, __webpack_exports__hasPreDraw as hasPreDraw, __webpack_exports__has_initialize as has_initialize, __webpack_exports__has_postupdate as has_postupdate, __webpack_exports__has_preupdate as has_preupdate, __webpack_exports__isAddedComponent as isAddedComponent, __webpack_exports__isAddedSystemEntity as isAddedSystemEntity, __webpack_exports__isRemoveSystemEntity as isRemoveSystemEntity, __webpack_exports__isRemovedComponent as isRemovedComponent, __webpack_exports__maxMessages as maxMessages, __webpack_exports__obsolete as obsolete, __webpack_exports__randomInRange as randomInRange, __webpack_exports__randomIntInRange as randomIntInRange, __webpack_exports__range as range, __webpack_exports__resetObsoleteCounter as resetObsoleteCounter, __webpack_exports__toDegrees as toDegrees, __webpack_exports__toRadians as toRadians, __webpack_exports__vec as vec };
28741
29143
 
28742
29144
  //# sourceMappingURL=excalibur.js.map