@gjsify/example-dom-excalibur-jelly-jumper 0.1.15 → 0.3.0

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 (3) hide show
  1. package/dist/browser.js +289 -52
  2. package/dist/gjs.js +3012 -1709
  3. package/package.json +13 -13
package/dist/browser.js CHANGED
@@ -37086,6 +37086,10 @@ var PhysicsActor = class extends Actor {
37086
37086
  touching = new TouchingComponent();
37087
37087
  isOnGround = false;
37088
37088
  _oldPosGlobal = vec(0, 0);
37089
+ // Pre-allocated rays for raycastSide — mutated in-place each call to avoid
37090
+ // per-frame Ray + Vector allocations (8 vec() calls per raycastSide invocation).
37091
+ _ray1 = new Ray(vec(0, 0), vec(1, 0));
37092
+ _ray2 = new Ray(vec(0, 0), vec(1, 0));
37089
37093
  constructor(args) {
37090
37094
  super(args);
37091
37095
  this.addComponent(new CarriableComponent());
@@ -37096,7 +37100,8 @@ var PhysicsActor = class extends Actor {
37096
37100
  this.isOnGround = this.touching.bottom.size > 0;
37097
37101
  });
37098
37102
  this.on("postupdate", () => {
37099
- this._oldPosGlobal = this.getGlobalPos().clone();
37103
+ const gp = this.getGlobalPos();
37104
+ this._oldPosGlobal.setTo(gp.x, gp.y);
37100
37105
  });
37101
37106
  }
37102
37107
  get canBeCarried() {
@@ -37114,27 +37119,38 @@ var PhysicsActor = class extends Actor {
37114
37119
  }).filter(__assignType6((hit) => hit.body !== this.body, ["hit", "", 'P"2!"/"'])).sort(__assignType6((a, b) => a.distance - b.distance, ["a", "b", "", 'P"2!"2""/#']));
37115
37120
  }
37116
37121
  raycastSide(side, distance, opts) {
37117
- const bounds = new BoundingBox({
37118
- left: Math.round(this.collider.bounds.left) + 1,
37119
- right: Math.round(this.collider.bounds.right) - 1,
37120
- top: Math.round(this.collider.bounds.top) + 1,
37121
- bottom: Math.round(this.collider.bounds.bottom) - 1
37122
- });
37123
- let ray1;
37124
- let ray2;
37122
+ const cb = this.collider.bounds;
37123
+ const bl2 = Math.round(cb.left) + 1;
37124
+ const br2 = Math.round(cb.right) - 1;
37125
+ const bt2 = Math.round(cb.top) + 1;
37126
+ const bb = Math.round(cb.bottom) - 1;
37125
37127
  if (side === "left" || side === "right") {
37126
- ray1 = new Ray(vec(side === "left" ? bounds.left : bounds.right, bounds.top), vec(side === "left" ? -1 : 1, 0));
37127
- ray2 = new Ray(vec(side === "left" ? bounds.left : bounds.right, bounds.bottom), vec(side === "left" ? -1 : 1, 0));
37128
- } else if (side === "top" || side === "bottom") {
37129
- ray1 = new Ray(vec(bounds.left, side === "top" ? bounds.top : bounds.bottom), vec(0, side === "top" ? -1 : 1));
37130
- ray2 = new Ray(vec(bounds.right, side === "top" ? bounds.top : bounds.bottom), vec(0, side === "top" ? -1 : 1));
37128
+ const x2 = side === "left" ? bl2 : br2;
37129
+ const dx = side === "left" ? -1 : 1;
37130
+ this._ray1.pos.setTo(x2, bt2);
37131
+ this._ray1.dir.setTo(dx, 0);
37132
+ this._ray2.pos.setTo(x2, bb);
37133
+ this._ray2.dir.setTo(dx, 0);
37134
+ } else {
37135
+ const y = side === "top" ? bt2 : bb;
37136
+ const dy = side === "top" ? -1 : 1;
37137
+ this._ray1.pos.setTo(bl2, y);
37138
+ this._ray1.dir.setTo(0, dy);
37139
+ this._ray2.pos.setTo(br2, y);
37140
+ this._ray2.dir.setTo(0, dy);
37141
+ }
37142
+ const hits1 = this.raycast(this._ray1, distance, opts);
37143
+ const hits2 = this.raycast(this._ray2, distance, opts);
37144
+ if (hits2.length === 0)
37145
+ return hits1;
37146
+ if (hits1.length === 0)
37147
+ return hits2;
37148
+ const result = hits1.slice();
37149
+ for (const h of hits2) {
37150
+ if (hits1.indexOf(h) === -1)
37151
+ result.push(h);
37131
37152
  }
37132
- return [
37133
- ...this.raycast(ray1, distance, opts),
37134
- ...this.raycast(ray2, distance, opts)
37135
- ].filter(__assignType6((value, index, self) => {
37136
- return self.indexOf(value) === index;
37137
- }, ["value", "index", "self", "", 'P"2!"2""2#"/$']));
37153
+ return result;
37138
37154
  }
