gdcore-tools 2.0.0-gd-v5.5.233-autobuild → 2.0.0-gd-v5.5.235-autobuild

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 (61) hide show
  1. package/dist/Runtime/Extensions/3D/Cube3DRuntimeObject.js +1 -1
  2. package/dist/Runtime/Extensions/3D/Cube3DRuntimeObject.js.map +2 -2
  3. package/dist/Runtime/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.js +1 -1
  4. package/dist/Runtime/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.js.map +2 -2
  5. package/dist/Runtime/Extensions/3D/DirectionalLight.js +1 -1
  6. package/dist/Runtime/Extensions/3D/DirectionalLight.js.map +2 -2
  7. package/dist/Runtime/Extensions/3D/JsExtension.js +72 -9
  8. package/dist/Runtime/Extensions/3D/Model3DRuntimeObject.js +1 -1
  9. package/dist/Runtime/Extensions/3D/Model3DRuntimeObject.js.map +2 -2
  10. package/dist/Runtime/Extensions/3D/Model3DRuntimeObject3DRenderer.js +1 -1
  11. package/dist/Runtime/Extensions/3D/Model3DRuntimeObject3DRenderer.js.map +2 -2
  12. package/dist/Runtime/Extensions/BBText/JsExtension.js +6 -6
  13. package/dist/Runtime/Extensions/BitmapText/JsExtension.js +6 -6
  14. package/dist/Runtime/Extensions/Physics2Behavior/JsExtension.js +10 -10
  15. package/dist/Runtime/Extensions/Physics3DBehavior/JsExtension.js +20 -7
  16. package/dist/Runtime/Extensions/Physics3DBehavior/Physics3DRuntimeBehavior.js +1 -1
  17. package/dist/Runtime/Extensions/Physics3DBehavior/Physics3DRuntimeBehavior.js.map +2 -2
  18. package/dist/Runtime/Extensions/Physics3DBehavior/PhysicsCar3DRuntimeBehavior.js +1 -1
  19. package/dist/Runtime/Extensions/Physics3DBehavior/PhysicsCar3DRuntimeBehavior.js.map +2 -2
  20. package/dist/Runtime/Extensions/PlatformBehavior/platformerobjectruntimebehavior.js +1 -1
  21. package/dist/Runtime/Extensions/PlatformBehavior/platformerobjectruntimebehavior.js.map +2 -2
  22. package/dist/Runtime/Extensions/Spine/managers/pixi-spine-atlas-manager.js +1 -1
  23. package/dist/Runtime/Extensions/Spine/managers/pixi-spine-atlas-manager.js.map +2 -2
  24. package/dist/Runtime/Extensions/Spine/managers/pixi-spine-manager.js +1 -1
  25. package/dist/Runtime/Extensions/Spine/managers/pixi-spine-manager.js.map +2 -2
  26. package/dist/Runtime/Extensions/TextInput/JsExtension.js +11 -11
  27. package/dist/Runtime/Extensions/TileMap/JsExtension.js +3 -3
  28. package/dist/Runtime/Model3DManager.js +1 -1
  29. package/dist/Runtime/Model3DManager.js.map +2 -2
  30. package/dist/Runtime/ResourceLoader.js +1 -1
  31. package/dist/Runtime/ResourceLoader.js.map +2 -2
  32. package/dist/Runtime/RuntimeLayer.js +1 -1
  33. package/dist/Runtime/RuntimeLayer.js.map +2 -2
  34. package/dist/Runtime/events-tools/objecttools.js +1 -1
  35. package/dist/Runtime/events-tools/objecttools.js.map +2 -2
  36. package/dist/Runtime/fontfaceobserver-font-manager/fontfaceobserver-font-manager.js +1 -1
  37. package/dist/Runtime/fontfaceobserver-font-manager/fontfaceobserver-font-manager.js.map +2 -2
  38. package/dist/Runtime/howler-sound-manager/howler-sound-manager.js +1 -1
  39. package/dist/Runtime/howler-sound-manager/howler-sound-manager.js.map +2 -2
  40. package/dist/Runtime/jsonmanager.js +1 -1
  41. package/dist/Runtime/jsonmanager.js.map +2 -2
  42. package/dist/Runtime/logger.js +1 -1
  43. package/dist/Runtime/logger.js.map +2 -2
  44. package/dist/Runtime/pixi-renderers/pixi-bitmapfont-manager.js +1 -1
  45. package/dist/Runtime/pixi-renderers/pixi-bitmapfont-manager.js.map +2 -2
  46. package/dist/Runtime/pixi-renderers/pixi-effects-manager.js.map +2 -2
  47. package/dist/Runtime/pixi-renderers/pixi-image-manager.js +1 -1
  48. package/dist/Runtime/pixi-renderers/pixi-image-manager.js.map +2 -2
  49. package/dist/Runtime/pixi-renderers/runtimegame-pixi-renderer.js +1 -1
  50. package/dist/Runtime/pixi-renderers/runtimegame-pixi-renderer.js.map +2 -2
  51. package/dist/Runtime/runtimegame.js +1 -1
  52. package/dist/Runtime/runtimegame.js.map +2 -2
  53. package/dist/Runtime/runtimescene.js +1 -1
  54. package/dist/Runtime/runtimescene.js.map +2 -2
  55. package/dist/Runtime/scenestack.js +1 -1
  56. package/dist/Runtime/scenestack.js.map +2 -2
  57. package/dist/Runtime/types/project-data.d.ts +6 -1
  58. package/dist/lib/libGD.cjs +1 -1
  59. package/dist/lib/libGD.wasm +0 -0
  60. package/gd.d.ts +21 -0
  61. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../GDevelop/GDJS/Runtime/pixi-renderers/runtimegame-pixi-renderer.ts"],
