import type Camera2d from "./../camera/camera2d.ts"; import World from "../physics/world.js"; import type Renderer from "./../video/renderer.js"; import type { ApplicationSettings, ResolvedApplicationSettings } from "./settings.ts"; /** * The Application class is the main entry point for creating a melonJS game. * The constructor resolves the given settings, creates the game world and * registers DOM event listeners (resize, orientation, scroll); you **MUST** * then call (and await) {@link Application#init init}, which builds the * renderer, appends the canvas to the parent element, and starts the game * loop — without it the application has no renderer and displays nothing. * * The Application instance provides access to the core game systems: * - {@link Application#renderer renderer} — the active Canvas, WebGL or (experimental) WebGPU renderer * - {@link Application#world world} — the root container for all game objects * - {@link Application#viewport viewport} — the default camera / viewport * * The app instance is automatically passed to {@link Stage#onResetEvent} and * {@link Stage#onDestroyEvent}, and is accessible from any renderable via * {@link Renderable#parentApp parentApp}. * @category Application * @example * // create a new melonJS Application * const app = new Application(800, 600, { * parent: "screen", * scaleMethod: "flex-width", * renderer: 2, // AUTO * }); * * // build the renderer (mandatory — only suspends for WebGPU) * await app.init(); * * // add objects to the world * app.world.addChild(new Sprite(0, 0, { image: "player" })); * * // access the viewport * app.viewport.follow(player, app.viewport.AXIS.BOTH); */ export default class Application { /** * the parent HTML element holding the main canvas of this application */ parentElement: HTMLElement; /** * a reference to the active Canvas, WebGL or (experimental) WebGPU renderer */ renderer: Renderer; /** * the active stage "default" camera */ viewport: Camera2d; /** * a reference to the game world,
* a world is a virtual environment containing all the game objects */ world: World; /** * when true, all objects will be added under the root world container.
* When false, a `me.Container` object will be created for each corresponding groups * @default true */ mergeGroup: boolean; /** * Last time the game update loop was executed.
* Use this value to implement frame prediction in drawing events, * for creating smooth motion while running game update logic at * a lower fps. */ lastUpdate: DOMHighResTimeStamp; /** * true when this app instance has been initialized * @default false */ isInitialized: boolean; /** * the given settings used when creating this application */ settings: ResolvedApplicationSettings; /** * Specify whether to pause this app when losing focus * @default true * @example * // keep the default game instance running even when losing focus * app.pauseOnBlur = false; */ pauseOnBlur: boolean; /** * Specify whether to unpause this app when gaining back focus * @default true */ resumeOnFocus: boolean; /** * Specify whether to stop this app when losing focus * @default false */ stopOnBlur: boolean; isDirty: boolean; isAlwaysDirty: boolean; frameCounter: number; frameRate: number; accumulator: number; accumulatorMax: number; accumulatorUpdateDelta: number; stepSize: number; /** * Simulated time advanced by one logic step, in ms — what `world.update()` * receives. Fixed at `1000 / world.fps` unless `timer.interpolation` is on, * in which case it follows the real frame delta. * * Not to be confused with {@link Application#lastUpdateDelta}, which is how * long that step actually took to compute. */ updateDelta: number; lastUpdateStart: number | null; /** * Measured wall-clock cost of the most recent logic step, in ms * (`performance.now()` taken either side of the world/stage update). * * Used by the fixed-timestep loop to avoid a spiral of death: the * accumulator drains by at least this much, so a scene too heavy to * simulate in real time slows down instead of locking up. * * Only the *last* step of a frame is recorded, so a frame that ran several * catch-up steps reports less than its total update cost. * Renamed from `updateAverageDelta` in 20.0.0. * @since 20.0.0 */ lastUpdateDelta: number; /** * @deprecated since 20.0.0 — renamed to {@link Application#lastUpdateDelta}. * The old name claimed an average that has not existed since 2015, when the * exponential smoothing behind it was removed a day after being added. */ get updateAverageDelta(): number; set updateAverageDelta(value: number); /** * Create a new melonJS Application. * Constructing the instance is only the first half of starting a game: * you **MUST** then call (and await) {@link Application#init init} to * build the renderer — an Application on which `init()` has not resolved * has no `renderer`, no canvas, and cannot render anything. * @param width - The width of the canvas viewport * @param height - The height of the canvas viewport * @param options - The optional parameters for the application and default renderer * @example * const app = new Application(1024, 768, { * parent: "game-container", * scale: "auto", * scaleMethod: "fit", * renderer: 2, // AUTO * }); * await app.init(); */ constructor(width: number, height: number, options?: Partial); /** * Build the renderer and everything that depends on it — the canvas * (appended to the parent element), the initial resize layout, and the * console banner. Reads {@link Application#settings}, resolved by the * constructor; it takes no arguments of its own. * * **Calling and awaiting this is mandatory** — it is the second half of * every Application's start-up, not an optional step. It resolves * synchronously for the Canvas and WebGL backends, which acquire their * context without suspending — but WebGPU cannot, and an application * whose `init()` has not resolved has no `renderer`. * @throws {Error} if it fails to instantiate the requested renderer * (e.g. `renderer: video.WEBGL` on a device with no WebGL 2 support) * @returns resolves once the application is ready to use * @example * const app = new Application(640, 480, { parent: "screen" }); * await app.init(); */ init(): Promise; /** * reset the game Object manager * destroy all current objects */ reset(): void; /** * Specify the property to be used when sorting renderables for this application game world. * Accepted values : "x", "y", "z", "depth" * @see {@link World.sortOn} */ get sortOn(): "x" | "y" | "z" | "depth"; set sortOn(value: "x" | "y" | "z" | "depth"); /** * Fired when a level is fully loaded and all renderable instantiated.
* Additionally the level id will also be passed to the called function. * @example * // call myFunction () everytime a level is loaded * app.onLevelLoaded = this.myFunction.bind(this); */ onLevelLoaded(): void; /** * Update the renderer framerate using the system config variables. * @see {@link timer.maxfps} * @see {@link World.fps} */ updateFrameRate(): void; /** * Returns the parent HTML Element holding the main canvas of this application * @returns the parent HTML element */ getParentElement(): HTMLElement; /** * Returns `true` if the browser/device is currently in fullscreen mode. * Thin convenience around {@link device.isFullscreen} so the * fullscreen trio (`isFullscreen` / `requestFullscreen` / * `exitFullscreen`) lives together on the app instance. * @category Application */ isFullscreen(): boolean; /** * Trigger a fullscreen request for this application. Defaults to this * application's `parentElement` (the container the canvas was appended * into — see {@link Application#getParentElement}), so the canvas and * any sibling HUD / overlay markup inside that container go fullscreen * together. * @param element - optional element to fullscreen instead of `this.parentElement` * @example * // bind F to toggle fullscreen * me.input.bindKey(me.input.KEY.F, "toggleFullscreen"); * me.event.on(me.event.KEYDOWN, (action) => { * if (action === "toggleFullscreen") { * if (!app.isFullscreen()) app.requestFullscreen(); * else app.exitFullscreen(); * } * }); * @category Application */ requestFullscreen(element?: Element): void; /** * Exit fullscreen mode for this application. * @category Application */ exitFullscreen(): void; /** * The HTML canvas element associated with this application's renderer. * @example * // access the canvas DOM element * const canvas = app.canvas; */ get canvas(): HTMLCanvasElement; /** * Trigger a manual resize of the application canvas to fit the parent element. * This is automatically called on window resize/orientation change, but can * be called manually if the parent element size changes programmatically. * @example * // force a resize after changing the parent element dimensions * app.resize(); */ resize(): void; /** * Destroy this application instance and release all associated resources. * Removes the canvas from the DOM, destroys the world, and unregisters * all event listeners. * * **Terminal**: a destroyed Application cannot be re-initialized — * `init()` rejects afterwards (and an `init()` still in flight aborts). * Construct a new Application to start again. * @param removeCanvas - if true, the canvas element is removed from the DOM (default: true) * @example * // clean up when done * app.destroy(); */ destroy(removeCanvas?: boolean): void; /** * force the redraw (not update) of all objects */ repaint(): void; /** * Pause the current stage. Convenience proxy for {@link state.pause}. * @param [music=false] - also pause the current music track * @example * app.pause(); // pause game updates, keep music playing * app.pause(true); // pause game updates and music */ pause(music?: boolean): void; /** * Resume the current stage. Convenience proxy for {@link state.resume}. * @param [music=false] - also resume the current music track */ resume(music?: boolean): void; /** * Freeze the current stage for a fixed duration, then automatically resume. * Useful for hit-stop / hit-pause effects on impact. * * Convenience proxy for {@link state.freeze}; see that method's * documentation for the full behaviour matrix (extend-not-stack semantics, * interaction with manual `state.pause()` / `state.resume()`, automatic * cancellation on window blur, etc.). * @param duration - duration of the freeze in milliseconds * @param [music=false] - also pause the current music track during the freeze * @returns a Promise that resolves once the freeze ends (or is cancelled) * @example * // simple hit-stop on impact * app.freeze(80); * * // chain VFX after the freeze * await app.freeze(120); * spawnImpactParticles(); */ freeze(duration: number, music?: boolean): Promise; /** * update all objects related to this game active scene/stage * @param time - current timestamp as provided by the RAF callback */ update(time: number): void; /** * draw the active scene/stage associated to this game */ draw(): void; } /** * The default game application instance. * Set via {@link setDefaultGame} during engine initialization. * When using {@link Application} directly, prefer using the app instance * (e.g. from {@link Stage#onResetEvent} or {@link Renderable#parentApp}). */ export declare let game: Application; //# sourceMappingURL=application.d.ts.map