37139
37155
  getGlobalOldPos() {
37140
37156
  return this._oldPosGlobal;
@@ -37145,7 +37161,11 @@ var PhysicsActor = class extends Actor {
37145
37161
  return false;
37146
37162
  }, "_oldPosGlobal", function() {
37147
37163
  return vec(0, 0);
37148
- }, "args", "constructor", "engine", "onInitialize", "ray", "distance", () => __\u03A9Omit, "maxDistance", "opts", "raycast", "left", "right", "top", "bottom", "side", () => __\u03A9Omit, "maxDistance", "raycastSide", "getGlobalOldPos", "PhysicsActor", `P7!!3">#)3$>%!3&;>'P!2("0)P!2*$0+!P!2,'2-!./o.#208"01PP.2.3.4.5J26'2-!.8o7#208"09P"0:5w;`];
37164
+ }, "_ray1", function() {
37165
+ return new Ray(vec(0, 0), vec(1, 0));
37166
+ }, "_ray2", function() {
37167
+ return new Ray(vec(0, 0), vec(1, 0));
37168
+ }, "args", "constructor", "engine", "onInitialize", "ray", "distance", () => __\u03A9Omit, "maxDistance", "opts", "raycast", "left", "right", "top", "bottom", "side", () => __\u03A9Omit, "maxDistance", "raycastSide", "getGlobalOldPos", "PhysicsActor", `P7!!3">#)3$>%!3&;>'!3(;>)!3*;>+P!2,"0-P!2.$0/!P!20'21!.3o2#248"05PP.6.7.8.9J2:'21!.<o;#248"0=P"0>5w?`];
37149
37169
  };
37150
37170
 
37151
37171
  // src/state/audio.ts
@@ -37957,7 +37977,11 @@ var Player = class _Player extends PhysicsActor {
37957
37977
  }
37958
37978
  }
37959
37979
  get bouncepad() {
37960
- return Array.from(this.touching.bottom).find(__assignType10((e2) => e2.hasTag("bouncepad"), ["e", "", 'P"2!"/"']));
37980
+ for (const e2 of this.touching.bottom) {
37981
+ if (e2.hasTag("bouncepad"))
37982
+ return e2;
37983
+ }
37984
+ return void 0;
37961
37985
  }
37962
37986
  get isTouchingLadder() {
37963
37987
  return this.touching.ladders.size > 0;
@@ -38974,18 +38998,26 @@ var EnemySpawner = class extends Actor {
38974
38998
  });
38975
38999
  this.scene.engine.add(this.spawnedInstance);
38976
39000
  }
