UNPKG

evidently-pixi

Version:

TypeScript powered set of modules to make it easier to make games in Pixi.js.

187 lines 8.04 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const PIXI = require("pixi.js"); const AssetLoader_1 = require("../Various/AssetLoader"); const TextureStore_1 = require("../Various/TextureStore"); const SceneManager_1 = require("../Managers/SceneManager"); const PostProcessEffects_1 = require("../Managers/PostProcessEffects"); const GameStage_1 = require("../Stages/GameStage"); const KeyboardInput_1 = require("evidently-input/dist/KeyboardInput"); const MouseInput_1 = require("evidently-input/dist/MouseInput"); /** * The bootstrap and entrypoint for a PIXI game. It does the following things in order: * 1. Creates a Pixi instance inside the element specified in `config.gameContainerId`. * 2. Register mouse and keyboard listeners to grab input. * 3. Setups loading screen. * 4. Calls a custom callback to allow you to queue all the assets you need for loading. * 5. Loads all the queued assets. * 6. Removes loading screen. * 7. Initializes the first scene (like a screen of your game: main menu, game itself, game over, leaderboards, etc) * 8. Connects to the ticker that updates the active scene. * 9. Adds all other necessary listeners - changing game dimensions, updating input etc. * * ### Example configuration * * ``` * const game = new Game({ * // `document` and `window` are required to be passed to the configuration * document, * window, * * // ID of the element where the PIXI's canvas should be added * gameContainerId: 'game', * * // optional PIXI configuration, at the very least you want to provide width and height * pixiConfig: { * width: 640, * height: 360, * backgroundColor: 0, * antialias: false, * }, * * // Creates and configures a stage which scales the game pixel-perfect, snapping to full integers of scale, * // ie. x1, x2, x3, for a crisp pixel look. It also handles all of the magic required for Pixi's * // interactions to work and for `MouseInput` library to report proper position * stageFactory: (game: Game) => new ScalingStage( * game, * 640, * 360, * PIXI.SCALE_MODES.NEAREST, * Config.ScalingStageUpscaleMode, * ), * * // Queue some assets to be loaded * onQueueAssets: (game: Game): void { * game.assetLoader.queuePixiAutoFont('topaz_0.png', FontTopaz8Image); * game.assetLoader.queuePixiAutoFont('font-topaz', FontTopaz8); * game.assetLoader.queueTexture(GfxConstants.InitialTileset, InitialTileset); * game.assetLoader.queueTileset(GfxConstants.InitialTileset, { * tileWidth: 16, * tileHeight: 16, * offsetX: 0, * offsetY: 0, * spacingX: 0, * spacingY: 0, * }) * }, * * // Callback to create the starting scene * initialSceneFactory: (game) => new IntroScene(game), * * // Called once everything has finished initializing * onStartGame: () => { * console.log("Game started"); * }, * ); * * // Actually starts the initialization of the game * game.start(); * ``` */ class Game { constructor(config) { if (config.pixiConfig.sharedTicker === undefined) { config.pixiConfig.sharedTicker = true; } this._config = config; this.pixi = new PIXI.Application(config.pixiConfig); this.document = config.document; this.keyboard = new KeyboardInput_1.KeyboardInput(); this.mouse = new MouseInput_1.MouseInput(); this.gameStage = config.stageFactory(this); this.textureStore = new TextureStore_1.TextureStore(); this.assetLoader = new AssetLoader_1.AssetLoader({ textureStore: this.textureStore }); this.sceneManager = new SceneManager_1.SceneManager(); this.postProcessManager = new PostProcessEffects_1.PostProcessEffects(); const gameElement = config.document.getElementById(config.gameContainerId); if (!gameElement) { throw new Error(`Failed to find element '${config.gameContainerId}'`); } gameElement.appendChild(this.pixi.view); this.keyboard.registerListeners(this.document); this.mouse.registerListeners(this.document); } /** * Initializes and runs the game. */ start() { Promise.resolve() .then(() => (this._config.onSetupLoadingScreen || this.setupDefaultLoadingScreen).call(this, this)) .then(() => this._config.onQueueAssets(this)) .then(() => this.loadAssets()) .then(() => (this._config.onRemoveLoadingScreen || this.removeDefaultLoadingScreen).call(this, this)) .then(() => this.initializeScene()) .then(() => this.finalSetup(this)) .then(() => { var _a; return (_a = this._config) === null || _a === void 0 ? void 0 : _a.onStartGame(this); }); } /** * Cretes a new PIXI.Sprite on the specified layer. This new sprite will be attached to the * [[GameStage]], and can be used to actually display something on the screen. * See [[GameStageLayer]] for more information about the types of layers. * @param {GameStageLayer} layer Layer on which to create the container. * @return {PIXI.Sprite} The sprite created and attached to stage. */ createContainer(layer = GameStage_1.GameStageLayer.Normal) { const sprite = new PIXI.Sprite(); this.gameStage.addChild(sprite, layer); return sprite; } /** * Removes a container previously created by the call to `createContainer` from the stage. Use * it when it's no longer in use, typicall when switching from a [[Scene]]. * @param {PIXI.Sprite} container The contianer to remove */ removeContainer(container) { this.gameStage.removeChild(container); } update() { const delta = this.pixi.ticker.elapsedMS; this.sceneManager.update(delta); this.postProcessManager.update(delta); this.gameStage.update(delta); this.mouse.update(); this.keyboard.update(); } setupDefaultLoadingScreen(game) { const div = game.document.createElement('div'); div.id = "__default-loading-div"; div.style.position = "fixed"; div.style.left = "0"; div.style.right = "0"; div.style.top = "0"; div.style.bottom = "0"; div.style.background = "#444"; div.style.color = "white"; div.style.fontSize = "80px"; div.style.display = "flex"; div.style.justifyContent = "center"; div.style.alignContent = "center"; div.style.alignItems = "center"; div.textContent = "Loading"; this.document.getElementsByTagName('body')[0].appendChild(div); } removeDefaultLoadingScreen() { var _a, _b; const loadingDiv = this.document.getElementById('__default-loading-div'); (_b = (_a = loadingDiv) === null || _a === void 0 ? void 0 : _a.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(loadingDiv); } loadAssets() { return this.assetLoader.load(this.pixi.loader); } initializeScene() { this.sceneManager.changeScene(this._config.initialSceneFactory(this)); } finalSetup(game) { game._config.window.onresize = () => { game.onWindowResize(game, game._config.window.innerWidth, game._config.window.innerHeight); }; game.pixi.ticker.add(() => game.update()); game.onWindowResize(game, game._config.window.innerWidth, game._config.window.innerHeight); } onWindowResize(game, width, height) { game.pixi.renderer.resize(width, height); game.gameStage.setWindowDimensions(width, height); } } exports.Game = Game; //# sourceMappingURL=Game.js.map