4
- "sourcesContent": ["namespace gdjs {\n const logger = new gdjs.Logger('PIXI game renderer');\n\n /**\n * Codes (as in `event.code`) of keys that should have their event `preventDefault`\n * called. This is used to avoid scrolling in a webpage when these keys are pressed\n * in the game.\n */\n const defaultPreventedKeyCodes = [\n 37, // ArrowLeft\n 38, // ArrowUp\n 39, // ArrowRight\n 40, // ArrowDown\n ];\n\n /**\n * The renderer for a gdjs.RuntimeGame using Pixi.js.\n */\n export class RuntimeGamePixiRenderer {\n _game: gdjs.RuntimeGame;\n _isFullPage: boolean = true;\n\n //Used to track if the canvas is displayed on the full page.\n _isFullscreen: boolean = false;\n\n //Used to track if the window is displayed as fullscreen (see setFullscreen method).\n _forceFullscreen: any;\n\n _pixiRenderer: PIXI.Renderer | null = null;\n private _threeRenderer: THREE.WebGLRenderer | null = null;\n private _gameCanvas: HTMLCanvasElement | null = null;\n private _domElementsContainer: HTMLDivElement | null = null;\n\n // Current width of the canvas (might be scaled down/up compared to renderer)\n _canvasWidth: float = 0;\n // Current height of the canvas (might be scaled down/up compared to renderer)\n _canvasHeight: float = 0;\n\n _keepRatio: boolean = true;\n _marginLeft: any;\n _marginTop: any;\n _marginRight: any;\n _marginBottom: any;\n\n _nextFrameId: integer = 0;\n\n _wasDisposed: boolean = false;\n\n /**\n * @param game The game that is being rendered\n * @param forceFullscreen If fullscreen should be always activated\n */\n constructor(game: gdjs.RuntimeGame, forceFullscreen: boolean) {\n this._game = game;\n this._forceFullscreen = forceFullscreen;\n\n //If set to true, the canvas will always be displayed as fullscreen, even if _isFullscreen == false.\n this._marginLeft =\n this._marginTop =\n this._marginRight =\n this._marginBottom =\n 0;\n this._setupOrientation();\n }\n\n /**\n * Create the canvas on which the game will be rendered, inside the specified DOM element, and\n * setup the rendering of the game.\n * If you want to use your own canvas, use `initializeRenderers` and `initializeCanvas` instead.\n *\n * @param parentElement The parent element to which the canvas will be added.\n */\n createStandardCanvas(parentElement: HTMLElement) {\n this._throwIfDisposed();\n\n const gameCanvas = document.createElement('canvas');\n parentElement.appendChild(gameCanvas);\n\n this.initializeRenderers(gameCanvas);\n this.initializeCanvas(gameCanvas);\n }\n\n /**\n * Set up the rendering of the game for the given canvas.\n *\n * In most cases, you can use `createStandardCanvas` instead to initialize the game.\n */\n initializeRenderers(gameCanvas: HTMLCanvasElement): void {\n this._throwIfDisposed();\n\n if (typeof THREE !== 'undefined') {\n this._threeRenderer = new THREE.WebGLRenderer({\n canvas: gameCanvas,\n antialias:\n this._game.getAntialiasingMode() !== 'none' &&\n (this._game.isAntialisingEnabledOnMobile() ||\n !gdjs.evtTools.common.isMobile()),\n preserveDrawingBuffer: true, // Keep to true to allow screenshots.\n });\n this._threeRenderer.useLegacyLights = true;\n this._threeRenderer.autoClear = false;\n this._threeRenderer.setSize(\n this._game.getGameResolutionWidth(),\n this._game.getGameResolutionHeight()\n );\n\n // Create a PixiJS renderer that use the same GL context as Three.js\n // so that both can render to the canvas and even have PixiJS rendering\n // reused in Three.js (by using a RenderTexture and the same internal WebGL texture).\n this._pixiRenderer = new PIXI.Renderer({\n width: this._game.getGameResolutionWidth(),\n height: this._game.getGameResolutionHeight(),\n view: gameCanvas,\n // @ts-ignore - reuse the context from Three.js.\n context: this._threeRenderer.getContext(),\n clearBeforeRender: false,\n preserveDrawingBuffer: true, // Keep to true to allow screenshots.\n antialias: false,\n backgroundAlpha: 0,\n // TODO (3D): add a setting for pixel ratio (`resolution: window.devicePixelRatio`)\n });\n } else {\n // Create the renderer and setup the rendering area.\n // \"preserveDrawingBuffer: true\" is needed to avoid flickering\n // and background issues on some mobile phones (see #585 #572 #566 #463).\n this._pixiRenderer = PIXI.autoDetectRenderer({\n width: this._game.getGameResolutionWidth(),\n height: this._game.getGameResolutionHeight(),\n view: gameCanvas,\n preserveDrawingBuffer: true,\n antialias: false,\n }) as PIXI.Renderer;\n }\n\n // Deactivating accessibility support in PixiJS renderer, as we want to be in control of this.\n // See https://github.com/pixijs/pixijs/issues/5111#issuecomment-420047824\n this._pixiRenderer.plugins.accessibility.destroy();\n delete this._pixiRenderer.plugins.accessibility;\n }\n\n /**\n * Set up the game canvas so that it covers the size required by the game\n * and has a container for DOM elements required by the game.\n */\n initializeCanvas(gameCanvas: HTMLCanvasElement): void {\n // Add the renderer view element to the DOM\n this._gameCanvas = gameCanvas;\n\n gameCanvas.style.position = 'absolute';\n\n // Ensure that the canvas has the focus.\n gameCanvas.tabIndex = 1;\n\n // Ensure long press can't create a selection\n gameCanvas.style.userSelect = 'none';\n gameCanvas.style.outline = 'none'; // No selection/focus ring on the canvas.\n\n // Set up the container for HTML elements on top of the game canvas.\n const domElementsContainer = document.createElement('div');\n domElementsContainer.style.position = 'absolute';\n domElementsContainer.style.overflow = 'hidden'; // Never show anything outside the container.\n domElementsContainer.style.outline = 'none'; // No selection/focus ring on this container.\n domElementsContainer.style.pointerEvents = 'none'; // Clicks go through the container.\n\n // The container should *never* scroll.\n // Elements are put inside with the same coordinates (with a scaling factor)\n // as on the game canvas.\n domElementsContainer.addEventListener('scroll', (event) => {\n domElementsContainer.scrollLeft = 0;\n domElementsContainer.scrollTop = 0;\n event.preventDefault();\n });\n\n // When clicking outside an input, (or other HTML element),\n // give back focus to the game canvas so that this element is blurred.\n gameCanvas.addEventListener('pointerdown', () => {\n gameCanvas.focus();\n });\n\n // Prevent magnifying glass on iOS with a long press.\n // Note that there are related bugs on iOS 15 (see https://bugs.webkit.org/show_bug.cgi?id=231161)\n // but it seems not to affect us as the `domElementsContainer` has `pointerEvents` set to `none`.\n domElementsContainer.style['-webkit-user-select'] = 'none';\n\n gameCanvas.parentNode?.appendChild(domElementsContainer);\n this._domElementsContainer = domElementsContainer;\n\n this._resizeCanvas();\n\n // Handle scale mode.\n if (this._game.getScaleMode() === 'nearest') {\n gameCanvas.style['image-rendering'] = '-moz-crisp-edges';\n gameCanvas.style['image-rendering'] = '-webkit-optimize-contrast';\n gameCanvas.style['image-rendering'] = '-webkit-crisp-edges';\n gameCanvas.style['image-rendering'] = 'pixelated';\n }\n\n // Handle pixels rounding.\n if (this._game.getPixelsRounding()) {\n PIXI.settings.ROUND_PIXELS = true;\n }\n\n // Handle resize: immediately adjust the game canvas (and dom element container)\n // and notify the game (that may want to adjust to the new size of the window).\n window.addEventListener('resize', () => {\n this._game.onWindowInnerSizeChanged();\n this._resizeCanvas();\n });\n\n // Focus the canvas when created.\n gameCanvas.focus();\n }\n\n static getWindowInnerWidth() {\n return typeof window !== 'undefined' ? window.innerWidth : 800;\n }\n\n static getWindowInnerHeight() {\n return typeof window !== 'undefined' ? window.innerHeight : 800;\n }\n\n /**\n * Update the game renderer size according to the \"game resolution\".\n * Called when game resolution changes.\n *\n * Note that if the canvas is fullscreen, it won't be resized, but when going back to\n * non fullscreen mode, the requested size will be used.\n */\n updateRendererSize(): void {\n this._resizeCanvas();\n }\n\n /**\n * Set the proper screen orientation from the project properties.\n */\n private _setupOrientation() {\n if (\n typeof window === 'undefined' ||\n !window.screen ||\n !window.screen.orientation\n ) {\n return;\n }\n const gameOrientation = this._game.getGameData().properties.orientation;\n try {\n // We ignore the error as some platforms may not supporting locking (i.e: desktop).\n if (gameOrientation === 'default') {\n const promise = window.screen.orientation.unlock();\n // @ts-ignore\n if (promise) {\n // @ts-ignore\n promise.catch(() => {});\n }\n } else {\n // @ts-ignore\n window.screen.orientation.lock(gameOrientation).catch(() => {});\n }\n } catch (error) {\n logger.error('Unexpected error while setting up orientation: ', error);\n }\n }\n\n /**\n * Resize the renderer (the \"game resolution\") and the canvas (which can be larger\n * or smaller to fill the page, with optional margins).\n *\n */\n private _resizeCanvas() {\n if (!this._pixiRenderer || !this._domElementsContainer) return;\n\n // Set the Pixi (and/or Three) renderer size to the game size.\n // There is no \"smart\" resizing to be done here: the rendering of the game\n // should be done with the size set on the game.\n if (\n this._pixiRenderer.width !== this._game.getGameResolutionWidth() ||\n this._pixiRenderer.height !== this._game.getGameResolutionHeight()\n ) {\n // TODO (3D): It might be useful to resize pixi view in 3D depending on FOV value\n // to enable a mode where pixi always fills the whole screen.\n this._pixiRenderer.resize(\n this._game.getGameResolutionWidth(),\n this._game.getGameResolutionHeight()\n );\n\n if (this._threeRenderer) {\n this._threeRenderer.setSize(\n this._game.getGameResolutionWidth(),\n this._game.getGameResolutionHeight()\n );\n }\n }\n\n // Set the canvas size.\n // Resizing is done according to the settings. This is a \"CSS\" resize\n // only, so won't create visual artifacts during the rendering.\n const isFullPage =\n this._forceFullscreen || this._isFullPage || this._isFullscreen;\n let canvasWidth = this._game.getGameResolutionWidth();\n let canvasHeight = this._game.getGameResolutionHeight();\n let maxWidth = window.innerWidth - this._marginLeft - this._marginRight;\n let maxHeight = window.innerHeight - this._marginTop - this._marginBottom;\n if (maxWidth < 0) {\n maxWidth = 0;\n }\n if (maxHeight < 0) {\n maxHeight = 0;\n }\n if (isFullPage && !this._keepRatio) {\n canvasWidth = maxWidth;\n canvasHeight = maxHeight;\n } else if (\n (isFullPage && this._keepRatio) ||\n canvasWidth > maxWidth ||\n canvasHeight > maxHeight\n ) {\n let factor = maxWidth / canvasWidth;\n if (canvasHeight * factor > maxHeight) {\n factor = maxHeight / canvasHeight;\n }\n canvasWidth *= factor;\n canvasHeight *= factor;\n }\n\n // Apply the calculations to the canvas element...\n if (this._gameCanvas) {\n this._gameCanvas.style.top =\n this._marginTop + (maxHeight - canvasHeight) / 2 + 'px';\n this._gameCanvas.style.left =\n this._marginLeft + (maxWidth - canvasWidth) / 2 + 'px';\n this._gameCanvas.style.width = canvasWidth + 'px';\n this._gameCanvas.style.height = canvasHeight + 'px';\n }\n\n // ...and to the div on top of it showing DOM elements (like inputs).\n this._domElementsContainer.style.top =\n this._marginTop + (maxHeight - canvasHeight) / 2 + 'px';\n this._domElementsContainer.style.left =\n this._marginLeft + (maxWidth - canvasWidth) / 2 + 'px';\n this._domElementsContainer.style.width = canvasWidth + 'px';\n this._domElementsContainer.style.height = canvasHeight + 'px';\n\n // Store the canvas size for fast access to it.\n this._canvasWidth = canvasWidth;\n this._canvasHeight = canvasHeight;\n }\n\n /**\n * Set if the aspect ratio must be kept when the game canvas is resized to fill\n * the page.\n */\n keepAspectRatio(enable) {\n if (this._keepRatio === enable) {\n return;\n }\n this._keepRatio = enable;\n this._resizeCanvas();\n }\n\n /**\n * Change the margin that must be preserved around the game canvas.\n */\n setMargins(top, right, bottom, left): void {\n this._throwIfDisposed();\n if (\n this._marginTop === top &&\n this._marginRight === right &&\n this._marginBottom === bottom &&\n this._marginLeft === left\n ) {\n return;\n }\n this._marginTop = top;\n this._marginRight = right;\n this._marginBottom = bottom;\n this._marginLeft = left;\n this._resizeCanvas();\n }\n\n /**\n * Update the window size, if possible.\n * @param width The new width, in pixels.\n * @param height The new height, in pixels.\n */\n setWindowSize(width: float, height: float): void {\n this._throwIfDisposed();\n const remote = this.getElectronRemote();\n if (remote) {\n const browserWindow = remote.getCurrentWindow();\n try {\n if (browserWindow) {\n browserWindow.setContentSize(width, height);\n }\n } catch (error) {\n logger.error(\n `Window size setting to width ${width} and height ${height} failed. See error:`,\n error\n );\n }\n } else {\n logger.warn(\"Window size can't be changed on this platform.\");\n }\n }\n\n /**\n * Center the window on screen.\n */\n centerWindow() {\n this._throwIfDisposed();\n const remote = this.getElectronRemote();\n if (remote) {\n const browserWindow = remote.getCurrentWindow();\n try {\n if (browserWindow) {\n browserWindow.center();\n }\n } catch (error) {\n logger.error('Window centering failed. See error:', error);\n }\n } else {\n logger.warn(\"Window can't be centered on this platform.\");\n }\n }\n\n /**\n * De/activate fullscreen for the game.\n */\n setFullScreen(enable): void {\n this._throwIfDisposed();\n if (this._forceFullscreen) {\n return;\n }\n if (this._isFullscreen !== enable) {\n this._isFullscreen = !!enable;\n const remote = this.getElectronRemote();\n if (remote) {\n const browserWindow = remote.getCurrentWindow();\n try {\n if (browserWindow) {\n browserWindow.setFullScreen(this._isFullscreen);\n }\n } catch (error) {\n logger.error(\n `Full screen setting to ${this._isFullscreen} failed. See error:`,\n error\n );\n }\n } else {\n // Use HTML5 Fullscreen API\n //TODO: Do this on a user gesture, otherwise most browsers won't activate fullscreen\n if (this._isFullscreen) {\n // @ts-ignore\n if (document.documentElement.requestFullscreen) {\n // @ts-ignore\n document.documentElement.requestFullscreen();\n } else {\n // @ts-ignore\n if (document.documentElement.mozRequestFullScreen) {\n // @ts-ignore\n document.documentElement.mozRequestFullScreen();\n } else {\n // @ts-ignore\n if (document.documentElement.webkitRequestFullScreen) {\n // @ts-ignore\n document.documentElement.webkitRequestFullScreen();\n }\n }\n }\n } else {\n // @ts-ignore\n if (document.exitFullscreen) {\n // @ts-ignore\n document.exitFullscreen();\n } else {\n // @ts-ignore\n if (document.mozCancelFullScreen) {\n // @ts-ignore\n document.mozCancelFullScreen();\n } else {\n // @ts-ignore\n if (document.webkitCancelFullScreen) {\n // @ts-ignore\n document.webkitCancelFullScreen();\n }\n }\n }\n }\n }\n this._resizeCanvas();\n }\n }\n\n /**\n * Checks if the game is in full screen.\n */\n isFullScreen(): boolean {\n const remote = this.getElectronRemote();\n if (remote) {\n try {\n return remote.getCurrentWindow().isFullScreen();\n } catch (error) {\n logger.error(`Full screen detection failed. See error:`, error);\n return false;\n }\n }\n\n // Height check is used to detect user triggered full screen (for example F11 shortcut).\n return this._isFullscreen || window.screen.height === window.innerHeight;\n }\n\n /**\n * Convert a point from the canvas coordinates to the dom element container coordinates.\n *\n * @param canvasCoords The point in the canvas coordinates.\n * @param result The point to return.\n * @returns The point in the dom element container coordinates.\n */\n convertCanvasToDomElementContainerCoords(\n canvasCoords: FloatPoint,\n result: FloatPoint\n ): FloatPoint {\n const pageCoords = result || [0, 0];\n\n // Handle the fact that the game is stretched to fill the canvas.\n pageCoords[0] =\n (canvasCoords[0] * this._canvasWidth) /\n this._game.getGameResolutionWidth();\n pageCoords[1] =\n (canvasCoords[1] * this._canvasHeight) /\n this._game.getGameResolutionHeight();\n\n return pageCoords;\n }\n\n /**\n * Return the scale factor between the renderer height and the actual canvas height,\n * which is also the height of the container for DOM elements to be superimposed on top of it.\n *\n * Useful to scale font sizes of DOM elements so that they follow the size of the game.\n */\n getCanvasToDomElementContainerHeightScale(): float {\n return (this._canvasHeight || 1) / this._game.getGameResolutionHeight();\n }\n\n /**\n * Translate an event position (mouse or touch) made on the canvas\n * on the page (or even outside the canvas) to game coordinates.\n */\n convertPageToGameCoords(pageX: float, pageY: float) {\n const canvas = this._gameCanvas;\n if (!canvas) return [0, 0];\n\n const pos = [pageX - canvas.offsetLeft, pageY - canvas.offsetTop];\n\n // Handle the fact that the game is stretched to fill the canvas.\n pos[0] *= this._game.getGameResolutionWidth() / (this._canvasWidth || 1);\n pos[1] *=\n this._game.getGameResolutionHeight() / (this._canvasHeight || 1);\n return pos;\n }\n\n /**\n * Add the standard events handler.\n *\n * The game canvas must have been initialized before calling this.\n */\n bindStandardEvents(\n manager: gdjs.InputManager,\n window: Window,\n document: Document\n ) {\n this._throwIfDisposed();\n const canvas = this._gameCanvas;\n if (!canvas) return;\n\n const isInsideCanvas = (e: MouseEvent | Touch) => {\n const x = e.pageX - canvas.offsetLeft;\n const y = e.pageY - canvas.offsetTop;\n\n return (\n 0 <= x &&\n x < (this._canvasWidth || 1) &&\n 0 <= y &&\n y < (this._canvasHeight || 1)\n );\n };\n\n // Some browsers lacks definition of some variables used to do calculations\n // in convertPageToGameCoords. They are defined to 0 as they are useless.\n\n (function ensureOffsetsExistence() {\n if (isNaN(canvas.offsetLeft)) {\n // @ts-ignore\n canvas.offsetLeft = 0;\n // @ts-ignore\n canvas.offsetTop = 0;\n }\n if (isNaN(document.body.scrollLeft)) {\n document.body.scrollLeft = 0;\n document.body.scrollTop = 0;\n }\n if (\n document.documentElement === undefined ||\n document.documentElement === null\n ) {\n // @ts-ignore\n document.documentElement = {};\n }\n if (isNaN(document.documentElement.scrollLeft)) {\n document.documentElement.scrollLeft = 0;\n document.documentElement.scrollTop = 0;\n }\n if (isNaN(canvas.offsetLeft)) {\n // @ts-ignore\n canvas.offsetLeft = 0;\n // @ts-ignore\n canvas.offsetTop = 0;\n }\n })();\n\n // Keyboard: listen at the document level to capture even when the canvas\n // is not focused.\n\n const isFocusingDomElement = () => {\n // Fast bailout when the game canvas should receive the inputs (i.e: almost always).\n // Also check the document body or null for activeElement, as all of these should go\n // to the game.\n if (\n document.activeElement === canvas ||\n document.activeElement === document.body ||\n document.activeElement === null\n )\n return false;\n\n return true;\n };\n const isTargetDomElement = (event: TouchEvent) => {\n // Fast bailout when the game canvas should receive the inputs (i.e: almost always).\n // Any event with a target that is not the body or the canvas should\n // not go to the game (<input> or <a> elements for instances).\n if (event.target === canvas || event.target === document.body)\n return false;\n return true;\n };\n document.onkeydown = function (e) {\n if (isFocusingDomElement()) {\n // Bail out if the game canvas is not focused. For example,\n // an `<input>` element can be focused, and needs to receive\n // arrow keys events.\n return;\n }\n\n if (defaultPreventedKeyCodes.includes(e.keyCode)) {\n // Some keys are \"default prevented\" to avoid scrolling when the game\n // is integrated in a page as an iframe.\n e.preventDefault();\n }\n\n manager.onKeyPressed(e.keyCode, e.location);\n };\n document.onkeyup = function (e) {\n if (isFocusingDomElement()) {\n // Bail out if the game canvas is not focused. For example,\n // an `<input>` element can be focused, and needs to receive\n // arrow keys events.\n return;\n }\n\n if (defaultPreventedKeyCodes.includes(e.keyCode)) {\n // Some keys are \"default prevented\" to avoid scrolling when the game\n // is integrated in a page as an iframe.\n e.preventDefault();\n }\n\n manager.onKeyReleased(e.keyCode, e.location);\n };\n\n // Mouse:\n\n // Converts HTML mouse button to InputManager mouse button.\n // This function is used to align HTML button values with GDevelop 3 C++ SFML Mouse button enum values,\n // notably the middle and right buttons.\n function convertHtmlMouseButtonToInputManagerMouseButton(button: number) {\n switch (button) {\n case 1: // Middle button\n return gdjs.InputManager.MOUSE_MIDDLE_BUTTON;\n case 2: // Right button\n return gdjs.InputManager.MOUSE_RIGHT_BUTTON;\n }\n return button;\n }\n canvas.onmousemove = (e) => {\n const pos = this.convertPageToGameCoords(e.pageX, e.pageY);\n manager.onMouseMove(pos[0], pos[1]);\n };\n canvas.onmousedown = (e) => {\n const pos = this.convertPageToGameCoords(e.pageX, e.pageY);\n manager.onMouseMove(pos[0], pos[1]);\n manager.onMouseButtonPressed(\n convertHtmlMouseButtonToInputManagerMouseButton(e.button)\n );\n if (window.focus !== undefined) {\n window.focus();\n }\n return false;\n };\n canvas.onmouseup = function (e) {\n manager.onMouseButtonReleased(\n convertHtmlMouseButtonToInputManagerMouseButton(e.button)\n );\n return false;\n };\n canvas.onmouseleave = function (e) {\n manager.onMouseLeave();\n };\n canvas.onmouseenter = function (e) {\n manager.onMouseEnter();\n // There is no mouse event when the cursor is outside of the canvas.\n // We catchup what happened.\n const buttons = [\n gdjs.InputManager.MOUSE_LEFT_BUTTON,\n gdjs.InputManager.MOUSE_RIGHT_BUTTON,\n gdjs.InputManager.MOUSE_MIDDLE_BUTTON,\n gdjs.InputManager.MOUSE_BACK_BUTTON,\n gdjs.InputManager.MOUSE_FORWARD_BUTTON,\n ];\n for (let i = 0, len = buttons.length; i < len; ++i) {\n const button = buttons[i];\n const buttonIsPressed = (e.buttons & (1 << i)) !== 0;\n const buttonWasPressed = manager.isMouseButtonPressed(button);\n if (buttonIsPressed && !buttonWasPressed) {\n manager.onMouseButtonPressed(button);\n } else if (!buttonIsPressed && buttonWasPressed) {\n manager.onMouseButtonReleased(button);\n }\n }\n };\n window.addEventListener(\n 'click',\n function (e) {\n if (window.focus !== undefined) {\n window.focus();\n }\n return false;\n },\n false\n );\n canvas.oncontextmenu = function (event) {\n event.preventDefault();\n event.stopPropagation();\n return false;\n };\n // @ts-ignore\n canvas.onwheel = function (event) {\n manager.onMouseWheel(-event.deltaY);\n };\n\n // Touches:\n window.addEventListener(\n 'touchmove',\n (e) => {\n if (isTargetDomElement(e)) {\n // Bail out if the game canvas is not focused. For example,\n // an `<input>` element can be focused, and needs to receive\n // touch events to move the selection (and do other native gestures).\n return;\n }\n\n e.preventDefault();\n if (e.changedTouches) {\n for (let i = 0; i < e.changedTouches.length; ++i) {\n const touch = e.changedTouches[i];\n const pos = this.convertPageToGameCoords(\n touch.pageX,\n touch.pageY\n );\n manager.onTouchMove(touch.identifier, pos[0], pos[1]);\n // This works because touch events are sent\n // when they continue outside of the canvas.\n if (manager.isSimulatingMouseWithTouch()) {\n if (isInsideCanvas(touch)) {\n manager.onMouseEnter();\n } else {\n manager.onMouseLeave();\n }\n }\n }\n }\n },\n // This is important so that we can use e.preventDefault() and block possible following mouse events.\n { passive: false }\n );\n window.addEventListener(\n 'touchstart',\n (e) => {\n if (isTargetDomElement(e)) {\n // Bail out if the game canvas is not focused. For example,\n // an `<input>` element can be focused, and needs to receive\n // touch events to move the selection (and do other native gestures).\n return;\n }\n\n e.preventDefault();\n if (e.changedTouches) {\n for (let i = 0; i < e.changedTouches.length; ++i) {\n const touch = e.changedTouches[i];\n const pos = this.convertPageToGameCoords(\n touch.pageX,\n touch.pageY\n );\n manager.onTouchStart(\n e.changedTouches[i].identifier,\n pos[0],\n pos[1]\n );\n }\n }\n return false;\n },\n // This is important so that we can use e.preventDefault() and block possible following mouse events.\n { passive: false }\n );\n window.addEventListener(\n 'touchend',\n function (e) {\n if (isTargetDomElement(e)) {\n // Bail out if the game canvas is not focused. For example,\n // an `<input>` element can be focused, and needs to receive\n // touch events to move the selection (and do other native gestures).\n return;\n }\n\n e.preventDefault();\n if (e.changedTouches) {\n for (let i = 0; i < e.changedTouches.length; ++i) {\n manager.onTouchEnd(e.changedTouches[i].identifier);\n }\n }\n return false;\n },\n // This is important so that we can use e.preventDefault() and block possible following mouse events.\n { passive: false }\n );\n window.addEventListener(\n 'touchcancel',\n function (e) {\n if (isTargetDomElement(e)) {\n // Bail out if the game canvas is not focused. For example,\n // an `<input>` element can be focused, and needs to receive\n // touch events to move the selection (and do other native gestures).\n return;\n }\n\n e.preventDefault();\n if (e.changedTouches) {\n for (let i = 0; i < e.changedTouches.length; ++i) {\n manager.onTouchCancel(e.changedTouches[i].identifier);\n }\n }\n return false;\n },\n // This is important so that we can use e.preventDefault() and block possible following mouse events.\n { passive: false }\n );\n }\n\n setWindowTitle(title): void {\n if (typeof document !== 'undefined') {\n document.title = title;\n }\n }\n\n getWindowTitle() {\n return typeof document !== 'undefined' ? document.title : '';\n }\n\n startGameLoop(fn) {\n this._throwIfDisposed();\n let oldTime = 0;\n const gameLoop = (time: float) => {\n // Schedule the next frame now to be sure it's called as soon\n // as possible after this one is finished.\n this._nextFrameId = requestAnimationFrame(gameLoop);\n\n const dt = oldTime ? time - oldTime : 0;\n oldTime = time;\n if (!fn(dt)) {\n // Stop the game loop if requested.\n cancelAnimationFrame(this._nextFrameId);\n }\n };\n\n requestAnimationFrame(gameLoop);\n }\n\n stopGameLoop(): void {\n cancelAnimationFrame(this._nextFrameId);\n }\n\n getPIXIRenderer() {\n return this._pixiRenderer;\n }\n\n /**\n * Get the Three.js renderer for the game - if any.\n */\n getThreeRenderer(): THREE.WebGLRenderer | null {\n return this._threeRenderer;\n }\n\n /**\n * Get the DOM element used as a container for HTML elements to display\n * on top of the game.\n */\n getDomElementContainer() {\n return this._domElementsContainer;\n }\n\n /**\n * Open the given URL in the system browser (or a new tab)\n */\n openURL(url: string) {\n // Try to detect the environment to use the most adapted\n // way of opening an URL.\n\n if (typeof window !== 'undefined') {\n const electron = this.getElectron();\n if (electron) {\n electron.shell.openExternal(url);\n } else if (\n // @ts-ignore\n typeof window.cordova !== 'undefined' &&\n // @ts-ignore\n typeof window.cordova.InAppBrowser !== 'undefined'\n ) {\n // @ts-ignore\n window.cordova.InAppBrowser.open(url, '_system', 'location=yes');\n } else {\n window.open(url, '_blank');\n }\n }\n }\n\n /**\n * Close the game, if applicable.\n */\n stopGame() {\n // Try to detect the environment to use the most adapted\n // way of closing the app\n const remote = this.getElectronRemote();\n if (remote) {\n const browserWindow = remote.getCurrentWindow();\n if (browserWindow) {\n try {\n browserWindow.close();\n } catch (error) {\n logger.error('Window closing failed. See error:', error);\n }\n }\n } else {\n if (\n typeof navigator !== 'undefined' &&\n // @ts-ignore\n navigator.app &&\n // @ts-ignore\n navigator.app.exitApp\n ) {\n // @ts-ignore\n navigator.app.exitApp();\n }\n }\n // HTML5 games on mobile/browsers don't have a way to close their window/page.\n }\n\n /**\n * Dispose the renderers (PixiJS and/or Three.js) as well as DOM elements\n * used for the game (the canvas, if specified, and the additional DOM container\n * created on top of it to allow display HTML elements, for example for text inputs).\n *\n * @param removeCanvas If true, the canvas will be removed from the DOM.\n */\n dispose(removeCanvas?: boolean) {\n this._pixiRenderer?.destroy();\n this._threeRenderer?.dispose();\n this._pixiRenderer = null;\n this._threeRenderer = null;\n\n if (removeCanvas && this._gameCanvas) {\n this._gameCanvas.parentNode?.removeChild(this._gameCanvas);\n }\n\n this._gameCanvas = null;\n this._domElementsContainer?.parentNode?.removeChild(\n this._domElementsContainer\n );\n this._domElementsContainer = null;\n this._wasDisposed = true;\n }\n\n /**\n * Get the canvas DOM element.\n */\n getCanvas(): HTMLCanvasElement | null {\n return this._gameCanvas;\n }\n\n /**\n * Check if the device supports WebGL.\n * @returns true if WebGL is supported\n */\n isWebGLSupported(): boolean {\n return (\n !!this._pixiRenderer &&\n this._pixiRenderer.type === PIXI.RENDERER_TYPE.WEBGL\n );\n }\n\n /**\n * Get the electron module, if running as a electron renderer process.\n */\n getElectron() {\n if (typeof require === 'function') {\n return require('electron');\n }\n return null;\n }\n\n /**\n * Helper to get the electron remote module, if running on Electron.\n * Note that is not guaranteed to be supported in the future - avoid if possible.\n */\n getElectronRemote = () => {\n if (typeof require === 'function') {\n const runtimeGameOptions = this._game.getAdditionalOptions();\n const moduleId =\n runtimeGameOptions && runtimeGameOptions.electronRemoteRequirePath\n ? runtimeGameOptions.electronRemoteRequirePath\n : '@electron/remote';\n\n try {\n return require(moduleId);\n } catch (requireError) {\n console.error(\n `Could not load @electron/remote from \"${moduleId}\". Error is:`,\n requireError\n );\n }\n }\n\n return null;\n };\n\n getGame() {\n return this._game;\n }\n\n private _throwIfDisposed(): void {\n if (this._wasDisposed) {\n throw 'The RuntimeGameRenderer has been disposed and should not be used anymore.';\n }\n }\n }\n\n //Register the class to let the engine use it.\n export type RuntimeGameRenderer = RuntimeGamePixiRenderer;\n export const RuntimeGameRenderer = RuntimeGamePixiRenderer;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["namespace gdjs {\n const logger = new gdjs.Logger('PIXI game renderer');\n\n /**\n * Codes (as in `event.code`) of keys that should have their event `preventDefault`\n * called. This is used to avoid scrolling in a webpage when these keys are pressed\n * in the game.\n */\n const defaultPreventedKeyCodes = [\n 37, // ArrowLeft\n 38, // ArrowUp\n 39, // ArrowRight\n 40, // ArrowDown\n ];\n\n /**\n * The renderer for a gdjs.RuntimeGame using Pixi.js.\n */\n export class RuntimeGamePixiRenderer {\n _game: gdjs.RuntimeGame;\n _isFullPage: boolean = true;\n\n //Used to track if the canvas is displayed on the full page.\n _isFullscreen: boolean = false;\n\n //Used to track if the window is displayed as fullscreen (see setFullscreen method).\n _forceFullscreen: any;\n\n _pixiRenderer: PIXI.Renderer | null = null;\n private _threeRenderer: THREE.WebGLRenderer | null = null;\n private _gameCanvas: HTMLCanvasElement | null = null;\n private _domElementsContainer: HTMLDivElement | null = null;\n\n // Current width of the canvas (might be scaled down/up compared to renderer)\n _canvasWidth: float = 0;\n // Current height of the canvas (might be scaled down/up compared to renderer)\n _canvasHeight: float = 0;\n\n _keepRatio: boolean = true;\n _marginLeft: any;\n _marginTop: any;\n _marginRight: any;\n _marginBottom: any;\n\n _nextFrameId: integer = 0;\n\n _wasDisposed: boolean = false;\n\n /**\n * @param game The game that is being rendered\n * @param forceFullscreen If fullscreen should be always activated\n */\n constructor(game: gdjs.RuntimeGame, forceFullscreen: boolean) {\n this._game = game;\n this._forceFullscreen = forceFullscreen;\n\n //If set to true, the canvas will always be displayed as fullscreen, even if _isFullscreen == false.\n this._marginLeft =\n this._marginTop =\n this._marginRight =\n this._marginBottom =\n 0;\n this._setupOrientation();\n }\n\n /**\n * Create the canvas on which the game will be rendered, inside the specified DOM element, and\n * setup the rendering of the game.\n * If you want to use your own canvas, use `initializeRenderers` and `initializeCanvas` instead.\n *\n * @param parentElement The parent element to which the canvas will be added.\n */\n createStandardCanvas(parentElement: HTMLElement) {\n this._throwIfDisposed();\n\n const gameCanvas = document.createElement('canvas');\n parentElement.appendChild(gameCanvas);\n\n this.initializeRenderers(gameCanvas);\n this.initializeCanvas(gameCanvas);\n }\n\n /**\n * Set up the rendering of the game for the given canvas.\n *\n * In most cases, you can use `createStandardCanvas` instead to initialize the game.\n */\n initializeRenderers(gameCanvas: HTMLCanvasElement): void {\n this._throwIfDisposed();\n\n if (typeof THREE !== 'undefined') {\n this._threeRenderer = new THREE.WebGLRenderer({\n canvas: gameCanvas,\n antialias:\n this._game.getAntialiasingMode() !== 'none' &&\n (this._game.isAntialisingEnabledOnMobile() ||\n !gdjs.evtTools.common.isMobile()),\n preserveDrawingBuffer: true, // Keep to true to allow screenshots.\n });\n this._threeRenderer.shadowMap.enabled = true;\n this._threeRenderer.shadowMap.type = THREE.PCFSoftShadowMap;\n this._threeRenderer.useLegacyLights = true;\n this._threeRenderer.autoClear = false;\n this._threeRenderer.setSize(\n this._game.getGameResolutionWidth(),\n this._game.getGameResolutionHeight()\n );\n\n // Create a PixiJS renderer that use the same GL context as Three.js\n // so that both can render to the canvas and even have PixiJS rendering\n // reused in Three.js (by using a RenderTexture and the same internal WebGL texture).\n this._pixiRenderer = new PIXI.Renderer({\n width: this._game.getGameResolutionWidth(),\n height: this._game.getGameResolutionHeight(),\n view: gameCanvas,\n // @ts-ignore - reuse the context from Three.js.\n context: this._threeRenderer.getContext(),\n clearBeforeRender: false,\n preserveDrawingBuffer: true, // Keep to true to allow screenshots.\n antialias: false,\n backgroundAlpha: 0,\n // TODO (3D): add a setting for pixel ratio (`resolution: window.devicePixelRatio`)\n });\n } else {\n // Create the renderer and setup the rendering area.\n // \"preserveDrawingBuffer: true\" is needed to avoid flickering\n // and background issues on some mobile phones (see #585 #572 #566 #463).\n this._pixiRenderer = PIXI.autoDetectRenderer({\n width: this._game.getGameResolutionWidth(),\n height: this._game.getGameResolutionHeight(),\n view: gameCanvas,\n preserveDrawingBuffer: true,\n antialias: false,\n }) as PIXI.Renderer;\n }\n\n // Deactivating accessibility support in PixiJS renderer, as we want to be in control of this.\n // See https://github.com/pixijs/pixijs/issues/5111#issuecomment-420047824\n this._pixiRenderer.plugins.accessibility.destroy();\n delete this._pixiRenderer.plugins.accessibility;\n }\n\n /**\n * Set up the game canvas so that it covers the size required by the game\n * and has a container for DOM elements required by the game.\n */\n initializeCanvas(gameCanvas: HTMLCanvasElement): void {\n // Add the renderer view element to the DOM\n this._gameCanvas = gameCanvas;\n\n gameCanvas.style.position = 'absolute';\n\n // Ensure that the canvas has the focus.\n gameCanvas.tabIndex = 1;\n\n // Ensure long press can't create a selection\n gameCanvas.style.userSelect = 'none';\n gameCanvas.style.outline = 'none'; // No selection/focus ring on the canvas.\n\n // Set up the container for HTML elements on top of the game canvas.\n const domElementsContainer = document.createElement('div');\n domElementsContainer.style.position = 'absolute';\n domElementsContainer.style.overflow = 'hidden'; // Never show anything outside the container.\n domElementsContainer.style.outline = 'none'; // No selection/focus ring on this container.\n domElementsContainer.style.pointerEvents = 'none'; // Clicks go through the container.\n\n // The container should *never* scroll.\n // Elements are put inside with the same coordinates (with a scaling factor)\n // as on the game canvas.\n domElementsContainer.addEventListener('scroll', (event) => {\n domElementsContainer.scrollLeft = 0;\n domElementsContainer.scrollTop = 0;\n event.preventDefault();\n });\n\n // When clicking outside an input, (or other HTML element),\n // give back focus to the game canvas so that this element is blurred.\n gameCanvas.addEventListener('pointerdown', () => {\n gameCanvas.focus();\n });\n\n // Prevent magnifying glass on iOS with a long press.\n // Note that there are related bugs on iOS 15 (see https://bugs.webkit.org/show_bug.cgi?id=231161)\n // but it seems not to affect us as the `domElementsContainer` has `pointerEvents` set to `none`.\n domElementsContainer.style['-webkit-user-select'] = 'none';\n\n gameCanvas.parentNode?.appendChild(domElementsContainer);\n this._domElementsContainer = domElementsContainer;\n\n this._resizeCanvas();\n\n // Handle scale mode.\n if (this._game.getScaleMode() === 'nearest') {\n gameCanvas.style['image-rendering'] = '-moz-crisp-edges';\n gameCanvas.style['image-rendering'] = '-webkit-optimize-contrast';\n gameCanvas.style['image-rendering'] = '-webkit-crisp-edges';\n gameCanvas.style['image-rendering'] = 'pixelated';\n }\n\n // Handle pixels rounding.\n if (this._game.getPixelsRounding()) {\n PIXI.settings.ROUND_PIXELS = true;\n }\n\n // Handle resize: immediately adjust the game canvas (and dom element container)\n // and notify the game (that may want to adjust to the new size of the window).\n window.addEventListener('resize', () => {\n this._game.onWindowInnerSizeChanged();\n this._resizeCanvas();\n });\n\n // Focus the canvas when created.\n gameCanvas.focus();\n }\n\n static getWindowInnerWidth() {\n return typeof window !== 'undefined' ? window.innerWidth : 800;\n }\n\n static getWindowInnerHeight() {\n return typeof window !== 'undefined' ? window.innerHeight : 800;\n }\n\n /**\n * Update the game renderer size according to the \"game resolution\".\n * Called when game resolution changes.\n *\n * Note that if the canvas is fullscreen, it won't be resized, but when going back to\n * non fullscreen mode, the requested size will be used.\n */\n updateRendererSize(): void {\n this._resizeCanvas();\n }\n\n /**\n * Set the proper screen orientation from the project properties.\n */\n private _setupOrientation() {\n if (\n typeof window === 'undefined' ||\n !window.screen ||\n !window.screen.orientation\n ) {\n return;\n }\n const gameOrientation = this._game.getGameData().properties.orientation;\n try {\n // We ignore the error as some platforms may not supporting locking (i.e: desktop).\n if (gameOrientation === 'default') {\n const promise = window.screen.orientation.unlock();\n // @ts-ignore\n if (promise) {\n // @ts-ignore\n promise.catch(() => {});\n }\n } else {\n // @ts-ignore\n window.screen.orientation.lock(gameOrientation).catch(() => {});\n }\n } catch (error) {\n logger.error('Unexpected error while setting up orientation: ', error);\n }\n }\n\n /**\n * Resize the renderer (the \"game resolution\") and the canvas (which can be larger\n * or smaller to fill the page, with optional margins).\n *\n */\n private _resizeCanvas() {\n if (!this._pixiRenderer || !this._domElementsContainer) return;\n\n // Set the Pixi (and/or Three) renderer size to the game size.\n // There is no \"smart\" resizing to be done here: the rendering of the game\n // should be done with the size set on the game.\n if (\n this._pixiRenderer.width !== this._game.getGameResolutionWidth() ||\n this._pixiRenderer.height !== this._game.getGameResolutionHeight()\n ) {\n // TODO (3D): It might be useful to resize pixi view in 3D depending on FOV value\n // to enable a mode where pixi always fills the whole screen.\n this._pixiRenderer.resize(\n this._game.getGameResolutionWidth(),\n this._game.getGameResolutionHeight()\n );\n\n if (this._threeRenderer) {\n this._threeRenderer.setSize(\n this._game.getGameResolutionWidth(),\n this._game.getGameResolutionHeight()\n );\n }\n }\n\n // Set the canvas size.\n // Resizing is done according to the settings. This is a \"CSS\" resize\n // only, so won't create visual artifacts during the rendering.\n const isFullPage =\n this._forceFullscreen || this._isFullPage || this._isFullscreen;\n let canvasWidth = this._game.getGameResolutionWidth();\n let canvasHeight = this._game.getGameResolutionHeight();\n let maxWidth = window.innerWidth - this._marginLeft - this._marginRight;\n let maxHeight = window.innerHeight - this._marginTop - this._marginBottom;\n if (maxWidth < 0) {\n maxWidth = 0;\n }\n if (maxHeight < 0) {\n maxHeight = 0;\n }\n if (isFullPage && !this._keepRatio) {\n canvasWidth = maxWidth;\n canvasHeight = maxHeight;\n } else if (\n (isFullPage && this._keepRatio) ||\n canvasWidth > maxWidth ||\n canvasHeight > maxHeight\n ) {\n let factor = maxWidth / canvasWidth;\n if (canvasHeight * factor > maxHeight) {\n factor = maxHeight / canvasHeight;\n }\n canvasWidth *= factor;\n canvasHeight *= factor;\n }\n\n // Apply the calculations to the canvas element...\n if (this._gameCanvas) {\n this._gameCanvas.style.top =\n this._marginTop + (maxHeight - canvasHeight) / 2 + 'px';\n this._gameCanvas.style.left =\n this._marginLeft + (maxWidth - canvasWidth) / 2 + 'px';\n this._gameCanvas.style.width = canvasWidth + 'px';\n this._gameCanvas.style.height = canvasHeight + 'px';\n }\n\n // ...and to the div on top of it showing DOM elements (like inputs).\n this._domElementsContainer.style.top =\n this._marginTop + (maxHeight - canvasHeight) / 2 + 'px';\n this._domElementsContainer.style.left =\n this._marginLeft + (maxWidth - canvasWidth) / 2 + 'px';\n this._domElementsContainer.style.width = canvasWidth + 'px';\n this._domElementsContainer.style.height = canvasHeight + 'px';\n\n // Store the canvas size for fast access to it.\n this._canvasWidth = canvasWidth;\n this._canvasHeight = canvasHeight;\n }\n\n /**\n * Set if the aspect ratio must be kept when the game canvas is resized to fill\n * the page.\n */\n keepAspectRatio(enable) {\n if (this._keepRatio === enable) {\n return;\n }\n this._keepRatio = enable;\n this._resizeCanvas();\n }\n\n /**\n * Change the margin that must be preserved around the game canvas.\n */\n setMargins(top, right, bottom, left): void {\n this._throwIfDisposed();\n if (\n this._marginTop === top &&\n this._marginRight === right &&\n this._marginBottom === bottom &&\n this._marginLeft === left\n ) {\n return;\n }\n this._marginTop = top;\n this._marginRight = right;\n this._marginBottom = bottom;\n this._marginLeft = left;\n this._resizeCanvas();\n }\n\n /**\n * Update the window size, if possible.\n * @param width The new width, in pixels.\n * @param height The new height, in pixels.\n */\n setWindowSize(width: float, height: float): void {\n this._throwIfDisposed();\n const remote = this.getElectronRemote();\n if (remote) {\n const browserWindow = remote.getCurrentWindow();\n try {\n if (browserWindow) {\n browserWindow.setContentSize(width, height);\n }\n } catch (error) {\n logger.error(\n `Window size setting to width ${width} and height ${height} failed. See error:`,\n error\n );\n }\n } else {\n logger.warn(\"Window size can't be changed on this platform.\");\n }\n }\n\n /**\n * Center the window on screen.\n */\n centerWindow() {\n this._throwIfDisposed();\n const remote = this.getElectronRemote();\n if (remote) {\n const browserWindow = remote.getCurrentWindow();\n try {\n if (browserWindow) {\n browserWindow.center();\n }\n } catch (error) {\n logger.error('Window centering failed. See error:', error);\n }\n } else {\n logger.warn(\"Window can't be centered on this platform.\");\n }\n }\n\n /**\n * De/activate fullscreen for the game.\n */\n setFullScreen(enable): void {\n this._throwIfDisposed();\n if (this._forceFullscreen) {\n return;\n }\n if (this._isFullscreen !== enable) {\n this._isFullscreen = !!enable;\n const remote = this.getElectronRemote();\n if (remote) {\n const browserWindow = remote.getCurrentWindow();\n try {\n if (browserWindow) {\n browserWindow.setFullScreen(this._isFullscreen);\n }\n } catch (error) {\n logger.error(\n `Full screen setting to ${this._isFullscreen} failed. See error:`,\n error\n );\n }\n } else {\n // Use HTML5 Fullscreen API\n //TODO: Do this on a user gesture, otherwise most browsers won't activate fullscreen\n if (this._isFullscreen) {\n // @ts-ignore\n if (document.documentElement.requestFullscreen) {\n // @ts-ignore\n document.documentElement.requestFullscreen();\n } else {\n // @ts-ignore\n if (document.documentElement.mozRequestFullScreen) {\n // @ts-ignore\n document.documentElement.mozRequestFullScreen();\n } else {\n // @ts-ignore\n if (document.documentElement.webkitRequestFullScreen) {\n // @ts-ignore\n document.documentElement.webkitRequestFullScreen();\n }\n }\n }\n } else {\n // @ts-ignore\n if (document.exitFullscreen) {\n // @ts-ignore\n document.exitFullscreen();\n } else {\n // @ts-ignore\n if (document.mozCancelFullScreen) {\n // @ts-ignore\n document.mozCancelFullScreen();\n } else {\n // @ts-ignore\n if (document.webkitCancelFullScreen) {\n // @ts-ignore\n document.webkitCancelFullScreen();\n }\n }\n }\n }\n }\n this._resizeCanvas();\n }\n }\n\n /**\n * Checks if the game is in full screen.\n */\n isFullScreen(): boolean {\n const remote = this.getElectronRemote();\n if (remote) {\n try {\n return remote.getCurrentWindow().isFullScreen();\n } catch (error) {\n logger.error(`Full screen detection failed. See error:`, error);\n return false;\n }\n }\n\n // Height check is used to detect user triggered full screen (for example F11 shortcut).\n return this._isFullscreen || window.screen.height === window.innerHeight;\n }\n\n /**\n * Convert a point from the canvas coordinates to the dom element container coordinates.\n *\n * @param canvasCoords The point in the canvas coordinates.\n * @param result The point to return.\n * @returns The point in the dom element container coordinates.\n */\n convertCanvasToDomElementContainerCoords(\n canvasCoords: FloatPoint,\n result: FloatPoint\n ): FloatPoint {\n const pageCoords = result || [0, 0];\n\n // Handle the fact that the game is stretched to fill the canvas.\n pageCoords[0] =\n (canvasCoords[0] * this._canvasWidth) /\n this._game.getGameResolutionWidth();\n pageCoords[1] =\n (canvasCoords[1] * this._canvasHeight) /\n this._game.getGameResolutionHeight();\n\n return pageCoords;\n }\n\n /**\n * Return the scale factor between the renderer height and the actual canvas height,\n * which is also the height of the container for DOM elements to be superimposed on top of it.\n *\n * Useful to scale font sizes of DOM elements so that they follow the size of the game.\n */\n getCanvasToDomElementContainerHeightScale(): float {\n return (this._canvasHeight || 1) / this._game.getGameResolutionHeight();\n }\n\n /**\n * Translate an event position (mouse or touch) made on the canvas\n * on the page (or even outside the canvas) to game coordinates.\n */\n convertPageToGameCoords(pageX: float, pageY: float) {\n const canvas = this._gameCanvas;\n if (!canvas) return [0, 0];\n\n const pos = [pageX - canvas.offsetLeft, pageY - canvas.offsetTop];\n\n // Handle the fact that the game is stretched to fill the canvas.\n pos[0] *= this._game.getGameResolutionWidth() / (this._canvasWidth || 1);\n pos[1] *=\n this._game.getGameResolutionHeight() / (this._canvasHeight || 1);\n return pos;\n }\n\n /**\n * Add the standard events handler.\n *\n * The game canvas must have been initialized before calling this.\n */\n bindStandardEvents(\n manager: gdjs.InputManager,\n window: Window,\n document: Document\n ) {\n this._throwIfDisposed();\n const canvas = this._gameCanvas;\n if (!canvas) return;\n\n const isInsideCanvas = (e: MouseEvent | Touch) => {\n const x = e.pageX - canvas.offsetLeft;\n const y = e.pageY - canvas.offsetTop;\n\n return (\n 0 <= x &&\n x < (this._canvasWidth || 1) &&\n 0 <= y &&\n y < (this._canvasHeight || 1)\n );\n };\n\n // Some browsers lacks definition of some variables used to do calculations\n // in convertPageToGameCoords. They are defined to 0 as they are useless.\n\n (function ensureOffsetsExistence() {\n if (isNaN(canvas.offsetLeft)) {\n // @ts-ignore\n canvas.offsetLeft = 0;\n // @ts-ignore\n canvas.offsetTop = 0;\n }\n if (isNaN(document.body.scrollLeft)) {\n document.body.scrollLeft = 0;\n document.body.scrollTop = 0;\n }\n if (\n document.documentElement === undefined ||\n document.documentElement === null\n ) {\n // @ts-ignore\n document.documentElement = {};\n }\n if (isNaN(document.documentElement.scrollLeft)) {\n document.documentElement.scrollLeft = 0;\n document.documentElement.scrollTop = 0;\n }\n if (isNaN(canvas.offsetLeft)) {\n // @ts-ignore\n canvas.offsetLeft = 0;\n // @ts-ignore\n canvas.offsetTop = 0;\n }\n })();\n\n // Keyboard: listen at the document level to capture even when the canvas\n // is not focused.\n\n const isFocusingDomElement = () => {\n // Fast bailout when the game canvas should receive the inputs (i.e: almost always).\n // Also check the document body or null for activeElement, as all of these should go\n // to the game.\n if (\n document.activeElement === canvas ||\n document.activeElement === document.body ||\n document.activeElement === null\n )\n return false;\n\n return true;\n };\n const isTargetDomElement = (event: TouchEvent) => {\n // Fast bailout when the game canvas should receive the inputs (i.e: almost always).\n // Any event with a target that is not the body or the canvas should\n // not go to the game (<input> or <a> elements for instances).\n if (event.target === canvas || event.target === document.body)\n return false;\n return true;\n };\n document.onkeydown = function (e) {\n if (isFocusingDomElement()) {\n // Bail out if the game canvas is not focused. For example,\n // an `<input>` element can be focused, and needs to receive\n // arrow keys events.\n return;\n }\n\n if (defaultPreventedKeyCodes.includes(e.keyCode)) {\n // Some keys are \"default prevented\" to avoid scrolling when the game\n // is integrated in a page as an iframe.\n e.preventDefault();\n }\n\n manager.onKeyPressed(e.keyCode, e.location);\n };\n document.onkeyup = function (e) {\n if (isFocusingDomElement()) {\n // Bail out if the game canvas is not focused. For example,\n // an `<input>` element can be focused, and needs to receive\n // arrow keys events.\n return;\n }\n\n if (defaultPreventedKeyCodes.includes(e.keyCode)) {\n // Some keys are \"default prevented\" to avoid scrolling when the game\n // is integrated in a page as an iframe.\n e.preventDefault();\n }\n\n manager.onKeyReleased(e.keyCode, e.location);\n };\n\n // Mouse:\n\n // Converts HTML mouse button to InputManager mouse button.\n // This function is used to align HTML button values with GDevelop 3 C++ SFML Mouse button enum values,\n // notably the middle and right buttons.\n function convertHtmlMouseButtonToInputManagerMouseButton(button: number) {\n switch (button) {\n case 1: // Middle button\n return gdjs.InputManager.MOUSE_MIDDLE_BUTTON;\n case 2: // Right button\n return gdjs.InputManager.MOUSE_RIGHT_BUTTON;\n }\n return button;\n }\n canvas.onmousemove = (e) => {\n const pos = this.convertPageToGameCoords(e.pageX, e.pageY);\n manager.onMouseMove(pos[0], pos[1]);\n };\n canvas.onmousedown = (e) => {\n const pos = this.convertPageToGameCoords(e.pageX, e.pageY);\n manager.onMouseMove(pos[0], pos[1]);\n manager.onMouseButtonPressed(\n convertHtmlMouseButtonToInputManagerMouseButton(e.button)\n );\n if (window.focus !== undefined) {\n window.focus();\n }\n return false;\n };\n canvas.onmouseup = function (e) {\n manager.onMouseButtonReleased(\n convertHtmlMouseButtonToInputManagerMouseButton(e.button)\n );\n return false;\n };\n canvas.onmouseleave = function (e) {\n manager.onMouseLeave();\n };\n canvas.onmouseenter = function (e) {\n manager.onMouseEnter();\n // There is no mouse event when the cursor is outside of the canvas.\n // We catchup what happened.\n const buttons = [\n gdjs.InputManager.MOUSE_LEFT_BUTTON,\n gdjs.InputManager.MOUSE_RIGHT_BUTTON,\n gdjs.InputManager.MOUSE_MIDDLE_BUTTON,\n gdjs.InputManager.MOUSE_BACK_BUTTON,\n gdjs.InputManager.MOUSE_FORWARD_BUTTON,\n ];\n for (let i = 0, len = buttons.length; i < len; ++i) {\n const button = buttons[i];\n const buttonIsPressed = (e.buttons & (1 << i)) !== 0;\n const buttonWasPressed = manager.isMouseButtonPressed(button);\n if (buttonIsPressed && !buttonWasPressed) {\n manager.onMouseButtonPressed(button);\n } else if (!buttonIsPressed && buttonWasPressed) {\n manager.onMouseButtonReleased(button);\n }\n }\n };\n window.addEventListener(\n 'click',\n function (e) {\n if (window.focus !== undefined) {\n window.focus();\n }\n return false;\n },\n false\n );\n canvas.oncontextmenu = function (event) {\n event.preventDefault();\n event.stopPropagation();\n return false;\n };\n // @ts-ignore\n canvas.onwheel = function (event) {\n manager.onMouseWheel(-event.deltaY);\n };\n\n // Touches:\n window.addEventListener(\n 'touchmove',\n (e) => {\n if (isTargetDomElement(e)) {\n // Bail out if the game canvas is not focused. For example,\n // an `<input>` element can be focused, and needs to receive\n // touch events to move the selection (and do other native gestures).\n return;\n }\n\n e.preventDefault();\n if (e.changedTouches) {\n for (let i = 0; i < e.changedTouches.length; ++i) {\n const touch = e.changedTouches[i];\n const pos = this.convertPageToGameCoords(\n touch.pageX,\n touch.pageY\n );\n manager.onTouchMove(touch.identifier, pos[0], pos[1]);\n // This works because touch events are sent\n // when they continue outside of the canvas.\n if (manager.isSimulatingMouseWithTouch()) {\n if (isInsideCanvas(touch)) {\n manager.onMouseEnter();\n } else {\n manager.onMouseLeave();\n }\n }\n }\n }\n },\n // This is important so that we can use e.preventDefault() and block possible following mouse events.\n { passive: false }\n );\n window.addEventListener(\n 'touchstart',\n (e) => {\n if (isTargetDomElement(e)) {\n // Bail out if the game canvas is not focused. For example,\n // an `<input>` element can be focused, and needs to receive\n // touch events to move the selection (and do other native gestures).\n return;\n }\n\n e.preventDefault();\n if (e.changedTouches) {\n for (let i = 0; i < e.changedTouches.length; ++i) {\n const touch = e.changedTouches[i];\n const pos = this.convertPageToGameCoords(\n touch.pageX,\n touch.pageY\n );\n manager.onTouchStart(\n e.changedTouches[i].identifier,\n pos[0],\n pos[1]\n );\n }\n }\n return false;\n },\n // This is important so that we can use e.preventDefault() and block possible following mouse events.\n { passive: false }\n );\n window.addEventListener(\n 'touchend',\n function (e) {\n if (isTargetDomElement(e)) {\n // Bail out if the game canvas is not focused. For example,\n // an `<input>` element can be focused, and needs to receive\n // touch events to move the selection (and do other native gestures).\n return;\n }\n\n e.preventDefault();\n if (e.changedTouches) {\n for (let i = 0; i < e.changedTouches.length; ++i) {\n manager.onTouchEnd(e.changedTouches[i].identifier);\n }\n }\n return false;\n },\n // This is important so that we can use e.preventDefault() and block possible following mouse events.\n { passive: false }\n );\n window.addEventListener(\n 'touchcancel',\n function (e) {\n if (isTargetDomElement(e)) {\n // Bail out if the game canvas is not focused. For example,\n // an `<input>` element can be focused, and needs to receive\n // touch events to move the selection (and do other native gestures).\n return;\n }\n\n e.preventDefault();\n if (e.changedTouches) {\n for (let i = 0; i < e.changedTouches.length; ++i) {\n manager.onTouchCancel(e.changedTouches[i].identifier);\n }\n }\n return false;\n },\n // This is important so that we can use e.preventDefault() and block possible following mouse events.\n { passive: false }\n );\n }\n\n setWindowTitle(title): void {\n if (typeof document !== 'undefined') {\n document.title = title;\n }\n }\n\n getWindowTitle() {\n return typeof document !== 'undefined' ? document.title : '';\n }\n\n startGameLoop(fn) {\n this._throwIfDisposed();\n let oldTime = 0;\n const gameLoop = (time: float) => {\n // Schedule the next frame now to be sure it's called as soon\n // as possible after this one is finished.\n this._nextFrameId = requestAnimationFrame(gameLoop);\n\n const dt = oldTime ? time - oldTime : 0;\n oldTime = time;\n if (!fn(dt)) {\n // Stop the game loop if requested.\n cancelAnimationFrame(this._nextFrameId);\n }\n };\n\n requestAnimationFrame(gameLoop);\n }\n\n stopGameLoop(): void {\n cancelAnimationFrame(this._nextFrameId);\n }\n\n getPIXIRenderer() {\n return this._pixiRenderer;\n }\n\n /**\n * Get the Three.js renderer for the game - if any.\n */\n getThreeRenderer(): THREE.WebGLRenderer | null {\n return this._threeRenderer;\n }\n\n /**\n * Get the DOM element used as a container for HTML elements to display\n * on top of the game.\n */\n getDomElementContainer() {\n return this._domElementsContainer;\n }\n\n /**\n * Open the given URL in the system browser (or a new tab)\n */\n openURL(url: string) {\n // Try to detect the environment to use the most adapted\n // way of opening an URL.\n\n if (typeof window !== 'undefined') {\n const electron = this.getElectron();\n if (electron) {\n electron.shell.openExternal(url);\n } else if (\n // @ts-ignore\n typeof window.cordova !== 'undefined' &&\n // @ts-ignore\n typeof window.cordova.InAppBrowser !== 'undefined'\n ) {\n // @ts-ignore\n window.cordova.InAppBrowser.open(url, '_system', 'location=yes');\n } else {\n window.open(url, '_blank');\n }\n }\n }\n\n /**\n * Close the game, if applicable.\n */\n stopGame() {\n // Try to detect the environment to use the most adapted\n // way of closing the app\n const remote = this.getElectronRemote();\n if (remote) {\n const browserWindow = remote.getCurrentWindow();\n if (browserWindow) {\n try {\n browserWindow.close();\n } catch (error) {\n logger.error('Window closing failed. See error:', error);\n }\n }\n } else {\n if (\n typeof navigator !== 'undefined' &&\n // @ts-ignore\n navigator.app &&\n // @ts-ignore\n navigator.app.exitApp\n ) {\n // @ts-ignore\n navigator.app.exitApp();\n }\n }\n // HTML5 games on mobile/browsers don't have a way to close their window/page.\n }\n\n /**\n * Dispose the renderers (PixiJS and/or Three.js) as well as DOM elements\n * used for the game (the canvas, if specified, and the additional DOM container\n * created on top of it to allow display HTML elements, for example for text inputs).\n *\n * @param removeCanvas If true, the canvas will be removed from the DOM.\n */\n dispose(removeCanvas?: boolean) {\n this._pixiRenderer?.destroy();\n this._threeRenderer?.dispose();\n this._pixiRenderer = null;\n this._threeRenderer = null;\n\n if (removeCanvas && this._gameCanvas) {\n this._gameCanvas.parentNode?.removeChild(this._gameCanvas);\n }\n\n this._gameCanvas = null;\n this._domElementsContainer?.parentNode?.removeChild(\n this._domElementsContainer\n );\n this._domElementsContainer = null;\n this._wasDisposed = true;\n }\n\n /**\n * Get the canvas DOM element.\n */\n getCanvas(): HTMLCanvasElement | null {\n return this._gameCanvas;\n }\n\n /**\n * Check if the device supports WebGL.\n * @returns true if WebGL is supported\n */\n isWebGLSupported(): boolean {\n return (\n !!this._pixiRenderer &&\n this._pixiRenderer.type === PIXI.RENDERER_TYPE.WEBGL\n );\n }\n\n /**\n * Get the electron module, if running as a electron renderer process.\n */\n getElectron() {\n if (typeof require === 'function') {\n return require('electron');\n }\n return null;\n }\n\n /**\n * Helper to get the electron remote module, if running on Electron.\n * Note that is not guaranteed to be supported in the future - avoid if possible.\n */\n getElectronRemote = () => {\n if (typeof require === 'function') {\n const runtimeGameOptions = this._game.getAdditionalOptions();\n const moduleId =\n runtimeGameOptions && runtimeGameOptions.electronRemoteRequirePath\n ? runtimeGameOptions.electronRemoteRequirePath\n : '@electron/remote';\n\n try {\n return require(moduleId);\n } catch (requireError) {\n console.error(\n `Could not load @electron/remote from \"${moduleId}\". Error is:`,\n requireError\n );\n }\n }\n\n return null;\n };\n\n getGame() {\n return this._game;\n }\n\n private _throwIfDisposed(): void {\n if (this._wasDisposed) {\n throw 'The RuntimeGameRenderer has been disposed and should not be used anymore.';\n }\n }\n }\n\n //Register the class to let the engine use it.\n export type RuntimeGameRenderer = RuntimeGamePixiRenderer;\n export const RuntimeGameRenderer = RuntimeGamePixiRenderer;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,2 +1,2 @@
1
- var gdjs;(function(n){const g=new n.Logger("Game manager"),c=u=>new Promise(e=>setTimeout(e,u)),h=u=>u.usedResources.map(e=>e.name);let l=null;const p=()=>{if(l)return l;l=[];try{new CompressionStream("gzip"),l.push("cs:gzip")}catch{}try{new CompressionStream("deflate"),l.push("cs:deflate")}catch{}return l};class _{constructor(e,t){this._sceneAndExtensionsData=[];this._notifyScenesForGameResolutionResize=!1;this._paused=!1;this._hasJustResumed=!1;this._sessionMetricsInitialized=!1;this._disableMetrics=!1;this._wasDisposed=!1;this.getPlatformInfo=()=>({isCordova:!!window.cordova,devicePlatform:typeof device!="undefined"&&device.platform||"",navigatorPlatform:typeof navigator!="undefined"?navigator.platform:"",hasTouch:typeof navigator!="undefined"?!!navigator.maxTouchPoints&&navigator.maxTouchPoints>2:!1,supportedCompressionMethods:p()});this._options=t||{},this._variables=new n.VariablesContainer(e.variables),this._variablesByExtensionName=new Map;for(const s of e.eventsFunctionsExtensions)s.globalVariables.length>0&&this._variablesByExtensionName.set(s.name,new n.VariablesContainer(s.globalVariables));this._eventsBasedObjectDatas=new Map,this._data=e,this._updateSceneAndExtensionsData(),this._resourcesLoader=new n.ResourceLoader(this,e.resources.resources,h(e),e.layouts),this._effectsManager=new n.EffectsManager,this._maxFPS=this._data.properties.maxFPS,this._minFPS=this._data.properties.minFPS,this._gameResolutionWidth=this._data.properties.windowWidth,this._gameResolutionHeight=this._data.properties.windowHeight,this._originalWidth=this._gameResolutionWidth,this._originalHeight=this._gameResolutionHeight,this._resizeMode=this._data.properties.sizeOnStartupMode,this._adaptGameResolutionAtRuntime=this._data.properties.adaptGameResolutionAtRuntime,this._scaleMode=e.properties.scaleMode||"linear",this._pixelsRounding=this._data.properties.pixelsRounding,this._antialiasingMode=this._data.properties.antialiasingMode,this._isAntialisingEnabledOnMobile=this._data.properties.antialisingEnabledOnMobile,this._renderer=new n.RuntimeGameRenderer(this,this._options.forceFullscreen||!1),this._watermark=new n.watermark.RuntimeWatermark(this,e.properties.authorUsernames,this._data.properties.watermark),this._sceneStack=new n.SceneStack(this),this._inputManager=new n.InputManager,this._injectExternalLayout=this._options.injectExternalLayout||"",this._debuggerClient=n.DebuggerClient?new n.DebuggerClient(this):null,this._captureManager=n.CaptureManager?new n.CaptureManager(this._renderer,this._options.captureOptions||{}):null,this._isPreview=this._options.isPreview||!1,this._sessionId=null,this._playerId=null,this._embeddedResourcesMappings=new Map;for(const s of this._data.resources.resources)if(s.metadata)try{const i=JSON.parse(s.metadata);i?.embeddedResourcesMapping&&this._embeddedResourcesMappings.set(s.name,i.embeddedResourcesMapping)}catch{g.error("Some metadata of resources can not be successfully parsed.")}this.isUsingGDevelopDevelopmentEnvironment()&&g.info("This game will run on the development version of GDevelop APIs.")}setProjectData(e){this._data=e,this._updateSceneAndExtensionsData(),this._resourcesLoader.setResources(e.resources.resources,h(e),e.layouts)}_updateSceneAndExtensionsData(){const e=this._data.eventsFunctionsExtensions.filter(t=>t.sceneVariables.length>0);if(this._sceneAndExtensionsData=this._data.layouts.map(t=>({sceneData:t,usedExtensionsWithVariablesData:e})),this._eventsBasedObjectDatas.clear(),this._data.eventsFunctionsExtensions)for(const t of this._data.eventsFunctionsExtensions)for(const s of t.eventsBasedObjects)this._eventsBasedObjectDatas.set(t.name+"::"+s.name,s)}getAdditionalOptions(){return this._options}getRenderer(){return this._renderer}getVariables(){return this._variables}getVariablesForExtension(e){return this._variablesByExtensionName.get(e)||null}getSoundManager(){return this._resourcesLoader.getSoundManager()}getImageManager(){return this._resourcesLoader.getImageManager()}getFontManager(){return this._resourcesLoader.getFontManager()}getBitmapFontManager(){return this._resourcesLoader.getBitmapFontManager()}getJsonManager(){return this._resourcesLoader.getJsonManager()}getModel3DManager(){return this._resourcesLoader.getModel3DManager()}getSpineManager(){return this._resourcesLoader.getSpineManager()}getSpineAtlasManager(){return this._resourcesLoader.getSpineAtlasManager()}getInputManager(){return this._inputManager}getEffectsManager(){return this._effectsManager}getGameData(){return this._data}getEventsBasedObjectData(e){const t=this._eventsBasedObjectDatas.get(e);return t||(g.error('The game has no events-based object of the type "'+e+'"'),null)}getSceneAndExtensionsData(e){for(let t=0,s=this._sceneAndExtensionsData.length;t<s;++t){const i=this._sceneAndExtensionsData[t];if(e===void 0||i.sceneData.name===e)return i}return g.error('The game has no scene called "'+e+'"'),null}hasScene(e){for(let t=0,s=this._data.layouts.length;t<s;++t){const i=this._data.layouts[t];if(e===void 0||i.name==e)return!0}return!1}getExternalLayoutData(e){let t=null;for(let s=0,i=this._data.externalLayouts.length;s<i;++s){const r=this._data.externalLayouts[s];if(r.name===e){t=r;break}}return t}getInitialObjectsData(){return this._data.objects||[]}getOriginalWidth(){return this._originalWidth}getOriginalHeight(){return this._originalHeight}getGameResolutionWidth(){return this._gameResolutionWidth}getGameResolutionHeight(){return this._gameResolutionHeight}setGameResolutionSize(e,t){if(this._throwIfDisposed(),this._gameResolutionWidth=e,this._gameResolutionHeight=t,this._adaptGameResolutionAtRuntime&&n.RuntimeGameRenderer&&n.RuntimeGameRenderer.getWindowInnerWidth&&n.RuntimeGameRenderer.getWindowInnerHeight){const s=n.RuntimeGameRenderer.getWindowInnerWidth(),i=n.RuntimeGameRenderer.getWindowInnerHeight();if(this._resizeMode==="adaptWidth")this._gameResolutionWidth=this._gameResolutionHeight*s/i;else if(this._resizeMode==="adaptHeight")this._gameResolutionHeight=this._gameResolutionWidth*i/s;else if(this._resizeMode==="scaleOuter"){const r=s/this._originalWidth,o=i/this._originalHeight;r<o?(this._gameResolutionWidth=this._originalWidth,this._gameResolutionHeight=Math.floor(i/r)):(this._gameResolutionWidth=Math.floor(s/o),this._gameResolutionHeight=this._originalHeight)}}this._renderer.updateRendererSize(),this._notifyScenesForGameResolutionResize=!0}setGameResolutionResizeMode(e){this._resizeMode=e,this._forceGameResolutionUpdate()}getGameResolutionResizeMode(){return this._resizeMode}setAdaptGameResolutionAtRuntime(e){this._adaptGameResolutionAtRuntime=e,this._forceGameResolutionUpdate()}getAdaptGameResolutionAtRuntime(){return this._adaptGameResolutionAtRuntime}getMinimalFramerate(){return this._minFPS}getScaleMode(){return this._scaleMode}getPixelsRounding(){return this._pixelsRounding}getAntialiasingMode(){return this._antialiasingMode}isAntialisingEnabledOnMobile(){return this._isAntialisingEnabledOnMobile}pause(e){this._paused!==e&&(this._paused=e,this._debuggerClient&&(this._paused?this._debuggerClient.sendGamePaused():this._debuggerClient.sendGameResumed()))}hasJustResumed(){return this._hasJustResumed}prioritizeLoadingOfScene(e){this._resourcesLoader.loadSceneResources(e)}getSceneLoadingProgress(e){return this._resourcesLoader.getSceneLoadingProgress(e)}areSceneAssetsLoaded(e){return this._resourcesLoader.areSceneAssetsLoaded(e)}areSceneAssetsReady(e){return this._resourcesLoader.areSceneAssetsReady(e)}loadAllAssets(e,t){this._throwIfDisposed(),this.loadFirstAssetsAndStartBackgroundLoading(this._getFirstSceneName(),t).then(e)}async loadFirstAssetsAndStartBackgroundLoading(e,t){try{const s=this._data.properties.loadingScreen.backgroundImageResourceName;s&&await this._resourcesLoader.getImageManager().loadResource(s),await Promise.all([this._loadAssetsWithLoadingScreen(!0,async i=>{await this._resourcesLoader.loadGlobalAndFirstSceneResources(e,i),this._resourcesLoader.loadAllSceneInBackground()},t),n.getAllAsynchronouslyLoadingLibraryPromise()])}catch(s){throw this._debuggerClient&&this._debuggerClient.onUncaughtException(s),s}}async loadSceneAssets(e,t){await this._loadAssetsWithLoadingScreen(!1,async s=>{await this._resourcesLoader.loadAndProcessSceneResources(e,s)},t)}async _loadAssetsWithLoadingScreen(e,t,s){this.pause(!0);const i=new n.LoadingScreenRenderer(this.getRenderer(),this._resourcesLoader.getImageManager(),this._data.properties.loadingScreen,this._data.properties.watermark.showWatermark,e);await t(async(o,a)=>{const d=Math.floor(100*o/a);i.setPercent(d),s&&s(d),i.renderIfNeeded()&&await c(1)}),await i.unload(),this.pause(!1)}_getFirstSceneName(){const e=this._data.firstLayout;return this.hasScene(e)?e:this.getSceneAndExtensionsData().sceneData.name}startGameLoop(){this._throwIfDisposed();try{if(!this.hasScene()){g.error("The game has no scene.");return}this._forceGameResolutionUpdate(),this._sceneStack.push(this._getFirstSceneName(),this._injectExternalLayout),this._watermark.displayAtStartup(),this._setupGameVisibilityEvents(),n.inAppTutorialMessage&&n.inAppTutorialMessage.displayInAppTutorialMessage(this,this._options.inAppTutorialMessageInPreview,this._options.inAppTutorialMessagePositionInPreview||"");let e=0;this._hasJustResumed=!1,this._renderer.startGameLoop(t=>{try{if(this._paused||(e+=t,this._maxFPS>0&&1e3/e>this._maxFPS+7))return!0;const s=e;return e=0,this._notifyScenesForGameResolutionResize&&(this._sceneStack.onGameResolutionResized(),this._notifyScenesForGameResolutionResize=!1),this._sceneStack.step(s)?(this.getInputManager().onFrameEnded(),this._hasJustResumed=!1,!0):!1}catch(s){throw this._debuggerClient&&this._debuggerClient.onUncaughtException(s),s}}),setTimeout(()=>{this._setupSessionMetrics()},4e3),this._captureManager&&this._captureManager.setupCaptureOptions(this._isPreview)}catch(e){throw this._debuggerClient&&this._debuggerClient.onUncaughtException(e),e}}dispose(e){this._renderer.stopGameLoop(),this._sceneStack.dispose(),this._renderer.dispose(e),this._resourcesLoader.dispose(),this._wasDisposed=!0}enableMetrics(e){this._disableMetrics=!e,e&&this._setupSessionMetrics()}_setupGameVisibilityEvents(){typeof navigator!="undefined"&&typeof document!="undefined"&&(document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&(this._hasJustResumed=!0)}),window.addEventListener("resume",()=>{this._hasJustResumed=!0},!1))}_setupSessionMetrics(){if(this._sessionMetricsInitialized||this._disableMetrics||this.isPreview()||typeof fetch=="undefined"||!this._data.properties.projectUuid)return;const e="https://api.gdevelop-app.com/analytics";this._playerId=this._makePlayerUuid();let t=0,s=0,i=Date.now();const r=this.getPlatformInfo();fetch(e+"/session",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({gameId:this._data.properties.projectUuid,playerId:this._playerId,game:{name:this._data.properties.name||"",packageName:this._data.properties.packageName||"",version:this._data.properties.version||"",location:window.location.href},platform:{isCordova:r.isCordova,devicePlatform:r.devicePlatform,navigatorPlatform:r.navigatorPlatform,hasTouch:r.hasTouch}})}).then(a=>{if(!a.ok)throw console.error("Error while creating the session",a),new Error("Error while creating the session");return a}).then(a=>a.text()).then(a=>{this._sessionId=a}).catch(()=>{});const o=()=>{if(!this._sessionId)return;const a=Date.now();if(s+=a-i,i=a,s<5*1e3)return;const d=Math.floor(s/1e3)*1e3;t+=d,s-=d,navigator.sendBeacon(e+"/session-hit",JSON.stringify({gameId:this._data.properties.projectUuid,playerId:this._playerId,sessionId:this._sessionId,duration:Math.floor(t/1e3)}))};if(typeof navigator!="undefined"&&typeof document!="undefined"){document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"?i=Date.now():o()}),window.addEventListener("pagehide",o,!1),window.addEventListener("pause",o,!1),window.addEventListener("resume",()=>{i=Date.now()},!1);const a=typeof safari=="object"&&safari.pushNotification,d=/electron/i.test(navigator.userAgent);(a||d)&&window.addEventListener("beforeunload",()=>{o()})}this._sessionMetricsInitialized=!0,this._sessionId=this._sessionId}_makePlayerUuid(){try{const e="GDJS-internal-player-uuid",t=localStorage.getItem(e);if(t)return t;const s=n.makeUuid();return localStorage.setItem(e,s),s}catch{return n.makeUuid()}}getSessionId(){return this._sessionId}getPlayerId(){return this._playerId}onWindowInnerSizeChanged(){this._forceGameResolutionUpdate()}_forceGameResolutionUpdate(){this.setGameResolutionSize(this._gameResolutionWidth,this._gameResolutionHeight)}startCurrentSceneProfiler(e){this._throwIfDisposed();const t=this._sceneStack.getCurrentScene();return t?(t.startProfiler(e),!0):!1}stopCurrentSceneProfiler(){this._throwIfDisposed();const e=this._sceneStack.getCurrentScene();!e||e.stopProfiler()}wasFirstSceneLoaded(){return this._sceneStack.wasFirstSceneLoaded()}getSceneStack(){return this._sceneStack}isPreview(){return this._isPreview}isUsingGDevelopDevelopmentEnvironment(){return this._options.environment==="dev"}getExtensionProperty(e,t){for(let s of this._data.properties.extensionProperties)if(s.extension===e&&s.property===t)return s.value;return null}resolveEmbeddedResource(e,t){const s=this._embeddedResourcesMappings.get(e);return s&&s[t]?s[t]:t}getEmbeddedResourcesNames(e){return this._embeddedResourcesMappings.has(e)?Object.keys(this._embeddedResourcesMappings.get(e)):[]}getNetworkSyncData(e){const t={var:this._variables.getNetworkSyncData(e),ss:this._sceneStack.getNetworkSyncData(e)||void 0},s={};return this._variablesByExtensionName.forEach((i,r)=>{const o=i.getNetworkSyncData(e);o.length&&(s[r]=o)}),t.extVar=s,(!t.var||t.var.length===0)&&!t.ss&&(!t.extVar||Object.keys(t.extVar).length===0)?null:t}updateFromNetworkSyncData(e){if(this._throwIfDisposed(),e.var&&this._variables.updateFromNetworkSyncData(e.var),e.ss&&this._sceneStack.updateFromNetworkSyncData(e.ss),e.extVar)for(const t in e.extVar){if(!e.extVar.hasOwnProperty(t))continue;const s=e.extVar[t],i=this.getVariablesForExtension(t);i&&i.updateFromNetworkSyncData(s)}}_throwIfDisposed(){if(this._wasDisposed)throw"The RuntimeGame has been disposed and should not be used anymore."}}n.RuntimeGame=_})(gdjs||(gdjs={}));
1
+ var gdjs;(function(n){const g=new n.Logger("Game manager"),c=u=>new Promise(e=>setTimeout(e,u)),h=u=>u.usedResources.map(e=>e.name);let l=null;const p=()=>{if(l)return l;l=[];try{new CompressionStream("gzip"),l.push("cs:gzip")}catch{}try{new CompressionStream("deflate"),l.push("cs:deflate")}catch{}return l};class _{constructor(e,t){this._sceneAndExtensionsData=[];this._notifyScenesForGameResolutionResize=!1;this._paused=!1;this._hasJustResumed=!1;this._sessionMetricsInitialized=!1;this._disableMetrics=!1;this._wasDisposed=!1;this.getPlatformInfo=()=>({isCordova:!!window.cordova,devicePlatform:typeof device!="undefined"&&device.platform||"",navigatorPlatform:typeof navigator!="undefined"?navigator.platform:"",hasTouch:typeof navigator!="undefined"?!!navigator.maxTouchPoints&&navigator.maxTouchPoints>2:!1,supportedCompressionMethods:p()});this._options=t||{},this._variables=new n.VariablesContainer(e.variables),this._variablesByExtensionName=new Map;for(const s of e.eventsFunctionsExtensions)s.globalVariables.length>0&&this._variablesByExtensionName.set(s.name,new n.VariablesContainer(s.globalVariables));this._eventsBasedObjectDatas=new Map,this._data=e,this._updateSceneAndExtensionsData(),this._sceneResourcesPreloading=this._data.properties.sceneResourcesPreloading||"at-startup",this._sceneResourcesUnloading=this._data.properties.sceneResourcesUnloading||"never",this._resourcesLoader=new n.ResourceLoader(this,e.resources.resources,h(e),e.layouts),this._effectsManager=new n.EffectsManager,this._maxFPS=this._data.properties.maxFPS,this._minFPS=this._data.properties.minFPS,this._gameResolutionWidth=this._data.properties.windowWidth,this._gameResolutionHeight=this._data.properties.windowHeight,this._originalWidth=this._gameResolutionWidth,this._originalHeight=this._gameResolutionHeight,this._resizeMode=this._data.properties.sizeOnStartupMode,this._adaptGameResolutionAtRuntime=this._data.properties.adaptGameResolutionAtRuntime,this._scaleMode=e.properties.scaleMode||"linear",this._pixelsRounding=this._data.properties.pixelsRounding,this._antialiasingMode=this._data.properties.antialiasingMode,this._isAntialisingEnabledOnMobile=this._data.properties.antialisingEnabledOnMobile,this._renderer=new n.RuntimeGameRenderer(this,this._options.forceFullscreen||!1),this._watermark=new n.watermark.RuntimeWatermark(this,e.properties.authorUsernames,this._data.properties.watermark),this._sceneStack=new n.SceneStack(this),this._inputManager=new n.InputManager,this._injectExternalLayout=this._options.injectExternalLayout||"",this._debuggerClient=n.DebuggerClient?new n.DebuggerClient(this):null,this._captureManager=n.CaptureManager?new n.CaptureManager(this._renderer,this._options.captureOptions||{}):null,this._isPreview=this._options.isPreview||!1,this._sessionId=null,this._playerId=null,this._embeddedResourcesMappings=new Map;for(const s of this._data.resources.resources)if(s.metadata)try{const i=JSON.parse(s.metadata);i?.embeddedResourcesMapping&&this._embeddedResourcesMappings.set(s.name,i.embeddedResourcesMapping)}catch{g.error("Some metadata of resources can not be successfully parsed.")}this.isUsingGDevelopDevelopmentEnvironment()&&g.info("This game will run on the development version of GDevelop APIs.")}setProjectData(e){this._data=e,this._updateSceneAndExtensionsData(),this._resourcesLoader.setResources(e.resources.resources,h(e),e.layouts)}_updateSceneAndExtensionsData(){const e=this._data.eventsFunctionsExtensions.filter(t=>t.sceneVariables.length>0);if(this._sceneAndExtensionsData=this._data.layouts.map(t=>({sceneData:t,usedExtensionsWithVariablesData:e})),this._eventsBasedObjectDatas.clear(),this._data.eventsFunctionsExtensions)for(const t of this._data.eventsFunctionsExtensions)for(const s of t.eventsBasedObjects)this._eventsBasedObjectDatas.set(t.name+"::"+s.name,s)}getAdditionalOptions(){return this._options}getRenderer(){return this._renderer}getVariables(){return this._variables}getVariablesForExtension(e){return this._variablesByExtensionName.get(e)||null}getResourceLoader(){return this._resourcesLoader}getSoundManager(){return this._resourcesLoader.getSoundManager()}getImageManager(){return this._resourcesLoader.getImageManager()}getFontManager(){return this._resourcesLoader.getFontManager()}getBitmapFontManager(){return this._resourcesLoader.getBitmapFontManager()}getJsonManager(){return this._resourcesLoader.getJsonManager()}getModel3DManager(){return this._resourcesLoader.getModel3DManager()}getSpineManager(){return this._resourcesLoader.getSpineManager()}getSpineAtlasManager(){return this._resourcesLoader.getSpineAtlasManager()}getInputManager(){return this._inputManager}getEffectsManager(){return this._effectsManager}getGameData(){return this._data}getEventsBasedObjectData(e){const t=this._eventsBasedObjectDatas.get(e);return t||(g.error('The game has no events-based object of the type "'+e+'"'),null)}getSceneAndExtensionsData(e){for(let t=0,s=this._sceneAndExtensionsData.length;t<s;++t){const i=this._sceneAndExtensionsData[t];if(e===void 0||i.sceneData.name===e)return i}return g.error('The game has no scene called "'+e+'"'),null}hasScene(e){for(let t=0,s=this._data.layouts.length;t<s;++t){const i=this._data.layouts[t];if(e===void 0||i.name==e)return!0}return!1}getExternalLayoutData(e){let t=null;for(let s=0,i=this._data.externalLayouts.length;s<i;++s){const r=this._data.externalLayouts[s];if(r.name===e){t=r;break}}return t}getInitialObjectsData(){return this._data.objects||[]}getOriginalWidth(){return this._originalWidth}getOriginalHeight(){return this._originalHeight}getGameResolutionWidth(){return this._gameResolutionWidth}getGameResolutionHeight(){return this._gameResolutionHeight}setGameResolutionSize(e,t){if(this._throwIfDisposed(),this._gameResolutionWidth=e,this._gameResolutionHeight=t,this._adaptGameResolutionAtRuntime&&n.RuntimeGameRenderer&&n.RuntimeGameRenderer.getWindowInnerWidth&&n.RuntimeGameRenderer.getWindowInnerHeight){const s=n.RuntimeGameRenderer.getWindowInnerWidth(),i=n.RuntimeGameRenderer.getWindowInnerHeight();if(this._resizeMode==="adaptWidth")this._gameResolutionWidth=this._gameResolutionHeight*s/i;else if(this._resizeMode==="adaptHeight")this._gameResolutionHeight=this._gameResolutionWidth*i/s;else if(this._resizeMode==="scaleOuter"){const r=s/this._originalWidth,o=i/this._originalHeight;r<o?(this._gameResolutionWidth=this._originalWidth,this._gameResolutionHeight=Math.floor(i/r)):(this._gameResolutionWidth=Math.floor(s/o),this._gameResolutionHeight=this._originalHeight)}}this._renderer.updateRendererSize(),this._notifyScenesForGameResolutionResize=!0}setGameResolutionResizeMode(e){this._resizeMode=e,this._forceGameResolutionUpdate()}getGameResolutionResizeMode(){return this._resizeMode}setAdaptGameResolutionAtRuntime(e){this._adaptGameResolutionAtRuntime=e,this._forceGameResolutionUpdate()}getAdaptGameResolutionAtRuntime(){return this._adaptGameResolutionAtRuntime}getMinimalFramerate(){return this._minFPS}getScaleMode(){return this._scaleMode}getPixelsRounding(){return this._pixelsRounding}getAntialiasingMode(){return this._antialiasingMode}isAntialisingEnabledOnMobile(){return this._isAntialisingEnabledOnMobile}pause(e){this._paused!==e&&(this._paused=e,this._debuggerClient&&(this._paused?this._debuggerClient.sendGamePaused():this._debuggerClient.sendGameResumed()))}hasJustResumed(){return this._hasJustResumed}prioritizeLoadingOfScene(e){this._resourcesLoader.loadSceneResources(e)}getSceneLoadingProgress(e){return this._resourcesLoader.getSceneLoadingProgress(e)}areSceneAssetsLoaded(e){return this._resourcesLoader.areSceneAssetsLoaded(e)}areSceneAssetsReady(e){return this._resourcesLoader.areSceneAssetsReady(e)}getSceneResourcesPreloading(){return this._sceneResourcesPreloading}getSceneResourcesUnloading(){return this._sceneResourcesUnloading}loadAllAssets(e,t){this._throwIfDisposed(),this.loadFirstAssetsAndStartBackgroundLoading(this._getFirstSceneName(),t).then(e)}async loadFirstAssetsAndStartBackgroundLoading(e,t){try{const s=this._data.properties.loadingScreen.backgroundImageResourceName;s&&await this._resourcesLoader.getImageManager().loadResource(s),await Promise.all([this._loadAssetsWithLoadingScreen(!0,async i=>{await this._resourcesLoader.loadGlobalAndFirstSceneResources(e,i),this._resourcesLoader.loadAllSceneInBackground()},t),n.getAllAsynchronouslyLoadingLibraryPromise()])}catch(s){throw this._debuggerClient&&this._debuggerClient.onUncaughtException(s),s}}async loadSceneAssets(e,t){await this._loadAssetsWithLoadingScreen(!1,async s=>{await this._resourcesLoader.loadAndProcessSceneResources(e,s)},t)}async _loadAssetsWithLoadingScreen(e,t,s){this.pause(!0);const i=new n.LoadingScreenRenderer(this.getRenderer(),this._resourcesLoader.getImageManager(),this._data.properties.loadingScreen,this._data.properties.watermark.showWatermark,e);await t(async(o,a)=>{const d=Math.floor(100*o/a);i.setPercent(d),s&&s(d),i.renderIfNeeded()&&await c(1)}),await i.unload(),this.pause(!1)}_getFirstSceneName(){const e=this._data.firstLayout;return this.hasScene(e)?e:this.getSceneAndExtensionsData().sceneData.name}startGameLoop(){this._throwIfDisposed();try{if(!this.hasScene()){g.error("The game has no scene.");return}this._forceGameResolutionUpdate(),this._sceneStack.push(this._getFirstSceneName(),this._injectExternalLayout),this._watermark.displayAtStartup(),this._setupGameVisibilityEvents(),n.inAppTutorialMessage&&n.inAppTutorialMessage.displayInAppTutorialMessage(this,this._options.inAppTutorialMessageInPreview,this._options.inAppTutorialMessagePositionInPreview||"");let e=0;this._hasJustResumed=!1,this._renderer.startGameLoop(t=>{try{if(this._paused||(e+=t,this._maxFPS>0&&1e3/e>this._maxFPS+7))return!0;const s=e;return e=0,this._notifyScenesForGameResolutionResize&&(this._sceneStack.onGameResolutionResized(),this._notifyScenesForGameResolutionResize=!1),this._sceneStack.step(s)?(this.getInputManager().onFrameEnded(),this._hasJustResumed=!1,!0):!1}catch(s){throw this._debuggerClient&&this._debuggerClient.onUncaughtException(s),s}}),setTimeout(()=>{this._setupSessionMetrics()},4e3),this._captureManager&&this._captureManager.setupCaptureOptions(this._isPreview)}catch(e){throw this._debuggerClient&&this._debuggerClient.onUncaughtException(e),e}}dispose(e){this._renderer.stopGameLoop(),this._sceneStack.dispose(),this._renderer.dispose(e),this._resourcesLoader.dispose(),this._wasDisposed=!0}enableMetrics(e){this._disableMetrics=!e,e&&this._setupSessionMetrics()}_setupGameVisibilityEvents(){typeof navigator!="undefined"&&typeof document!="undefined"&&(document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&(this._hasJustResumed=!0)}),window.addEventListener("resume",()=>{this._hasJustResumed=!0},!1))}_setupSessionMetrics(){if(this._sessionMetricsInitialized||this._disableMetrics||this.isPreview()||typeof fetch=="undefined"||!this._data.properties.projectUuid)return;const e="https://api.gdevelop-app.com/analytics";this._playerId=this._makePlayerUuid();let t=0,s=0,i=Date.now();const r=this.getPlatformInfo();fetch(e+"/session",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({gameId:this._data.properties.projectUuid,playerId:this._playerId,game:{name:this._data.properties.name||"",packageName:this._data.properties.packageName||"",version:this._data.properties.version||"",location:window.location.href},platform:{isCordova:r.isCordova,devicePlatform:r.devicePlatform,navigatorPlatform:r.navigatorPlatform,hasTouch:r.hasTouch}})}).then(a=>{if(!a.ok)throw console.error("Error while creating the session",a),new Error("Error while creating the session");return a}).then(a=>a.text()).then(a=>{this._sessionId=a}).catch(()=>{});const o=()=>{if(!this._sessionId)return;const a=Date.now();if(s+=a-i,i=a,s<5*1e3)return;const d=Math.floor(s/1e3)*1e3;t+=d,s-=d,navigator.sendBeacon(e+"/session-hit",JSON.stringify({gameId:this._data.properties.projectUuid,playerId:this._playerId,sessionId:this._sessionId,duration:Math.floor(t/1e3)}))};if(typeof navigator!="undefined"&&typeof document!="undefined"){document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"?i=Date.now():o()}),window.addEventListener("pagehide",o,!1),window.addEventListener("pause",o,!1),window.addEventListener("resume",()=>{i=Date.now()},!1);const a=typeof safari=="object"&&safari.pushNotification,d=/electron/i.test(navigator.userAgent);(a||d)&&window.addEventListener("beforeunload",()=>{o()})}this._sessionMetricsInitialized=!0,this._sessionId=this._sessionId}_makePlayerUuid(){try{const e="GDJS-internal-player-uuid",t=localStorage.getItem(e);if(t)return t;const s=n.makeUuid();return localStorage.setItem(e,s),s}catch{return n.makeUuid()}}getSessionId(){return this._sessionId}getPlayerId(){return this._playerId}onWindowInnerSizeChanged(){this._forceGameResolutionUpdate()}_forceGameResolutionUpdate(){this.setGameResolutionSize(this._gameResolutionWidth,this._gameResolutionHeight)}startCurrentSceneProfiler(e){this._throwIfDisposed();const t=this._sceneStack.getCurrentScene();return t?(t.startProfiler(e),!0):!1}stopCurrentSceneProfiler(){this._throwIfDisposed();const e=this._sceneStack.getCurrentScene();!e||e.stopProfiler()}wasFirstSceneLoaded(){return this._sceneStack.wasFirstSceneLoaded()}getSceneStack(){return this._sceneStack}isPreview(){return this._isPreview}isUsingGDevelopDevelopmentEnvironment(){return this._options.environment==="dev"}getExtensionProperty(e,t){for(let s of this._data.properties.extensionProperties)if(s.extension===e&&s.property===t)return s.value;return null}resolveEmbeddedResource(e,t){const s=this._embeddedResourcesMappings.get(e);return s&&s[t]?s[t]:t}getEmbeddedResourcesNames(e){return this._embeddedResourcesMappings.has(e)?Object.keys(this._embeddedResourcesMappings.get(e)):[]}getNetworkSyncData(e){const t={var:this._variables.getNetworkSyncData(e),ss:this._sceneStack.getNetworkSyncData(e)||void 0},s={};return this._variablesByExtensionName.forEach((i,r)=>{const o=i.getNetworkSyncData(e);o.length&&(s[r]=o)}),t.extVar=s,(!t.var||t.var.length===0)&&!t.ss&&(!t.extVar||Object.keys(t.extVar).length===0)?null:t}updateFromNetworkSyncData(e){if(this._throwIfDisposed(),e.var&&this._variables.updateFromNetworkSyncData(e.var),e.ss&&this._sceneStack.updateFromNetworkSyncData(e.ss),e.extVar)for(const t in e.extVar){if(!e.extVar.hasOwnProperty(t))continue;const s=e.extVar[t],i=this.getVariablesForExtension(t);i&&i.updateFromNetworkSyncData(s)}}_throwIfDisposed(){if(this._wasDisposed)throw"The RuntimeGame has been disposed and should not be used anymore."}}n.RuntimeGame=_})(gdjs||(gdjs={}));
2
2
  //# sourceMappingURL=runtimegame.js.map