38977
- onPreUpdate(engine, elapsed) {
38978
- const camera = engine.currentScene.camera;
38979
- const boundsWithBuffer = new BoundingBox(camera.viewport.left - this.OFFSCREEN_BUFFER, camera.viewport.top - this.OFFSCREEN_BUFFER, camera.viewport.right + this.OFFSCREEN_BUFFER, camera.viewport.bottom + this.OFFSCREEN_BUFFER);
38980
- const isOffScreen = !boundsWithBuffer.contains(this.pos);
39001
+ onPreUpdate(engine, _elapsed) {
39002
+ const vp = engine.currentScene.camera.viewport;
39003
+ const buf = this.OFFSCREEN_BUFFER;
39004
+ const left = vp.left - buf;
39005
+ const top = vp.top - buf;
39006
+ const right = vp.right + buf;
39007
+ const bottom = vp.bottom + buf;
39008
+ const { x: x2, y } = this.pos;
39009
+ const isOffScreen = x2 < left || x2 > right || y < top || y > bottom;
38981
39010
  if (!isOffScreen) {
38982
39011
  this.spawnInstance();
38983
- } else if (isOffScreen && !this.spawnedInstance) {
39012
+ } else if (!this.spawnedInstance) {
38984
39013
  this.canSpawn = true;
38985
39014
  }
38986
- if (this.spawnedInstance && !boundsWithBuffer.contains(this.spawnedInstance.getGlobalPos())) {
38987
- this.spawnedInstance.kill();
38988
- this.spawnedInstance = null;
39015
+ if (this.spawnedInstance) {
39016
+ const ip = this.spawnedInstance.getGlobalPos();
39017
+ if (ip.x < left || ip.x > right || ip.y < top || ip.y > bottom) {
39018
+ this.spawnedInstance.kill();
39019
+ this.spawnedInstance = null;
39020
+ }
38989
39021
  }
38990
39022
  }
38991
39023
  static __type = [() => Actor, "OFFSCREEN_BUFFER", function() {
@@ -38994,7 +39026,7 @@ var EnemySpawner = class extends Actor {
38994
39026
  return null;
38995
39027
  }, "canSpawn", function() {
38996
39028
  return true;
38997
- }, "pos", () => EnemyActor, "", "spawn", () => __\u03A9EnemySpawnerArgs, "param0", "constructor", "spawnInstance", "engine", "elapsed", "onPreUpdate", "EnemySpawner", `P7!'3">#PP7$,J3%;>&)3';>(P!2)P7*/+3,Pn-2."0/P"00P!21'22$035w4`];
39029
+ }, "pos", () => EnemyActor, "", "spawn", () => __\u03A9EnemySpawnerArgs, "param0", "constructor", "spawnInstance", "engine", "_elapsed", "onPreUpdate", "EnemySpawner", `P7!'3">#PP7$,J3%;>&)3';>(P!2)P7*/+3,Pn-2."0/P"00P!21'22$035w4`];
38998
39030
  };
38999
39031
 
39000
39032
  // src/actors/enemies/bird.ts
@@ -39867,6 +39899,204 @@ var Demo = class extends Scene {
39867
39899
  static __type = [() => Scene, "onInitialize", "Demo", 'P7!P"0"5w#'];
39868
39900
  };
39869
39901
 
