UNPKG

phaser

Version:

A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers from the team at Phaser Studio Inc.

1,440 lines (1,274 loc) 60 kB
/** * @author Richard Davey <rich@phaser.io> * @copyright 2013-2026 Phaser Studio Inc. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ var CanvasPool = require('../display/canvas/CanvasPool'); var CanvasTexture = require('./CanvasTexture'); var Class = require('../utils/Class'); var Color = require('../display/color/Color'); var CONST = require('../const'); var DynamicTexture = require('./DynamicTexture'); var EventEmitter = require('eventemitter3'); var Events = require('./events'); var Frame = require('./Frame'); var GameEvents = require('../core/events'); var GetValue = require('../utils/object/GetValue'); var ImageGameObject = require('../gameobjects/image/Image'); var IntegerToColor = require('../display/color/IntegerToColor'); var IsPlainObject = require('../utils/object/IsPlainObject'); var Parser = require('./parsers'); var Rectangle = require('../geom/rectangle/Rectangle'); var Texture = require('./Texture'); var TileSpriteGameObject = require('../gameobjects/tilesprite/TileSprite'); /** * @callback EachTextureCallback * * @param {Phaser.Textures.Texture} texture - Each texture in the Texture Manager. * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. */ /** * @classdesc * When Phaser boots it will create an instance of this Texture Manager class. * * It is a global manager that handles all textures in your game. You can access it from within * a Scene via the `this.textures` property. * * Its role is as a manager for all textures that your game uses. It can create, update and remove * textures globally, as well as parse texture data from external files, such as sprite sheets * and texture atlases. * * Sprites and other texture-based Game Objects get their texture data directly from this class. * * @class TextureManager * @extends Phaser.Events.EventEmitter * @memberof Phaser.Textures * @constructor * @since 3.0.0 * * @param {Phaser.Game} game - The Phaser.Game instance this Texture Manager belongs to. */ var TextureManager = new Class({ Extends: EventEmitter, initialize: function TextureManager (game) { EventEmitter.call(this); /** * The Game that the Texture Manager belongs to. * * A game will only ever have one instance of a Texture Manager. * * @name Phaser.Textures.TextureManager#game * @type {Phaser.Game} * @since 3.0.0 */ this.game = game; /** * The internal name of this manager. * * @name Phaser.Textures.TextureManager#name * @type {string} * @readonly * @since 3.0.0 */ this.name = 'TextureManager'; /** * This object contains all Textures that belong to this Texture Manager. * * Textures are identified by string-based keys, which are used as the property * within this object. Therefore, you can access any texture directly from this * object without any iteration. * * You should not typically modify this object directly, but instead use the * methods provided by the Texture Manager to add and remove entries from it. * * @name Phaser.Textures.TextureManager#list * @type {object} * @default {} * @since 3.0.0 */ this.list = {}; /** * The temporary canvas element used to save the pixel data of an arbitrary texture * during the `TextureManager.getPixel` and `getPixelAlpha` methods. * * @name Phaser.Textures.TextureManager#_tempCanvas * @type {HTMLCanvasElement} * @private * @since 3.0.0 */ this._tempCanvas = CanvasPool.create2D(this); /** * The 2d context of the `_tempCanvas` element. * * @name Phaser.Textures.TextureManager#_tempContext * @type {CanvasRenderingContext2D} * @private * @since 3.0.0 */ this._tempContext = this._tempCanvas.getContext('2d', { willReadFrequently: true }); /** * An internal tracking value used for emitting the 'READY' event after all of * the managers in the game have booted. * * @name Phaser.Textures.TextureManager#_pending * @type {number} * @private * @default 0 * @since 3.0.0 */ this._pending = 0; /** * An Image Game Object that belongs to this Texture Manager. * * Used as a drawing stamp within Dynamic Textures. * * This is not part of the display list and doesn't render. * * Prior to v4.0.0, this was of the type `Phaser.GameObjects.Image`. * * @name Phaser.Textures.TextureManager#stamp * @type {Phaser.GameObjects.Stamp} * @readonly * @since 3.60.0 */ this.stamp; /** * The crop Rectangle as used by the Stamp when it needs to crop itself. * * @name Phaser.Textures.TextureManager#stampCrop * @type {Phaser.Geom.Rectangle} * @since 3.60.0 */ this.stampCrop = new Rectangle(); /** * A TileSprite Game Object that belongs to this Texture Manager. * * Used for repeated drawing within Dynamic Textures. * * This is not part of the display list and doesn't render. * * @name Phaser.Textures.TextureManager#tileSprite * @type {Phaser.GameObjects.TileSprite} * @readonly * @since 4.0.0 */ this.tileSprite; /** * If this flag is `true` then the Texture Manager will never emit any * warnings to the console log that report missing textures. * * @name Phaser.Textures.TextureManager#silentWarnings * @type {boolean} * @default false * @since 3.60.0 */ this.silentWarnings = false; game.events.once(GameEvents.BOOT, this.boot, this); }, /** * The Boot Handler called by Phaser.Game when it first starts up. * * @method Phaser.Textures.TextureManager#boot * @private * @since 3.0.0 */ boot: function () { this._pending = 3; this.on(Events.LOAD, this.updatePending, this); this.on(Events.ERROR, this.updatePending, this); var config = this.game.config; if (config.defaultImage !== null) { this.addBase64('__DEFAULT', config.defaultImage); } if (config.missingImage !== null) { this.addBase64('__MISSING', config.missingImage); } if (config.whiteImage !== null) { this.addBase64('__WHITE', config.whiteImage); } if (this.game.renderer && this.game.renderer.gl) { this.addUint8Array('__NORMAL', new Uint8Array([ 127, 127, 255, 255 ]), 1, 1); } this.game.events.once(GameEvents.DESTROY, this.destroy, this); this.game.events.once(GameEvents.SYSTEM_READY, function (scene) { this.stamp = new ImageGameObject(scene).setOrigin(0); this.tileSprite = new TileSpriteGameObject(scene, 0, 0, 256, 256, '__WHITE').setOrigin(0); }, this); }, /** * After 'onload' or 'onerror' invoked twice, emit 'ready' event. * * @method Phaser.Textures.TextureManager#updatePending * @private * @since 3.0.0 */ updatePending: function () { this._pending--; if (this._pending === 0) { this.off(Events.LOAD); this.off(Events.ERROR); this.emit(Events.READY); } }, /** * Checks the given texture key and logs a console.error if the key is already in use, then returns false. * * If you wish to avoid the console.warn then use `TextureManager.exists` instead. * * @method Phaser.Textures.TextureManager#checkKey * @since 3.7.0 * * @param {string} key - The texture key to check. * * @return {boolean} `true` if it's safe to use the texture key, otherwise `false`. */ checkKey: function (key) { if (!key || typeof key !== 'string' || this.exists(key)) { if (!this.silentWarnings) { // eslint-disable-next-line no-console console.error('Texture key already in use: ' + key); } return false; } return true; }, /** * Removes a Texture from the Texture Manager and destroys it. This will immediately * clear all references to it from the Texture Manager, and if it has one, destroy its * WebGLTexture. This will emit a `removetexture` event. * * Note: If you have any Game Objects still using this texture they will start throwing * errors the next time they try to render. Make sure that removing the texture is the final * step when clearing down to avoid this. * * @method Phaser.Textures.TextureManager#remove * @fires Phaser.Textures.Events#REMOVE * @since 3.7.0 * * @param {(string|Phaser.Textures.Texture)} key - The key of the Texture to remove, or a reference to it. * * @return {Phaser.Textures.TextureManager} The Texture Manager. */ remove: function (key) { if (typeof key === 'string') { if (this.exists(key)) { key = this.get(key); } else { if (!this.silentWarnings) { console.warn('No texture found matching key: ' + key); } return this; } } // By this point key should be a Texture, if not, the following fails anyway var textureKey = key.key; if (this.list.hasOwnProperty(textureKey)) { key.destroy(); this.emit(Events.REMOVE, textureKey); this.emit(Events.REMOVE_KEY + textureKey); } return this; }, /** * Removes a key from the Texture Manager but does not destroy the Texture that was using the key. * * @method Phaser.Textures.TextureManager#removeKey * @since 3.17.0 * * @param {string} key - The key to remove from the texture list. * * @return {Phaser.Textures.TextureManager} The Texture Manager. */ removeKey: function (key) { if (this.list.hasOwnProperty(key)) { delete this.list[key]; } return this; }, /** * Adds a new Texture to the Texture Manager created from the given Base64 encoded data. * * It works by creating an `Image` DOM object, then setting the `src` attribute to * the given base64 encoded data. As a result, the process is asynchronous by its nature, * so be sure to listen for the events this method dispatches before using the texture. * * @method Phaser.Textures.TextureManager#addBase64 * @fires Phaser.Textures.Events#ADD * @fires Phaser.Textures.Events#ERROR * @fires Phaser.Textures.Events#LOAD * @since 3.0.0 * * @param {string} key - The unique string-based key of the Texture. * @param {*} data - The Base64 encoded data. * * @return {this} This Texture Manager instance. */ addBase64: function (key, data) { if (this.checkKey(key)) { var _this = this; var image = new Image(); image.onerror = function () { _this.emit(Events.ERROR, key); }; image.onload = function () { var texture = _this.create(key, image); if (!texture) { return; } Parser.Image(texture, 0); _this.emit(Events.ADD, key, texture); _this.emit(Events.ADD_KEY + key, texture); _this.emit(Events.LOAD, key, texture); }; image.src = data; } return this; }, /** * Gets an existing texture frame and converts it into a base64 encoded image and returns the base64 data. * * You can also provide the image type and encoder options. * * This will only work with bitmap based texture frames, such as those created from Texture Atlases. * It will not work with GL Texture objects, such as Shaders, or Render Textures. For those please * see the WebGL Snapshot function instead. * * @method Phaser.Textures.TextureManager#getBase64 * @since 3.12.0 * * @param {string} key - The unique string-based key of the Texture. * @param {(string|number)} [frame] - The string-based name, or integer based index, of the Frame to get from the Texture. * @param {string} [type='image/png'] - A DOMString indicating the image format. The default format type is image/png. * @param {number} [encoderOptions=0.92] - A Number between 0 and 1 indicating the image quality to use for image formats that use lossy compression such as image/jpeg and image/webp. If this argument is anything else, the default value for image quality is used. The default value is 0.92. Other arguments are ignored. * * @return {string} The base64 encoded data, or an empty string if the texture frame could not be found. */ getBase64: function (key, frame, type, encoderOptions) { if (type === undefined) { type = 'image/png'; } if (encoderOptions === undefined) { encoderOptions = 0.92; } var data = ''; var textureFrame = this.getFrame(key, frame); if (textureFrame && (textureFrame.source.isRenderTexture || textureFrame.source.isGLTexture)) { if (!this.silentWarnings) { console.warn('Cannot getBase64 from WebGL Texture'); } } else if (textureFrame) { var cd = textureFrame.canvasData; var canvas = CanvasPool.create2D(this, cd.width, cd.height); var ctx = canvas.getContext('2d', { willReadFrequently: true }); if (cd.width > 0 && cd.height > 0) { ctx.drawImage( textureFrame.source.image, cd.x, cd.y, cd.width, cd.height, 0, 0, cd.width, cd.height ); } data = canvas.toDataURL(type, encoderOptions); CanvasPool.remove(canvas); } return data; }, /** * Adds a new Texture to the Texture Manager created from the given Image element. * * @method Phaser.Textures.TextureManager#addImage * @fires Phaser.Textures.Events#ADD * @since 3.0.0 * * @param {string} key - The unique string-based key of the Texture. * @param {HTMLImageElement} source - The source Image element. * @param {HTMLImageElement|HTMLCanvasElement} [dataSource] - An optional data Image element. * * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. */ addImage: function (key, source, dataSource) { var texture = null; if (this.checkKey(key)) { texture = this.create(key, source); Parser.Image(texture, 0); if (dataSource) { texture.setDataSource(dataSource); } this.emit(Events.ADD, key, texture); this.emit(Events.ADD_KEY + key, texture); } return texture; }, /** * Takes a WebGLTextureWrapper and creates a Phaser Texture from it, which is added to the Texture Manager using the given key. * * This allows you to then use the Texture as a normal texture for texture based Game Objects like Sprites. * * This is a WebGL only feature. * * Prior to Phaser 3.80.0, this method took a bare `WebGLTexture` * as the `glTexture` parameter. You must now wrap the `WebGLTexture` in a * `WebGLTextureWrapper` instance before passing it to this method. * * @method Phaser.Textures.TextureManager#addGLTexture * @fires Phaser.Textures.Events#ADD * @since 3.19.0 * * @param {string} key - The unique string-based key of the Texture. * @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} glTexture - The source Render Texture. * * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. */ addGLTexture: function (key, glTexture) { var texture = null; if (this.checkKey(key)) { var width = glTexture.width; var height = glTexture.height; texture = this.create(key, glTexture, width, height); texture.add('__BASE', 0, 0, 0, width, height); this.emit(Events.ADD, key, texture); this.emit(Events.ADD_KEY + key, texture); } return texture; }, /** * Adds a Compressed Texture to this Texture Manager. * * The texture should typically have been loaded via the `CompressedTextureFile` loader, * in order to prepare the correct data object this method requires. * * You can optionally also pass atlas data to this method, in which case a texture atlas * will be generated from the given compressed texture, combined with the atlas data. * * @method Phaser.Textures.TextureManager#addCompressedTexture * @fires Phaser.Textures.Events#ADD * @since 3.60.0 * * @param {string} key - The unique string-based key of the Texture. * @param {Phaser.Types.Textures.CompressedTextureData} textureData - The Compressed Texture data object. * @param {object} [atlasData] - Optional Texture Atlas data. * * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. */ addCompressedTexture: function (key, textureData, atlasData) { var texture = null; if (this.checkKey(key)) { texture = this.create(key, textureData); texture.add('__BASE', 0, 0, 0, textureData.width, textureData.height); if (atlasData) { var parse = function (texture, sourceIndex, atlasData) { if (Array.isArray(atlasData.textures) || Array.isArray(atlasData.frames)) { Parser.JSONArray(texture, sourceIndex, atlasData); } else { Parser.JSONHash(texture, sourceIndex, atlasData); } }; if (Array.isArray(atlasData)) { for (var i = 0; i < atlasData.length; i++) { parse(texture, i, atlasData[i]); } } else { parse(texture, 0, atlasData); } } this.emit(Events.ADD, key, texture); this.emit(Events.ADD_KEY + key, texture); } return texture; }, /** * Adds a Render Texture to the Texture Manager using the given key. * This allows you to then use the Render Texture as a normal texture for texture based Game Objects like Sprites. * * @method Phaser.Textures.TextureManager#addRenderTexture * @fires Phaser.Textures.Events#ADD * @since 3.12.0 * * @param {string} key - The unique string-based key of the Texture. * @param {Phaser.GameObjects.RenderTexture} renderTexture - The source Render Texture. * * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. */ addRenderTexture: function (key, renderTexture) { var texture = null; if (this.checkKey(key)) { texture = this.create(key, renderTexture); texture.add('__BASE', 0, 0, 0, renderTexture.width, renderTexture.height); this.emit(Events.ADD, key, texture); this.emit(Events.ADD_KEY + key, texture); } return texture; }, /** * Creates a new Texture using a blank Canvas element of the size given. * * Canvas elements are automatically pooled and calling this method will * extract a free canvas from the CanvasPool, or create one if none are available. * * @method Phaser.Textures.TextureManager#createCanvas * @since 3.0.0 * * @param {string} key - The unique string-based key of the Texture. * @param {number} [width=256] - The width of the Canvas element. * @param {number} [height=256] - The height of the Canvas element. * * @return {?Phaser.Textures.CanvasTexture} The Canvas Texture that was created, or `null` if the key is already in use. */ createCanvas: function (key, width, height) { if (width === undefined) { width = 256; } if (height === undefined) { height = 256; } if (this.checkKey(key)) { var canvas = CanvasPool.create(this, width, height, CONST.CANVAS, true); return this.addCanvas(key, canvas); } return null; }, /** * Creates a new Canvas Texture object from an existing Canvas element * and adds it to this Texture Manager, unless `skipCache` is true. * * @method Phaser.Textures.TextureManager#addCanvas * @fires Phaser.Textures.Events#ADD * @since 3.0.0 * * @param {string} key - The unique string-based key of the Texture. * @param {HTMLCanvasElement} source - The Canvas element to form the base of the new Texture. * @param {boolean} [skipCache=false] - Skip adding this Texture into the Cache? * * @return {?Phaser.Textures.CanvasTexture} The Canvas Texture that was created, or `null` if the key is already in use. */ addCanvas: function (key, source, skipCache) { if (skipCache === undefined) { skipCache = false; } var texture = null; if (skipCache) { texture = new CanvasTexture(this, key, source, source.width, source.height); } else if (this.checkKey(key)) { texture = new CanvasTexture(this, key, source, source.width, source.height); this.list[key] = texture; this.emit(Events.ADD, key, texture); this.emit(Events.ADD_KEY + key, texture); } return texture; }, /** * Creates a Dynamic Texture instance and adds itself to this Texture Manager. * * A Dynamic Texture is a special texture that allows you to draw textures, frames and most kind of * Game Objects directly to it. * * You can take many complex objects and draw them to this one texture, which can then be used as the * base texture for other Game Objects, such as Sprites. Should you then update this texture, all * Game Objects using it will instantly be updated as well, reflecting the changes immediately. * * It's a powerful way to generate dynamic textures at run-time that are WebGL friendly and don't invoke * expensive GPU uploads on each change. * * See the methods available on the `DynamicTexture` class for more details. * * Optionally, you can also pass a Dynamic Texture instance to this method to have * it added to the Texture Manager. * * @method Phaser.Textures.TextureManager#addDynamicTexture * @fires Phaser.Textures.Events#ADD * @since 3.60.0 * * @param {(string|Phaser.Textures.DynamicTexture)} key - The string-based key of this Texture. Must be unique within the Texture Manager. Or, a DynamicTexture instance. * @param {number} [width=256] - The width of this Dynamic Texture in pixels. Defaults to 256 x 256. Ignored if an instance is passed as the key. * @param {number} [height=256] - The height of this Dynamic Texture in pixels. Defaults to 256 x 256. Ignored if an instance is passed as the key. * @param {boolean} [forceEven=true] - If the width and height are odd numbers, should they be forced to be even? Ignored if an instance is passed as the key. * * @return {?Phaser.Textures.DynamicTexture} The Dynamic Texture that was created, or `null` if the key is already in use. */ addDynamicTexture: function (key, width, height, forceEven) { var texture = null; if (typeof(key) === 'string' && !this.exists(key)) { if (forceEven === undefined) { forceEven = true; } texture = new DynamicTexture(this, key, width, height, forceEven); } else { texture = key; key = texture.key; } if (this.checkKey(key)) { this.list[key] = texture; this.emit(Events.ADD, key, texture); this.emit(Events.ADD_KEY + key, texture); } else { texture = null; } return texture; }, /** * Adds a Texture Atlas to this Texture Manager. * * In Phaser terminology, a Texture Atlas is a combination of an atlas image and a data file * describing the frames within it, such as those exported by applications like Texture Packer. * * This method accepts three different atlas data formats: * * - **JSON Array** — the `frames` or `textures` field is an Array. Used by Texture Packer's * "JSON Array" and "Phaser (multi-atlas)" exports. Dispatched to `addAtlasJSONArray`. * - **JSON Hash** — the `frames` field is an Object. Used by Texture Packer's "JSON Hash" export. * Dispatched to `addAtlasJSONHash`. * - **Phaser Compact Texture (PCT)** — a decoded PCT data object with a `pages` array. This is * the compact line-oriented format loaded by `LoaderPlugin#atlasPCT`. Dispatched to `addAtlasPCT`. * * The format is detected automatically from the shape of the `data` argument. As of Phaser 3.60 * you can use this method to add an atlas data set to an existing Phaser Texture. * * @method Phaser.Textures.TextureManager#addAtlas * @since 3.0.0 * * @param {string} key - The unique string-based key of the Texture. * @param {(HTMLImageElement|HTMLImageElement[]|Phaser.Textures.Texture)} source - The source Image element/s, or a Phaser Texture. * @param {(object|object[])} data - The Texture Atlas data/s. * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. * * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. */ addAtlas: function (key, source, data, dataSource) { // Phaser Compact Texture Atlas format? if (data && !Array.isArray(data) && Array.isArray(data.pages) && data.frames && !Array.isArray(data.frames)) { return this.addAtlasPCT(key, source, data, dataSource); } // New Texture Packer format? if (Array.isArray(data.textures) || Array.isArray(data.frames)) { return this.addAtlasJSONArray(key, source, data, dataSource); } else { return this.addAtlasJSONHash(key, source, data, dataSource); } }, /** * Adds a Texture Atlas to this Texture Manager. * * In Phaser terminology, a Texture Atlas is a combination of an atlas image and a JSON data file, * such as those exported by applications like Texture Packer. * * The frame data of the atlas must be stored in an Array within the JSON. * * This is known as a JSON Array in software such as Texture Packer. * * As of Phaser 3.60 you can use this method to add an atlas data set to an existing Phaser Texture. * * @method Phaser.Textures.TextureManager#addAtlasJSONArray * @fires Phaser.Textures.Events#ADD * @since 3.0.0 * * @param {string} key - The unique string-based key of the Texture. * @param {(HTMLImageElement|HTMLImageElement[]|Phaser.Textures.Texture)} source - The source Image element/s, or a Phaser Texture. * @param {(object|object[])} data - The Texture Atlas data/s. * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. * * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. */ addAtlasJSONArray: function (key, source, data, dataSource) { var texture = null; if (source instanceof Texture) { key = source.key; texture = source; } else if (this.checkKey(key)) { texture = this.create(key, source); } if (texture) { // Multi-Atlas? if (Array.isArray(data)) { var singleAtlasFile = (data.length === 1); // multi-pack with one atlas file for all images // !! Assumes the textures are in the same order in the source array as in the json data !! for (var i = 0; i < texture.source.length; i++) { var atlasData = singleAtlasFile ? data[0] : data[i]; Parser.JSONArray(texture, i, atlasData); } } else { Parser.JSONArray(texture, 0, data); } if (dataSource) { texture.setDataSource(dataSource); } this.emit(Events.ADD, key, texture); this.emit(Events.ADD_KEY + key, texture); } return texture; }, /** * Adds a Texture Atlas to this Texture Manager. * * In Phaser terminology, a Texture Atlas is a combination of an atlas image and a JSON data file, * such as those exported by applications like Texture Packer. * * The frame data of the atlas must be stored in an Object within the JSON. * * This is known as a JSON Hash in software such as Texture Packer. * * As of Phaser 3.60 you can use this method to add an atlas data set to an existing Phaser Texture. * * @method Phaser.Textures.TextureManager#addAtlasJSONHash * @fires Phaser.Textures.Events#ADD * @since 3.0.0 * * @param {string} key - The unique string-based key of the Texture. * @param {(HTMLImageElement|HTMLImageElement[]|Phaser.Textures.Texture)} source - The source Image element/s, or a Phaser Texture. * @param {(object|object[])} data - The Texture Atlas data/s. * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. * * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. */ addAtlasJSONHash: function (key, source, data, dataSource) { var texture = null; if (source instanceof Texture) { key = source.key; texture = source; } else if (this.checkKey(key)) { texture = this.create(key, source); } if (texture) { if (Array.isArray(data)) { for (var i = 0; i < data.length; i++) { Parser.JSONHash(texture, i, data[i]); } } else { Parser.JSONHash(texture, 0, data); } if (dataSource) { texture.setDataSource(dataSource); } this.emit(Events.ADD, key, texture); this.emit(Events.ADD_KEY + key, texture); } return texture; }, /** * Adds a Phaser Compact Texture Atlas (PCT) to this Texture Manager. * * PCT is a compact line-oriented atlas format. A single PCT file can describe multiple atlas * pages, each referencing a separate texture image. The `data` argument must be a decoded PCT * structure as produced by `Phaser.Textures.Parsers.PCTDecode` — that is, an object containing * `pages`, `folders`, and `frames` fields. The `source` argument should be a single Image or an * Array of Images, one per page, in the same order as the `pages` field on the decoded data. * * You do not normally need to call this method directly. It is called automatically when the * `LoaderPlugin#atlasPCT` method finishes loading a PCT file. You can also use this method to add a * decoded PCT data set to an existing Phaser Texture. * * @method Phaser.Textures.TextureManager#addAtlasPCT * @fires Phaser.Textures.Events#ADD * @since 4.0.0 * * @param {string} key - The unique string-based key of the Texture. * @param {(HTMLImageElement|HTMLImageElement[]|Phaser.Textures.Texture)} source - The source Image element(s) — one per PCT page — or an existing Phaser Texture. * @param {object} data - The decoded PCT data object. * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element (normal map source). * * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. */ addAtlasPCT: function (key, source, data, dataSource) { var texture = null; if (source instanceof Texture) { key = source.key; texture = source; } else if (this.checkKey(key)) { texture = this.create(key, source); } if (texture) { Parser.PCT(texture, data); if (dataSource) { texture.setDataSource(dataSource); } this.emit(Events.ADD, key, texture); this.emit(Events.ADD_KEY + key, texture); } return texture; }, /** * Adds a Texture Atlas to this Texture Manager. * * In Phaser terminology, a Texture Atlas is a combination of an atlas image and a data file, * such as those exported by applications like Texture Packer. * * The frame data of the atlas must be stored in an XML file. * * As of Phaser 3.60 you can use this method to add an atlas data set to an existing Phaser Texture. * * @method Phaser.Textures.TextureManager#addAtlasXML * @fires Phaser.Textures.Events#ADD * @since 3.7.0 * * @param {string} key - The unique string-based key of the Texture. * @param {(HTMLImageElement|Phaser.Textures.Texture)} source - The source Image element, or a Phaser Texture. * @param {object} data - The Texture Atlas XML data. * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. * * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. */ addAtlasXML: function (key, source, data, dataSource) { var texture = null; if (source instanceof Texture) { key = source.key; texture = source; } else if (this.checkKey(key)) { texture = this.create(key, source); } if (texture) { Parser.AtlasXML(texture, 0, data); if (dataSource) { texture.setDataSource(dataSource); } this.emit(Events.ADD, key, texture); this.emit(Events.ADD_KEY + key, texture); } return texture; }, /** * Adds a Unity Texture Atlas to this Texture Manager. * * In Phaser terminology, a Texture Atlas is a combination of an atlas image and a data file, * such as those exported by applications like Texture Packer or Unity. * * The frame data of the atlas must be stored in a Unity YAML file. * * As of Phaser 3.60 you can use this method to add an atlas data set to an existing Phaser Texture. * * @method Phaser.Textures.TextureManager#addUnityAtlas * @fires Phaser.Textures.Events#ADD * @since 3.0.0 * * @param {string} key - The unique string-based key of the Texture. * @param {HTMLImageElement} source - The source Image element. * @param {object} data - The Texture Atlas data. * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. * * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. */ addUnityAtlas: function (key, source, data, dataSource) { var texture = null; if (source instanceof Texture) { key = source.key; texture = source; } else if (this.checkKey(key)) { texture = this.create(key, source); } if (texture) { Parser.UnityYAML(texture, 0, data); if (dataSource) { texture.setDataSource(dataSource); } this.emit(Events.ADD, key, texture); this.emit(Events.ADD_KEY + key, texture); } return texture; }, /** * Adds a Sprite Sheet to this Texture Manager. * * In Phaser terminology a Sprite Sheet is a texture containing different frames, but each frame is the exact * same size and cannot be trimmed or rotated. This is different to a Texture Atlas, created by tools such as * Texture Packer, and more akin with the fixed-frame exports you get from apps like Aseprite or old arcade * games. * * As of Phaser 3.60 you can use this method to add a sprite sheet to an existing Phaser Texture. * * @method Phaser.Textures.TextureManager#addSpriteSheet * @fires Phaser.Textures.Events#ADD * @since 3.0.0 * * @param {string} key - The unique string-based key of the Texture. Give an empty string if you provide a Phaser Texture as the 2nd argument. * @param {(HTMLImageElement|Phaser.Textures.Texture)} source - The source Image element, or a Phaser Texture. * @param {Phaser.Types.Textures.SpriteSheetConfig} config - The configuration object for this Sprite Sheet. * @param {HTMLImageElement|HTMLCanvasElement} [dataSource] - An optional data Image element. * * @return {?Phaser.Textures.Texture} The Texture that was created or updated, or `null` if the key is already in use. */ addSpriteSheet: function (key, source, config, dataSource) { var texture = null; if (source instanceof Texture) { key = source.key; texture = source; } else if (this.checkKey(key)) { texture = this.create(key, source); } if (texture) { var width = texture.source[0].width; var height = texture.source[0].height; Parser.SpriteSheet(texture, 0, 0, 0, width, height, config); if (dataSource) { texture.setDataSource(dataSource); } this.emit(Events.ADD, key, texture); this.emit(Events.ADD_KEY + key, texture); } return texture; }, /** * Adds a Sprite Sheet to this Texture Manager, where the Sprite Sheet exists as a Frame within a Texture Atlas. * * In Phaser terminology a Sprite Sheet is a texture containing different frames, but each frame is the exact * same size and cannot be trimmed or rotated. * * @method Phaser.Textures.TextureManager#addSpriteSheetFromAtlas * @fires Phaser.Textures.Events#ADD * @since 3.0.0 * * @param {string} key - The unique string-based key of the Texture. * @param {Phaser.Types.Textures.SpriteSheetFromAtlasConfig} config - The configuration object for this Sprite Sheet. * * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. */ addSpriteSheetFromAtlas: function (key, config) { if (!this.checkKey(key)) { return null; } var atlasKey = GetValue(config, 'atlas', null); var atlasFrame = GetValue(config, 'frame', null); if (!atlasKey || !atlasFrame) { return; } var atlas = this.get(atlasKey); var sheet = atlas.get(atlasFrame); if (sheet) { var source = sheet.source.image; if (!source) { source = sheet.source.glTexture; } var texture = this.create(key, source); if (sheet.trimmed) { // If trimmed we need to help the parser adjust Parser.SpriteSheetFromAtlas(texture, sheet, config); } else { Parser.SpriteSheet(texture, 0, sheet.cutX, sheet.cutY, sheet.cutWidth, sheet.cutHeight, config); } this.emit(Events.ADD, key, texture); this.emit(Events.ADD_KEY + key, texture); return texture; } }, /** * Creates a texture from an array of colour data. * * This is only available in WebGL mode. * * If the dimensions provided are powers of two, the resulting texture * will be automatically set to wrap by the WebGL Renderer. * * @method Phaser.Textures.TextureManager#addUint8Array * @fires Phaser.Textures.Events#ADD * @since 3.80.0 * * @param {string} key - The unique string-based key of the Texture. * @param {Uint8Array} data - The color data for the texture. * @param {number} width - The width of the texture. * @param {number} height - The height of the texture. * * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. */ addUint8Array: function (key, data, width, height) { if ( !this.checkKey(key) || data.length / 4 !== width * height ) { return null; } var texture = this.create(key, data, width, height); texture.add('__BASE', 0, 0, 0, width, height); this.emit(Events.ADD, key, texture); this.emit(Events.ADD_KEY + key, texture); return texture; }, /** * Creates a texture from a color and alpha. * The texture will be filled with the given color and alpha. * * This may be used as a proxy texture, * which can later be replaced with a real texture. * See {@link Phaser.Textures.Texture#setSource} * for more information on replacing the proxy with a real texture. * * This is only available in WebGL mode. * * @method Phaser.Textures.TextureManager#addFlatColor * @fires Phaser.Textures.Events#ADD * @since 4.0.0 * @webglonly * * @param {string} key - The unique string-based key of the Texture. * @param {number} width - The width of the texture. * @param {number} height - The height of the texture. * @param {number} [color=0x000000] - The color of the texture. * @param {number} [alpha=0] - The alpha of the texture. * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use or the width or height is not positive. */ addFlatColor: function (key, width, height, color, alpha) { if ( !this.checkKey(key) || width <= 0 || height <= 0 ) { return null; } if (color === undefined) { color = 0x000000; } if (alpha === undefined) { alpha = 0; } var col = IntegerToColor(color); var r = col.red; var g = col.green; var b = col.blue; var data = new Uint8Array(width * height * 4); for (var i = 0; i < width * height; i++) { data[i * 4] = r; data[i * 4 + 1] = g; data[i * 4 + 2] = b; data[i * 4 + 3] = alpha * 255; } return this.addUint8Array(key, data, width, height); }, /** * Creates a new Texture using the given source and dimensions. * * @method Phaser.Textures.TextureManager#create * @since 3.0.0 * * @param {string} key - The unique string-based key of the Texture. * @param {Phaser.Types.Textures.TextureSource | Phaser.Types.Textures.TextureSource[]} source - A source or array of sources that are used to create the texture. Usually Images, but can also be a Canvas or other types. * @param {number} [width] - The width of the Texture. This is optional and automatically derived from the source images. * @param {number} [height] - The height of the Texture. This is optional and automatically derived from the source images. * * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. */ create: function (key, source, width, height) { var texture = null; if (this.checkKey(key)) { texture = new Texture(this, key, source, width, height); this.list[key] = texture; } return texture; }, /** * Checks the given key to see if a Texture using it exists within this Texture Manager. * * @method Phaser.Textures.TextureManager#exists * @since 3.0.0 * * @param {string} key - The unique string-based key of the Texture. * * @return {boolean} Returns `true` if a Texture matching the given key exists in this Texture Manager. */ exists: function (key) { return (this.list.hasOwnProperty(key)); }, /** * Returns a Texture from the Texture Manager that matches the given key. * * If the key is `undefined` it will return the `__DEFAULT` Texture. * * If the key is an instance of a Texture, it will return the instance. * * If the key is an instance of a Frame, it will return the frames parent Texture instance. * * Finally, if the key is given, but not found, and not a Texture or Frame instance, it will return the `__MISSING` Texture. * * @method Phaser.Textures.TextureManager#get * @since 3.0.0 * * @param {(string|Phaser.Textures.Texture|Phaser.Textures.Frame)} key - The unique string-based key of the Texture, or a Texture, or Frame instance. * * @return {Phaser.Textures.Texture} The Texture matching the given key. */ get: function (key) { if (key === undefined) { key = '__DEFAULT'; } if (this.list[key]) { return this.list[key]; } else if (key instanceof Texture) { return key; } else if (key instanceof Frame) { return key.texture; } else { return this.list['__MISSING']; } }, /** * Takes a Texture key and Frame name and returns a clone of that Frame if found. * * @method Phaser.Textures.TextureManager#cloneFrame * @since 3.0.0 * * @param {string} key - The unique string-based key of the Texture. * @param {(string|number)} frame - The string or index of the Frame to be cloned. * * @return {Phaser.Textures.Frame} A Clone of the given Frame. */ cloneFrame: function (key, frame) { if (this.list[key]) { return this.list[key].get(frame).clone(); } }, /** * Takes a Texture key and Frame name and returns a reference to that Frame, if found. * * @method Phaser.Textures.TextureManager#getFrame * @since 3.0.0 * * @param {string} key - The unique string-based key of the Texture. * @param {(string|number)} [frame] - The string-based name, or integer based index, of the Frame to get from the Texture. * * @return {Phaser.Textures.Frame} A Texture Frame object. */ getFrame: function (key, frame) { if (this.list[key]) { return this.list[key].get(frame); } }, /** * Parses the 'key' parameter and returns a Texture Frame instance. * * It can accept the following formats: * * 1) A string * 2) An array where the elements are: [ key, [frame] ] * 3) An object with the properties: { key, [frame] } * 4) A Texture instance - which returns the default frame from the Texture * 5) A Frame instance - returns itself * * @method Phaser.Textures.TextureManager#parseFrame * @since 3.60.0 * * @param {(string|array|object|Phaser.Textures.Texture|Phaser.Textures.Frame)} key - The key to be parsed. * * @return {Phaser.Textures.Frame} A Texture Frame object, if found, or undefined if not.