39902
+ // src/perf/performance-monitor.ts
39903
+ function __assignType17(fn2, args) {
39904
+ fn2.__type = args;
39905
+ return fn2;
39906
+ }
39907
+ var __\u03A9PerfStats = ["platform", "frames", "fps_avg", "fps_min", "fps_max", "update_avg_ms", "draw_avg_ms", "frame_avg_ms", "dropped", "PerfStats", `P&4!'4"'4#'4$'4%'4&'4''4('4)Mw*y`];
39908
+ var PerformanceMonitor = class {
39909
+ _platform;
39910
+ _updateStart = 0;
39911
+ _drawStart = 0;
39912
+ _frameStart = 0;
39913
+ _firstFrame = true;
39914
+ _frameTimes = [];
39915
+ _updateTimes = [];
39916
+ _drawTimes = [];
39917
+ _droppedFrames = 0;
39918
+ _sampleCount = 0;
39919
+ _logInterval = 60;
39920
+ _logToConsole = false;
39921
+ _updateCallback;
39922
+ _lastStats = null;
39923
+ constructor(platform) {
39924
+ this._platform = platform;
39925
+ }
39926
+ get lastStats() {
39927
+ return this._lastStats;
39928
+ }
39929
+ setLogging(enabled) {
39930
+ this._logToConsole = enabled;
39931
+ }
39932
+ onUpdate(cb) {
39933
+ this._updateCallback = cb;
39934
+ }
39935
+ attach(engine, logToConsole = false) {
39936
+ this._logToConsole = logToConsole;
39937
+ engine.on("preupdate", () => {
39938
+ this._updateStart = performance.now();
39939
+ });
39940
+ engine.on("postupdate", () => {
39941
+ this._updateTimes.push(performance.now() - this._updateStart);
39942
+ });
39943
+ engine.on("predraw", () => {
39944
+ this._drawStart = performance.now();
39945
+ });
39946
+ engine.on("postdraw", () => {
39947
+ this._drawTimes.push(performance.now() - this._drawStart);
39948
+ const now = performance.now();
39949
+ if (!this._firstFrame) {
39950
+ const ft2 = now - this._frameStart;
39951
+ this._frameTimes.push(ft2);
39952
+ if (ft2 > 20)
39953
+ this._droppedFrames++;
39954
+ }
39955
+ this._frameStart = now;
39956
+ this._firstFrame = false;
39957
+ this._sampleCount++;
39958
+ if (this._sampleCount >= this._logInterval) {
39959
+ this._report();
39960
+ this._frameTimes = [];
39961
+ this._updateTimes = [];
39962
+ this._drawTimes = [];
39963
+ this._droppedFrames = 0;
39964
+ this._sampleCount = 0;
39965
+ }
39966
+ });
39967
+ }
39968
+ _avg(arr) {
39969
+ return arr.length ? arr.reduce(__assignType17((a, b) => a + b, ["a", "b", "", 'P"2!"2""/#']), 0) / arr.length : 0;
39970
+ }
39971
+ _report() {
39972
+ const frameAvg = this._avg(this._frameTimes);
39973
+ const frameMax = this._frameTimes.length ? Math.max(...this._frameTimes) : 0;
39974
+ const frameMin = this._frameTimes.length ? Math.min(...this._frameTimes) : 0;
39975
+ const stats = {
39976
+ platform: this._platform,
39977
+ frames: this._frameTimes.length,
39978
+ fps_avg: +(frameAvg > 0 ? 1e3 / frameAvg : 0).toFixed(1),
39979
+ fps_min: +(frameMax > 0 ? 1e3 / frameMax : 0).toFixed(1),
39980
+ fps_max: +(frameMin > 0 ? 1e3 / frameMin : 0).toFixed(1),
39981
+ update_avg_ms: +this._avg(this._updateTimes).toFixed(2),
39982
+ draw_avg_ms: +this._avg(this._drawTimes).toFixed(2),
39983
+ frame_avg_ms: +frameAvg.toFixed(2),
39984
+ dropped: this._droppedFrames
39985
+ };
39986
+ this._lastStats = stats;
39987
+ if (this._logToConsole)
39988
+ console.log("[PERF]", JSON.stringify(stats));
39989
+ this._updateCallback?.(stats);
39990
+ }
39991
+ static __type = ["_platform", "_updateStart", function() {
39992
+ return 0;
39993
+ }, "_drawStart", function() {
39994
+ return 0;
39995
+ }, "_frameStart", function() {
39996
+ return 0;
39997
+ }, "_firstFrame", function() {
39998
+ return true;
39999
+ }, "_frameTimes", function() {
40000
+ return [];
40001
+ }, "_updateTimes", function() {
40002
+ return [];
40003
+ }, "_drawTimes", function() {
40004
+ return [];
40005
+ }, "_droppedFrames", function() {
40006
+ return 0;
40007
+ }, "_sampleCount", function() {
40008
+ return 0;
40009
+ }, "_logInterval", function() {
40010
+ return 60;
40011
+ }, "_logToConsole", function() {
40012
+ return false;
40013
+ }, () => __\u03A9PerfStats, "stats", "", "_updateCallback", () => __\u03A9PerfStats, "_lastStats", function() {
40014
+ return null;
40015
+ }, "gjs", "browser", "platform", "constructor", "enabled", "setLogging", () => __\u03A9PerfStats, "cb", "onUpdate", "engine", "logToConsole", "attach", "arr", "_avg", "_report", "PerformanceMonitor", `&3!9;'3";>#'3$;>%'3&;>')3(;>)'F3*;>+'F3,;>-'F3.;>/'30;>1'32;>3'349;>5)36;>7Pn829$/:3;8;Pn<,J3=;>>PP.?.@J2A"0B!P)2C$0DPPnE29$/:2F$0GP!2H"2I$0JP'F2K'0L;P$0M;5wN`];
40016
+ };
40017
+
40018
+ // src/perf/performance-hud.ts
40019
+ function __assignType18(fn2, args) {
40020
+ fn2.__type = args;
40021
+ return fn2;
40022
+ }
40023
+ var PerformanceHUD = class extends ScreenElement {
40024
+ _lines = [];
40025
+ _frameCount = 0;
40026
+ _monitor;
40027
+ _platform;
40028
+ _hudVisible = false;
40029
+ constructor(monitor, platform) {
40030
+ super({
40031
+ pos: vec(3, 3),
40032
+ anchor: vec(0, 0),
40033
+ z: 9999,
40034
+ coordPlane: CoordPlane.Screen
40035
+ });
40036
+ this._monitor = monitor;
40037
+ this._platform = platform;
40038
+ }
40039
+ onInitialize(engine) {
40040
+ const font = new Font({
40041
+ family: "monospace",
40042
+ size: 7
40043
+ });
40044
+ const initialTexts = [
40045
+ `[${this._platform.toUpperCase()}] FPS: --`,
40046
+ `Frame: --ms Dropped: --`,
40047
+ `Update: --ms Draw: --ms`,
40048
+ `F1: toggle`
40049
+ ];
40050
+ for (let i = 0; i < initialTexts.length; i++) {
40051
+ const label = new Label({
40052
+ text: initialTexts[i],
40053
+ pos: vec(0, i * 9),
40054
+ anchor: vec(0, 0),
40055
+ font,
40056
+ color: Color.Black,
40057
+ z: this.z,
40058
+ coordPlane: CoordPlane.Screen
40059
+ });
40060
+ this._lines.push(label);
40061
+ this.addChild(label);
40062
+ }
40063
+ this._lines.forEach(__assignType18((l) => {
40064
+ l.graphics.opacity = 0;
40065
+ }, ["l", "", 'P"2!"/"']));
40066
+ engine.input.keyboard.on("press", __assignType18((evt) => {
40067
+ if (evt.key === Keys.F1) {
40068
+ this._hudVisible = !this._hudVisible;
40069
+ this._lines.forEach(__assignType18((l) => {
40070
+ l.graphics.opacity = this._hudVisible ? 1 : 0;
40071
+ }, ["l", "", 'P"2!"/"']));
40072
+ this._monitor.setLogging(this._hudVisible);
40073
+ }
40074
+ }, ["evt", "", 'P!2!"/"']));
40075
+ }
40076
+ onPreUpdate(_engine, _delta) {
40077
+ this._frameCount++;
40078
+ if (this._frameCount < 30)
40079
+ return;
40080
+ this._frameCount = 0;
40081
+ const stats = this._monitor.lastStats;
40082
+ if (stats)
40083
+ this._renderStats(stats);
40084
+ }
40085
+ _renderStats(s) {
40086
+ this._lines[0].text = `[${s.platform.toUpperCase()}] FPS: ${s.fps_avg.toFixed(1)} (min:${s.fps_min.toFixed(1)})`;
40087
+ this._lines[1].text = `Frame: ${s.frame_avg_ms.toFixed(1)}ms Dropped: ${s.dropped}/${s.frames}`;
40088
+ this._lines[2].text = `Update: ${s.update_avg_ms.toFixed(1)}ms Draw: ${s.draw_avg_ms.toFixed(1)}ms`;
40089
+ this._lines[3].text = `F1: toggle HUD`;
40090
+ }
40091
+ static __type = [() => ScreenElement, "_lines", function() {
40092
+ return [];
40093
+ }, "_frameCount", function() {
40094
+ return 0;
40095
+ }, "PerformanceMonitor", "_monitor", "_platform", "_hudVisible", function() {
40096
+ return false;
40097
+ }, "monitor", "platform", "constructor", "engine", "onInitialize", "_engine", "_delta", "onPreUpdate", "PerfStats", "s", "_renderStats", "PerformanceHUD", `P7!!F3"9;>#'3$;>%"w&3'9;&3(9;)3);>*P"w&2+&2,"0-P!2.$0/P!20'21$02P"w324$05;5w6`];
40098
+ };
40099
+
39870
40100
  // src/game.ts
39871
40101
  var __\u03A9HTMLCanvasElement = [() => __\u03A9HTMLElement, "height", "width", "frameRequestRate", () => __\u03A9MediaStream, "captureStream", "2d", "contextId", () => __\u03A9CanvasRenderingContext2DSettings, "options", () => __\u03A9CanvasRenderingContext2D, "getContext", "bitmaprenderer", () => __\u03A9ImageBitmapRenderingContextSettings, () => __\u03A9ImageBitmapRenderingContext, "webgl", () => __\u03A9WebGLContextAttributes, () => __\u03A9WebGLRenderingContext, "webgl2", () => __\u03A9WebGLContextAttributes, () => __\u03A9WebGL2RenderingContext, () => __\u03A9RenderingContext, () => __\u03A9BlobCallback, "callback", "type", "quality", "toBlob", "toDataURL", () => __\u03A9OffscreenCanvas, "transferControlToOffscreen", 0, "this", () => __\u03A9HTMLElementEventMap, "ev", "", "listener", () => __\u03A9AddEventListenerOptions, "addEventListener", () => __\u03A9EventListenerOrEventListenerObject, () => __\u03A9AddEventListenerOptions, 0, () => __\u03A9HTMLElementEventMap, () => __\u03A9EventListenerOptions, "removeEventListener", () => __\u03A9EventListenerOrEventListenerObject, () => __\u03A9EventListenerOptions, "HTMLCanvasElement", `Pn!'4"'4#P'2$8n%1&P.'2(n)2*8Pn+,J1,P.-2(n.2*8Pn/,J1,P.02(n12*8Pn2,J1,P.32(n42*8Pn5,J1,P&2("2*8Pn6,J1,Pn728&298'2:8$1;P&298'2:8&1<Pn=1>P"29Pn?2@nA"f2B"/C2DP)nEJ2*8$1FP&29nG2DP)nHJ2*8$1FP"29PnI2@nJ"f2B"/C2DP)nKJ2*8$1LP&29nM2DP)nNJ2*8$1LMwOy`];
39872
40102
  var __\u03A9HTMLElement = [() => __\u03A9Element, () => __\u03A9ElementCSSInlineStyle, () => __\u03A9ElementContentEditable, () => __\u03A9GlobalEventHandlers, () => __\u03A9HTMLOrSVGElement, "accessKey", "accessKeyLabel", "autocapitalize", "autocorrect", "dir", "draggable", "until-found", "hidden", "inert", "innerText", "lang", "offsetHeight", "offsetLeft", () => __\u03A9Element, "offsetParent", "offsetTop", "offsetWidth", "outerText", "popover", "spellcheck", "title", "translate", "writingSuggestions", () => __\u03A9ElementInternals, "attachInternals", "click", "hidePopover", () => __\u03A9ShowPopoverOptions, "options", "showPopover", () => __\u03A9TogglePopoverOptions, "togglePopover", "type", 0, "this", () => __\u03A9HTMLElementEventMap, "ev", "", "listener", () => __\u03A9AddEventListenerOptions, "addEventListener", () => __\u03A9EventListenerOrEventListenerObject, () => __\u03A9AddEventListenerOptions, 0, () => __\u03A9HTMLElementEventMap, () => __\u03A9EventListenerOptions, "removeEventListener", () => __\u03A9EventListenerOrEventListenerObject, () => __\u03A9EventListenerOptions, "HTMLElement", `Pn!n"n#n$n%&4&&4'9&4()4)&4*)4+P).,J4-)4.&4/&40'419'429Pn3,J449'459'469&47P&,J48)49&4:)4;&4<Pn=1>P$1?P$1@PnA2B8$1CPPnD)J2B8)1EP"2FPnG2HnI"f2J"/K2LP)nMJ2B8$1NP&2FnO2LP)nPJ2B8$1NP"2FPnQ2HnR"f2J"/K2LP)nSJ2B8$1TP&2FnU2LP)nVJ2B8$1TMwWy`];
@@ -41103,13 +41333,13 @@ var __\u03A9PushEncryptionKeyName = ["auth", "p256dh", "PushEncryptionKeyName",
41103
41333
  var __\u03A9PushSubscriptionJSON = ["endpoint", () => __\u03A9EpochTimeStamp, "expirationTime", () => __\u03A9Record4, "keys", "PushSubscriptionJSON", 'P&4!8Pn",J4#8&&o$#4%8Mw&y'];
41104
41334
  var __\u03A9WriteParams = [() => __\u03A9BufferSource, () => __\u03A9Blob, "data", "position", "size", () => __\u03A9WriteCommandType, "type", "WriteParams", `PPn!n"&,J4#8P',J4$8P',J4%8n&4'Mw(y`];
41105
41335
  var __\u03A9WriteCommandType = ["seek", "truncate", "write", "WriteCommandType", 'P.!.".#Jw$y'];
41106
- function __assignType17(fn2, args) {
41336
+ function __assignType19(fn2, args) {
41107
41337
  fn2.__type = args;
41108
41338
  return fn2;
41109
41339
  }
41110
41340
  var __\u03A9GameHandle = ["engine", "pause", "resume", "isPaused", "mute", "unmute", "isMuted", "GameHandle", `P!4!P$1"P$1#)4$9P$1%P$1&)4'9Mw(y`];
41111
- var __\u03A9StartGameOptions = ["startMuted", "assetBase", "StartGameOptions", 'P)4!8&4"8Mw#y'];
41112
- function buildEngineOptions(canvas) {
41341
+ var __\u03A9StartGameOptions = ["startMuted", "assetBase", "gjs", "browser", "platform", "pixelRatio", "fixedUpdateFps", "enablePerf", "StartGameOptions", `P)4!8&4"8P.#.$J4%8'4&8'4'8)4(8Mw)y`];
41342
+ function buildEngineOptions(canvas, options) {
41113
41343
  return {
41114
41344
  canvasElement: canvas,
41115
41345
  suppressMinimumBrowserFeatureDetection: true,
@@ -41119,7 +41349,7 @@ function buildEngineOptions(canvas) {
41119
41349
  width: Resolution.SNES.height / 9 * 16
41120
41350
  },
41121
41351
  displayMode: DisplayMode.FitContainerAndFill,
41122
- fixedUpdateFps: 60,
41352
+ fixedUpdateFps: options?.fixedUpdateFps ?? 60,
41123
41353
  physics: {
41124
41354
  gravity: GRAVITY,
41125
41355
  solver: SolverStrategy.Arcade,
@@ -41130,7 +41360,7 @@ function buildEngineOptions(canvas) {
41130
41360
  compositeStrategy: "separate"
41131
41361
  }
41132
41362
  },
41133
- pixelRatio: 4,
41363
+ pixelRatio: options?.pixelRatio ?? 4,
41134
41364
  pixelArt: true,
41135
41365
  scenes: {
41136
41366
  root: {
@@ -41144,14 +41374,14 @@ function buildEngineOptions(canvas) {
41144
41374
  }
41145
41375
  };
41146
41376
  }
41147
- buildEngineOptions.__type = [() => __\u03A9HTMLCanvasElement, "canvas", "buildEngineOptions", 'Pn!2"!/#'];
41377
+ buildEngineOptions.__type = [() => __\u03A9HTMLCanvasElement, "canvas", () => __\u03A9StartGameOptions, "options", "buildEngineOptions", 'Pn!2"n#2$8!/%'];
41148
41378
  function rebaseResources(base) {
41149
41379
  for (const category of Object.values(Resources)) {
41150
41380
  for (const resource of Object.values(category)) {
41151
41381
  if (!resource || typeof resource !== "object")
41152
41382
  continue;
41153
41383
  const r = resource;
41154
- const rebase = __assignType17(
41384
+ const rebase = __assignType19(
41155
41385
  (p) => p.startsWith("/res/") ? base + p.slice(1) : p,
41156
41386
  ["p", "", 'P&2!"/"']
41157
41387
  );
@@ -41169,23 +41399,29 @@ async function startGame(canvas, options) {
41169
41399
  if (options?.assetBase)
41170
41400
  rebaseResources(options.assetBase);
41171
41401
  AudioManager.init(options?.startMuted);
41172
- const game = new Engine(buildEngineOptions(canvas));
41402
+ const pixelRatio = options?.pixelRatio ?? 4;
41403
+ const platform = options?.platform ?? "browser";
41404
+ const game = new Engine(buildEngineOptions(canvas, options));
41173
41405
  await game.start(loader);
41174
- game.screen.pixelRatioOverride = 4;
41406
+ game.screen.pixelRatioOverride = pixelRatio;
41175
41407
  game.screen.applyResolutionAndViewport();
41408
+ const monitor = new PerformanceMonitor(platform);
41409
+ monitor.attach(game, false);
41410
+ const hud = new PerformanceHUD(monitor, platform);
41411
+ game.currentScene.add(hud);
41176
41412
  let paused = false;
41177
41413
  return {
41178
41414
  engine: game,
41179
41415
  get isPaused() {
41180
41416
  return paused;
41181
41417
  },
41182
- pause: __assignType17(function pause() {
41418
+ pause: __assignType19(function pause() {
41183
41419
  if (!paused) {
41184
41420
  paused = true;
41185
41421
  game.stop();
41186
41422
  }
41187
41423
  }, ["pause", 'P"/!']),
41188
- resume: __assignType17(function resume() {
41424
+ resume: __assignType19(function resume() {
41189
41425
  if (paused) {
41190
41426
  paused = false;
41191
41427
  game.start();
@@ -41194,10 +41430,10 @@ async function startGame(canvas, options) {
41194
41430
  get isMuted() {
41195
41431
  return AudioManager.isMuted;
41196
41432
  },
41197
- mute: __assignType17(function mute() {
41433
+ mute: __assignType19(function mute() {
41198
41434
  AudioManager.muteAll();
41199
41435
  }, ["mute", 'P"/!']),
41200
- unmute: __assignType17(function unmute() {
41436
+ unmute: __assignType19(function unmute() {
41201
41437
  AudioManager.unmuteAll();
41202
41438
  }, ["unmute", 'P"/!'])
41203
41439
  };
@@ -42440,11 +42676,11 @@ var __\u03A9GPUVertexFormat2 = ["float16", "float16x2", "float16x4", "float32",
42440
42676
  var __\u03A9WriteCommandType2 = ["seek", "truncate", "write", "WriteCommandType", 'P.!.".#Jw$y'];
42441
42677
  var __\u03A9GPUBlendFactor2 = ["constant", "dst", "dst-alpha", "one", "one-minus-constant", "one-minus-dst", "one-minus-dst-alpha", "one-minus-src", "one-minus-src-alpha", "src", "src-alpha", "src-alpha-saturated", "zero", "GPUBlendFactor", `P.!.".#.$.%.&.'.(.).*.+.,.-Jw.y`];
42442
42678
  var __\u03A9GPUBlendOperation2 = ["add", "max", "min", "reverse-subtract", "subtract", "GPUBlendOperation", 'P.!.".#.$.%Jw&y'];
42443
- function __assignType18(fn2, args) {
42679
+ function __assignType20(fn2, args) {
42444
42680
  fn2.__type = args;
42445
42681
  return fn2;
42446
42682
  }
42447
- var __\u03A9MountOptions = ["assetBase", "startMuted", "MountOptions", 'P&4!8)4"8Mw#y'];
42683
+ var __\u03A9MountOptions = ["assetBase", "startMuted", "enablePerf", "MountOptions", 'P&4!8)4"8)4#8Mw$y'];
42448
42684
  var __\u03A9ShowcaseHandle = ["pause", "resume", "isPaused", "mute", "unmute", "isMuted", "ShowcaseHandle", `PP$1!P$1")4#9P$1$P$1%)4&9Mw'y`];
42449
42685
  function parseSvg(src) {
42450
42686
  const doc = new DOMParser().parseFromString(src, "image/svg+xml");
@@ -42523,7 +42759,8 @@ function mount(container, options) {
42523
42759
  if (canvasContainer.clientWidth === 0 || canvasContainer.clientHeight === 0)
42524
42760
  return;
42525
42761
  ro2.disconnect();
42526
- startGame(canvas, { startMuted: pendingMuted, assetBase: options?.assetBase }).then(__assignType18((g) => {
42762
+ const enablePerf = options?.enablePerf ?? (typeof location !== "undefined" && new URLSearchParams(location.search).get("perf") === "1");
42763
+ startGame(canvas, { startMuted: pendingMuted, assetBase: options?.assetBase, platform: "browser", enablePerf }).then(__assignType20((g) => {
42527
42764
  game = g;
42528
42765
  if (pendingPause) {
42529
42766
  game.pause();
@@ -42531,7 +42768,7 @@ function mount(container, options) {
42531
42768
  }
42532
42769
  updatePauseButton(game.isPaused);
42533
42770
  updateAudioButton(game.isMuted);
42534
- }, ["g", "", 'P"2!"/"'])).catch(__assignType18((err) => {
42771
+ }, ["g", "", 'P"2!"/"'])).catch(__assignType20((err) => {
42535
42772
  console.error("JellyJumper: startGame failed:", err);
42536
42773
  }, ["err", "", 'P"2!"/"']));
42537
42774
  });
@@ -42540,7 +42777,7 @@ function mount(container, options) {
42540
42777
  get isPaused() {
42541
42778
  return game ? game.isPaused : pendingPause;
42542
42779
  },
42543
- pause: __assignType18(function pause() {
42780
+ pause: __assignType20(function pause() {
42544
42781
  if (game) {
42545
42782
  game.pause();
42546
42783
  updatePauseButton(true);
@@ -42549,7 +42786,7 @@ function mount(container, options) {
42549
42786
  updatePauseButton(true);
42550
42787
  }
42551
42788
  }, ["pause", 'P"/!']),
42552
- resume: __assignType18(function resume() {
42789
+ resume: __assignType20(function resume() {
42553
42790
  if (game) {
42554
42791
  game.resume();
42555
42792
  updatePauseButton(false);
@@ -42561,7 +42798,7 @@ function mount(container, options) {
42561
42798
  get isMuted() {
42562
42799
  return game ? game.isMuted : pendingMuted;
42563
42800
  },
42564
- mute: __assignType18(function mute() {
42801
+ mute: __assignType20(function mute() {
42565
42802
  if (game) {
42566
42803
  game.mute();
42567
42804
  updateAudioButton(true);
@@ -42570,7 +42807,7 @@ function mount(container, options) {
42570
42807
  updateAudioButton(true);
42571
42808
  }
42572
42809
  }, ["mute", 'P"/!']),
42573
- unmute: __assignType18(function unmute() {
42810
+ unmute: __assignType20(function unmute() {
42574
42811
  if (game) {
42575
42812
  game.unmute();
42576
42813
  updateAudioButton(false);