2013-08-28 06:02:55 +00:00
|
|
|
/**
|
2013-10-01 12:54:29 +00:00
|
|
|
* @author Richard Davey <rich@photonstorm.com>
|
2014-02-05 05:54:25 +00:00
|
|
|
* @copyright 2014 Photon Storm Ltd.
|
2013-10-01 12:54:29 +00:00
|
|
|
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
2013-08-28 06:02:55 +00:00
|
|
|
*/
|
|
|
|
|
2013-08-29 06:06:16 +00:00
|
|
|
/**
|
2014-09-16 16:35:08 +00:00
|
|
|
* This is where the magic happens. The Game object is the heart of your game,
|
2013-10-01 12:54:29 +00:00
|
|
|
* providing quick access to common functions and handling the boot process.
|
2014-11-21 10:40:18 +00:00
|
|
|
*
|
2013-10-31 05:31:54 +00:00
|
|
|
* "Hell, there are no rules here - we're trying to accomplish something."
|
2013-10-01 12:54:29 +00:00
|
|
|
* Thomas A. Edison
|
2014-09-16 16:35:08 +00:00
|
|
|
*
|
|
|
|
* @class Phaser.Game
|
2013-08-29 06:06:16 +00:00
|
|
|
* @constructor
|
2014-08-31 00:57:50 +00:00
|
|
|
* @param {number|string} [width=800] - The width of your game in game pixels. If given as a string the value must be between 0 and 100 and will be used as the percentage width of the parent container, or the browser window if no parent is given.
|
|
|
|
* @param {number|string} [height=600] - The height of your game in game pixels. If given as a string the value must be between 0 and 100 and will be used as the percentage height of the parent container, or the browser window if no parent is given.
|
2013-11-25 14:53:30 +00:00
|
|
|
* @param {number} [renderer=Phaser.AUTO] - Which renderer to use: Phaser.AUTO will auto-detect, Phaser.WEBGL, Phaser.CANVAS or Phaser.HEADLESS (no rendering at all).
|
2013-12-10 12:23:42 +00:00
|
|
|
* @param {string|HTMLElement} [parent=''] - The DOM element into which this games canvas will be injected. Either a DOM ID (string) or the element itself.
|
|
|
|
* @param {object} [state=null] - The default state object. A object consisting of Phaser.State functions (preload, create, update, render) or null.
|
2013-10-31 05:31:54 +00:00
|
|
|
* @param {boolean} [transparent=false] - Use a transparent canvas background or not.
|
2014-09-16 16:35:08 +00:00
|
|
|
* @param {boolean} [antialias=true] - Draw all image textures anti-aliased or not. The default is for smooth textures, but disable if your game features pixel art.
|
2014-02-19 03:51:48 +00:00
|
|
|
* @param {object} [physicsConfig=null] - A physics configuration object to pass to the Physics world on creation.
|
2013-08-29 06:06:16 +00:00
|
|
|
*/
|
2014-02-19 03:51:48 +00:00
|
|
|
Phaser.Game = function (width, height, renderer, parent, state, transparent, antialias, physicsConfig) {
|
2013-08-28 06:02:55 +00:00
|
|
|
|
2013-11-25 03:13:04 +00:00
|
|
|
/**
|
|
|
|
* @property {number} id - Phaser Game ID (for when Pixi supports multiple instances).
|
2014-11-29 19:40:35 +00:00
|
|
|
* @readonly
|
2013-11-25 03:13:04 +00:00
|
|
|
*/
|
|
|
|
this.id = Phaser.GAMES.push(this) - 1;
|
|
|
|
|
2013-12-24 03:18:55 +00:00
|
|
|
/**
|
|
|
|
* @property {object} config - The Phaser.Game configuration object.
|
|
|
|
*/
|
|
|
|
this.config = null;
|
|
|
|
|
2014-02-19 03:51:48 +00:00
|
|
|
/**
|
|
|
|
* @property {object} physicsConfig - The Phaser.Physics.World configuration object.
|
|
|
|
*/
|
|
|
|
this.physicsConfig = physicsConfig;
|
|
|
|
|
2013-11-25 03:13:04 +00:00
|
|
|
/**
|
2014-04-07 11:01:51 +00:00
|
|
|
* @property {string|HTMLElement} parent - The Games DOM parent.
|
2013-12-24 03:18:55 +00:00
|
|
|
* @default
|
2013-11-25 03:13:04 +00:00
|
|
|
*/
|
2013-12-24 03:18:55 +00:00
|
|
|
this.parent = '';
|
2013-11-25 03:13:04 +00:00
|
|
|
|
|
|
|
/**
|
2014-11-08 09:13:25 +00:00
|
|
|
* The current Game Width in pixels.
|
2014-11-08 07:24:57 +00:00
|
|
|
*
|
2014-11-08 09:13:25 +00:00
|
|
|
* _Do not modify this property directly:_ use {@link Phaser.ScaleManager#setGameSize} - eg. `game.scale.setGameSize(width, height)` - instead.
|
|
|
|
*
|
|
|
|
* @property {integer} width
|
2014-11-08 07:24:57 +00:00
|
|
|
* @readonly
|
2013-12-24 03:18:55 +00:00
|
|
|
* @default
|
2013-11-25 03:13:04 +00:00
|
|
|
*/
|
2013-12-24 03:18:55 +00:00
|
|
|
this.width = 800;
|
2013-11-25 03:13:04 +00:00
|
|
|
|
|
|
|
/**
|
2014-11-08 09:13:25 +00:00
|
|
|
* The current Game Height in pixels.
|
|
|
|
*
|
|
|
|
* _Do not modify this property directly:_ use {@link Phaser.ScaleManager#setGameSize} - eg. `game.scale.setGameSize(width, height)` - instead.
|
2014-11-08 07:24:57 +00:00
|
|
|
*
|
2014-11-08 09:13:25 +00:00
|
|
|
* @property {integer} height
|
2014-11-08 07:24:57 +00:00
|
|
|
* @readonly
|
2013-12-24 03:18:55 +00:00
|
|
|
* @default
|
2013-11-25 03:13:04 +00:00
|
|
|
*/
|
2013-12-24 03:18:55 +00:00
|
|
|
this.height = 600;
|
2013-11-25 03:13:04 +00:00
|
|
|
|
2014-11-08 18:52:02 +00:00
|
|
|
/**
|
|
|
|
* @property {integer} _width - Private internal var.
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this._width = 800;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {integer} _height - Private internal var.
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this._height = 600;
|
|
|
|
|
2013-11-25 03:13:04 +00:00
|
|
|
/**
|
|
|
|
* @property {boolean} transparent - Use a transparent canvas background or not.
|
2013-12-24 03:18:55 +00:00
|
|
|
* @default
|
2013-11-25 03:13:04 +00:00
|
|
|
*/
|
2013-12-24 03:18:55 +00:00
|
|
|
this.transparent = false;
|
2013-11-25 03:13:04 +00:00
|
|
|
|
|
|
|
/**
|
2014-02-27 21:56:47 +00:00
|
|
|
* @property {boolean} antialias - Anti-alias graphics. By default scaled images are smoothed in Canvas and WebGL, set anti-alias to false to disable this globally.
|
2013-12-24 03:18:55 +00:00
|
|
|
* @default
|
2013-11-25 03:13:04 +00:00
|
|
|
*/
|
2013-12-24 03:18:55 +00:00
|
|
|
this.antialias = true;
|
2013-11-25 03:13:04 +00:00
|
|
|
|
2014-07-10 09:28:23 +00:00
|
|
|
/**
|
|
|
|
* @property {boolean} preserveDrawingBuffer - The value of the preserveDrawingBuffer flag affects whether or not the contents of the stencil buffer is retained after rendering.
|
|
|
|
* @default
|
|
|
|
*/
|
|
|
|
this.preserveDrawingBuffer = false;
|
|
|
|
|
2013-11-25 03:13:04 +00:00
|
|
|
/**
|
2014-04-07 11:01:51 +00:00
|
|
|
* @property {PIXI.CanvasRenderer|PIXI.WebGLRenderer} renderer - The Pixi Renderer.
|
2014-11-29 19:40:35 +00:00
|
|
|
* @protected
|
2013-11-25 03:13:04 +00:00
|
|
|
*/
|
2014-04-07 11:01:51 +00:00
|
|
|
this.renderer = null;
|
2013-12-24 03:18:55 +00:00
|
|
|
|
|
|
|
/**
|
2014-02-24 00:35:11 +00:00
|
|
|
* @property {number} renderType - The Renderer this game will use. Either Phaser.AUTO, Phaser.CANVAS or Phaser.WEBGL.
|
2014-11-29 19:40:35 +00:00
|
|
|
* @readonly
|
2013-12-24 03:18:55 +00:00
|
|
|
*/
|
|
|
|
this.renderType = Phaser.AUTO;
|
2013-11-25 03:13:04 +00:00
|
|
|
|
|
|
|
/**
|
2014-04-07 11:01:51 +00:00
|
|
|
* @property {Phaser.StateManager} state - The StateManager.
|
2013-11-25 03:13:04 +00:00
|
|
|
*/
|
2013-12-24 03:18:55 +00:00
|
|
|
this.state = null;
|
2013-11-25 03:13:04 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {boolean} isBooted - Whether the game engine is booted, aka available.
|
2014-11-29 19:40:35 +00:00
|
|
|
* @readonly
|
2013-11-25 03:13:04 +00:00
|
|
|
*/
|
|
|
|
this.isBooted = false;
|
|
|
|
|
|
|
|
/**
|
2014-11-30 12:05:23 +00:00
|
|
|
* @property {boolean} isRunning - Is game running or paused?
|
2014-11-29 19:40:35 +00:00
|
|
|
* @readonly
|
2013-11-25 03:13:04 +00:00
|
|
|
*/
|
|
|
|
this.isRunning = false;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {Phaser.RequestAnimationFrame} raf - Automatically handles the core game loop via requestAnimationFrame or setTimeout
|
2014-11-29 19:40:35 +00:00
|
|
|
* @protected
|
2013-11-25 03:13:04 +00:00
|
|
|
*/
|
|
|
|
this.raf = null;
|
|
|
|
|
|
|
|
/**
|
2014-02-21 14:50:18 +00:00
|
|
|
* @property {Phaser.GameObjectFactory} add - Reference to the Phaser.GameObjectFactory.
|
2013-11-25 03:13:04 +00:00
|
|
|
*/
|
2013-09-10 22:51:35 +00:00
|
|
|
this.add = null;
|
2013-08-29 02:52:59 +00:00
|
|
|
|
2014-02-21 14:50:18 +00:00
|
|
|
/**
|
|
|
|
* @property {Phaser.GameObjectCreator} make - Reference to the GameObject Creator.
|
|
|
|
*/
|
|
|
|
this.make = null;
|
|
|
|
|
2013-08-29 02:52:59 +00:00
|
|
|
/**
|
2013-11-25 03:13:04 +00:00
|
|
|
* @property {Phaser.Cache} cache - Reference to the assets cache.
|
|
|
|
*/
|
2013-09-10 22:51:35 +00:00
|
|
|
this.cache = null;
|
2013-08-29 02:52:59 +00:00
|
|
|
|
|
|
|
/**
|
2013-11-25 03:13:04 +00:00
|
|
|
* @property {Phaser.Input} input - Reference to the input manager
|
|
|
|
*/
|
2013-09-10 22:51:35 +00:00
|
|
|
this.input = null;
|
2013-08-29 02:52:59 +00:00
|
|
|
|
|
|
|
/**
|
2013-11-25 03:13:04 +00:00
|
|
|
* @property {Phaser.Loader} load - Reference to the assets loader.
|
|
|
|
*/
|
2013-09-10 22:51:35 +00:00
|
|
|
this.load = null;
|
2013-08-29 02:52:59 +00:00
|
|
|
|
|
|
|
/**
|
2013-11-25 03:13:04 +00:00
|
|
|
* @property {Phaser.Math} math - Reference to the math helper.
|
|
|
|
*/
|
2013-09-10 22:51:35 +00:00
|
|
|
this.math = null;
|
2013-08-29 02:52:59 +00:00
|
|
|
|
|
|
|
/**
|
2013-11-25 03:13:04 +00:00
|
|
|
* @property {Phaser.Net} net - Reference to the network class.
|
|
|
|
*/
|
2013-09-10 22:51:35 +00:00
|
|
|
this.net = null;
|
2013-08-29 02:52:59 +00:00
|
|
|
|
2014-02-13 12:50:10 +00:00
|
|
|
/**
|
2014-02-25 14:46:48 +00:00
|
|
|
* @property {Phaser.ScaleManager} scale - The game scale manager.
|
2014-02-13 12:50:10 +00:00
|
|
|
*/
|
|
|
|
this.scale = null;
|
|
|
|
|
2013-08-29 02:52:59 +00:00
|
|
|
/**
|
2013-11-25 03:13:04 +00:00
|
|
|
* @property {Phaser.SoundManager} sound - Reference to the sound manager.
|
|
|
|
*/
|
2013-09-10 22:51:35 +00:00
|
|
|
this.sound = null;
|
2013-08-29 02:52:59 +00:00
|
|
|
|
|
|
|
/**
|
2013-11-25 03:13:04 +00:00
|
|
|
* @property {Phaser.Stage} stage - Reference to the stage.
|
|
|
|
*/
|
2013-09-10 22:51:35 +00:00
|
|
|
this.stage = null;
|
2013-08-29 02:52:59 +00:00
|
|
|
|
|
|
|
/**
|
2014-04-02 09:40:38 +00:00
|
|
|
* @property {Phaser.Time} time - Reference to the core game clock.
|
2013-11-25 03:13:04 +00:00
|
|
|
*/
|
2013-09-10 22:51:35 +00:00
|
|
|
this.time = null;
|
2013-08-29 02:52:59 +00:00
|
|
|
|
|
|
|
/**
|
2013-11-25 03:13:04 +00:00
|
|
|
* @property {Phaser.TweenManager} tweens - Reference to the tween manager.
|
|
|
|
*/
|
2013-09-10 22:51:35 +00:00
|
|
|
this.tweens = null;
|
2013-08-29 02:52:59 +00:00
|
|
|
|
|
|
|
/**
|
2013-11-25 03:13:04 +00:00
|
|
|
* @property {Phaser.World} world - Reference to the world.
|
|
|
|
*/
|
2013-09-10 22:51:35 +00:00
|
|
|
this.world = null;
|
2013-08-29 02:52:59 +00:00
|
|
|
|
|
|
|
/**
|
2014-03-05 02:36:08 +00:00
|
|
|
* @property {Phaser.Physics} physics - Reference to the physics manager.
|
2013-11-25 03:13:04 +00:00
|
|
|
*/
|
2013-09-10 22:51:35 +00:00
|
|
|
this.physics = null;
|
2015-01-29 22:51:38 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {Phaser.PluginManager} plugins - Reference to the plugin manager.
|
|
|
|
*/
|
|
|
|
this.plugins = null;
|
2013-08-29 02:52:59 +00:00
|
|
|
|
|
|
|
/**
|
2013-11-25 03:13:04 +00:00
|
|
|
* @property {Phaser.RandomDataGenerator} rnd - Instance of repeatable random data generator helper.
|
|
|
|
*/
|
2013-09-10 22:51:35 +00:00
|
|
|
this.rnd = null;
|
2013-08-29 02:52:59 +00:00
|
|
|
|
|
|
|
/**
|
2013-11-25 03:13:04 +00:00
|
|
|
* @property {Phaser.Device} device - Contains device information and capabilities.
|
|
|
|
*/
|
2014-11-14 02:06:45 +00:00
|
|
|
this.device = Phaser.Device;
|
2013-08-29 02:52:59 +00:00
|
|
|
|
2013-10-01 12:54:29 +00:00
|
|
|
/**
|
2014-04-07 11:01:51 +00:00
|
|
|
* @property {Phaser.Camera} camera - A handy reference to world.camera.
|
2013-11-25 03:13:04 +00:00
|
|
|
*/
|
|
|
|
this.camera = null;
|
2013-08-31 20:50:34 +00:00
|
|
|
|
2014-02-13 12:50:10 +00:00
|
|
|
/**
|
|
|
|
* @property {HTMLCanvasElement} canvas - A handy reference to renderer.view, the canvas that the game is being rendered in to.
|
2013-11-25 03:13:04 +00:00
|
|
|
*/
|
|
|
|
this.canvas = null;
|
2013-08-31 20:50:34 +00:00
|
|
|
|
2013-11-25 03:13:04 +00:00
|
|
|
/**
|
2014-03-03 13:43:33 +00:00
|
|
|
* @property {CanvasRenderingContext2D} context - A handy reference to renderer.context (only set for CANVAS games, not WebGL)
|
2013-11-25 03:13:04 +00:00
|
|
|
*/
|
|
|
|
this.context = null;
|
2013-08-31 20:50:34 +00:00
|
|
|
|
2013-10-01 12:54:29 +00:00
|
|
|
/**
|
2013-11-25 03:13:04 +00:00
|
|
|
* @property {Phaser.Utils.Debug} debug - A set of useful debug utilitie.
|
|
|
|
*/
|
|
|
|
this.debug = null;
|
2013-08-31 20:50:34 +00:00
|
|
|
|
2013-11-25 03:13:04 +00:00
|
|
|
/**
|
|
|
|
* @property {Phaser.Particles} particles - The Particle Manager.
|
|
|
|
*/
|
|
|
|
this.particles = null;
|
2013-09-10 22:51:35 +00:00
|
|
|
|
2014-12-02 09:03:06 +00:00
|
|
|
/**
|
|
|
|
* If `false` Phaser will automatically render the display list every update. If `true` the render loop will be skipped.
|
|
|
|
* You can toggle this value at run-time to gain exact control over when Phaser renders. This can be useful in certain types of game or application.
|
|
|
|
* Please note that if you don't render the display list then none of the game object transforms will be updated, so use this value carefully.
|
|
|
|
* @property {boolean} lockRender
|
|
|
|
* @default
|
|
|
|
*/
|
|
|
|
this.lockRender = false;
|
|
|
|
|
2014-01-31 05:42:20 +00:00
|
|
|
/**
|
|
|
|
* @property {boolean} stepping - Enable core loop stepping with Game.enableStep().
|
|
|
|
* @default
|
|
|
|
* @readonly
|
|
|
|
*/
|
|
|
|
this.stepping = false;
|
|
|
|
|
|
|
|
/**
|
2014-04-07 11:01:51 +00:00
|
|
|
* @property {boolean} pendingStep - An internal property used by enableStep, but also useful to query from your own game objects.
|
2014-01-31 05:42:20 +00:00
|
|
|
* @default
|
|
|
|
* @readonly
|
|
|
|
*/
|
|
|
|
this.pendingStep = false;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {number} stepCount - When stepping is enabled this contains the current step cycle.
|
|
|
|
* @default
|
|
|
|
* @readonly
|
|
|
|
*/
|
|
|
|
this.stepCount = 0;
|
|
|
|
|
2014-03-12 21:19:00 +00:00
|
|
|
/**
|
|
|
|
* @property {Phaser.Signal} onPause - This event is fired when the game pauses.
|
|
|
|
*/
|
|
|
|
this.onPause = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {Phaser.Signal} onResume - This event is fired when the game resumes from a paused state.
|
|
|
|
*/
|
|
|
|
this.onResume = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {Phaser.Signal} onBlur - This event is fired when the game no longer has focus (typically on page hide).
|
|
|
|
*/
|
|
|
|
this.onBlur = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {Phaser.Signal} onFocus - This event is fired when the game has focus (typically on page show).
|
|
|
|
*/
|
|
|
|
this.onFocus = null;
|
|
|
|
|
2014-02-25 02:59:24 +00:00
|
|
|
/**
|
|
|
|
* @property {boolean} _paused - Is game paused?
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this._paused = false;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {boolean} _codePaused - Was the game paused via code or a visibility change?
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this._codePaused = false;
|
|
|
|
|
2014-11-25 08:56:23 +00:00
|
|
|
/**
|
2014-11-29 06:54:30 +00:00
|
|
|
* The ID of the current/last logic update applied this render frame, starting from 0.
|
2014-11-25 08:56:23 +00:00
|
|
|
*
|
2014-11-29 06:54:30 +00:00
|
|
|
* The first update is `currentUpdateID === 0` and the last update is `currentUpdateID === updatesThisFrame.`
|
|
|
|
* @property {integer} currentUpdateID
|
2014-11-25 08:56:23 +00:00
|
|
|
* @protected
|
|
|
|
*/
|
2014-11-29 06:54:30 +00:00
|
|
|
this.currentUpdateID = 0;
|
2014-11-25 08:56:23 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Number of logic updates expected to occur this render frame;
|
|
|
|
* will be 1 unless there are catch-ups required (and allowed).
|
|
|
|
* @property {integer} updatesThisFrame
|
|
|
|
* @protected
|
|
|
|
*/
|
|
|
|
this.updatesThisFrame = 1;
|
|
|
|
|
2014-11-08 18:52:02 +00:00
|
|
|
/**
|
|
|
|
* @property {number} _deltaTime - accumulate elapsed time until a logic update is due
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this._deltaTime = 0;
|
|
|
|
|
2014-11-25 02:50:39 +00:00
|
|
|
/**
|
2014-11-25 08:56:23 +00:00
|
|
|
* @property {number} _lastCount - remember how many 'catch-up' iterations were used on the logicUpdate last frame
|
|
|
|
* @private
|
|
|
|
*/
|
2014-11-08 18:52:02 +00:00
|
|
|
this._lastCount = 0;
|
|
|
|
|
|
|
|
/**
|
2014-11-25 08:56:23 +00:00
|
|
|
* @property {number} _spiralling - if the 'catch-up' iterations are spiralling out of control, this counter is incremented
|
|
|
|
* @private
|
|
|
|
*/
|
2014-11-08 18:52:02 +00:00
|
|
|
this._spiralling = 0;
|
|
|
|
|
|
|
|
/**
|
2014-11-25 08:56:23 +00:00
|
|
|
* If the game is struggling to maintain the desired FPS, this signal will be dispatched.
|
|
|
|
* The desired/chosen FPS should probably be closer to the {@link Phaser.Time#suggestedFps} value.
|
|
|
|
* @property {Phaser.Signal} fpsProblemNotifier
|
|
|
|
* @public
|
|
|
|
*/
|
2014-11-08 18:52:02 +00:00
|
|
|
this.fpsProblemNotifier = new Phaser.Signal();
|
|
|
|
|
2014-11-11 05:51:47 +00:00
|
|
|
/**
|
2014-11-25 08:56:23 +00:00
|
|
|
* @property {boolean} forceSingleUpdate - Should the game loop force a logic update, regardless of the delta timer? Set to true if you know you need this. You can toggle it on the fly.
|
|
|
|
*/
|
2014-11-11 05:51:47 +00:00
|
|
|
this.forceSingleUpdate = false;
|
|
|
|
|
2014-11-08 18:52:02 +00:00
|
|
|
/**
|
2014-11-25 08:56:23 +00:00
|
|
|
* @property {number} _nextNotification - the soonest game.time.time value that the next fpsProblemNotifier can be dispatched
|
|
|
|
* @private
|
|
|
|
*/
|
2014-11-08 18:52:02 +00:00
|
|
|
this._nextFpsNotification = 0;
|
2014-08-31 00:57:50 +00:00
|
|
|
|
2013-12-24 03:18:55 +00:00
|
|
|
// Parse the configuration object (if any)
|
|
|
|
if (arguments.length === 1 && typeof arguments[0] === 'object')
|
|
|
|
{
|
|
|
|
this.parseConfig(arguments[0]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-07-10 09:45:43 +00:00
|
|
|
this.config = { enableDebug: true };
|
2014-05-30 04:33:30 +00:00
|
|
|
|
2013-12-24 03:18:55 +00:00
|
|
|
if (typeof width !== 'undefined')
|
|
|
|
{
|
2014-08-31 00:57:50 +00:00
|
|
|
this._width = width;
|
2013-12-24 03:18:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof height !== 'undefined')
|
|
|
|
{
|
2014-08-31 00:57:50 +00:00
|
|
|
this._height = height;
|
2013-12-24 03:18:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof renderer !== 'undefined')
|
|
|
|
{
|
|
|
|
this.renderType = renderer;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof parent !== 'undefined')
|
|
|
|
{
|
|
|
|
this.parent = parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof transparent !== 'undefined')
|
|
|
|
{
|
|
|
|
this.transparent = transparent;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof antialias !== 'undefined')
|
|
|
|
{
|
|
|
|
this.antialias = antialias;
|
|
|
|
}
|
|
|
|
|
2014-03-12 13:53:30 +00:00
|
|
|
this.rnd = new Phaser.RandomDataGenerator([(Date.now() * Math.random()).toString()]);
|
|
|
|
|
2013-12-24 03:18:55 +00:00
|
|
|
this.state = new Phaser.StateManager(this, state);
|
|
|
|
}
|
|
|
|
|
2014-11-14 02:06:45 +00:00
|
|
|
this.device.whenReady(this.boot, this);
|
2013-09-10 22:51:35 +00:00
|
|
|
|
2013-11-25 03:13:04 +00:00
|
|
|
return this;
|
2013-09-10 22:51:35 +00:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
Phaser.Game.prototype = {
|
2013-09-10 00:26:50 +00:00
|
|
|
|
2013-12-24 03:18:55 +00:00
|
|
|
/**
|
|
|
|
* Parses a Game configuration object.
|
|
|
|
*
|
|
|
|
* @method Phaser.Game#parseConfig
|
|
|
|
* @protected
|
|
|
|
*/
|
|
|
|
parseConfig: function (config) {
|
|
|
|
|
|
|
|
this.config = config;
|
|
|
|
|
2014-08-28 03:19:10 +00:00
|
|
|
if (typeof config['enableDebug'] === 'undefined')
|
|
|
|
{
|
|
|
|
this.config.enableDebug = true;
|
|
|
|
}
|
|
|
|
|
2013-12-24 03:18:55 +00:00
|
|
|
if (config['width'])
|
|
|
|
{
|
2014-08-31 00:57:50 +00:00
|
|
|
this._width = config['width'];
|
2013-12-24 03:18:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (config['height'])
|
|
|
|
{
|
2014-08-31 00:57:50 +00:00
|
|
|
this._height = config['height'];
|
2013-12-24 03:18:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (config['renderer'])
|
|
|
|
{
|
|
|
|
this.renderType = config['renderer'];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (config['parent'])
|
|
|
|
{
|
|
|
|
this.parent = config['parent'];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (config['transparent'])
|
|
|
|
{
|
|
|
|
this.transparent = config['transparent'];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (config['antialias'])
|
|
|
|
{
|
|
|
|
this.antialias = config['antialias'];
|
|
|
|
}
|
|
|
|
|
2014-07-10 09:28:23 +00:00
|
|
|
if (config['preserveDrawingBuffer'])
|
|
|
|
{
|
|
|
|
this.preserveDrawingBuffer = config['preserveDrawingBuffer'];
|
|
|
|
}
|
|
|
|
|
2014-02-19 03:51:48 +00:00
|
|
|
if (config['physicsConfig'])
|
|
|
|
{
|
|
|
|
this.physicsConfig = config['physicsConfig'];
|
|
|
|
}
|
|
|
|
|
2014-03-21 09:51:33 +00:00
|
|
|
var seed = [(Date.now() * Math.random()).toString()];
|
|
|
|
|
2014-03-12 13:53:30 +00:00
|
|
|
if (config['seed'])
|
|
|
|
{
|
2014-03-21 09:51:33 +00:00
|
|
|
seed = config['seed'];
|
2014-03-12 13:53:30 +00:00
|
|
|
}
|
|
|
|
|
2014-03-21 09:51:33 +00:00
|
|
|
this.rnd = new Phaser.RandomDataGenerator(seed);
|
|
|
|
|
2013-12-24 03:18:55 +00:00
|
|
|
var state = null;
|
|
|
|
|
|
|
|
if (config['state'])
|
|
|
|
{
|
|
|
|
state = config['state'];
|
|
|
|
}
|
|
|
|
|
|
|
|
this.state = new Phaser.StateManager(this, state);
|
|
|
|
|
|
|
|
},
|
|
|
|
|
2013-11-25 03:13:04 +00:00
|
|
|
/**
|
|
|
|
* Initialize engine sub modules and start the game.
|
|
|
|
*
|
|
|
|
* @method Phaser.Game#boot
|
|
|
|
* @protected
|
|
|
|
*/
|
|
|
|
boot: function () {
|
|
|
|
|
|
|
|
if (this.isBooted)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-11-14 02:06:45 +00:00
|
|
|
this.onPause = new Phaser.Signal();
|
|
|
|
this.onResume = new Phaser.Signal();
|
|
|
|
this.onBlur = new Phaser.Signal();
|
|
|
|
this.onFocus = new Phaser.Signal();
|
|
|
|
|
|
|
|
this.isBooted = true;
|
|
|
|
|
|
|
|
this.math = Phaser.Math;
|
|
|
|
|
|
|
|
this.scale = new Phaser.ScaleManager(this, this._width, this._height);
|
|
|
|
this.stage = new Phaser.Stage(this);
|
|
|
|
|
|
|
|
this.setUpRenderer();
|
|
|
|
|
|
|
|
this.world = new Phaser.World(this);
|
|
|
|
this.add = new Phaser.GameObjectFactory(this);
|
|
|
|
this.make = new Phaser.GameObjectCreator(this);
|
|
|
|
this.cache = new Phaser.Cache(this);
|
|
|
|
this.load = new Phaser.Loader(this);
|
|
|
|
this.time = new Phaser.Time(this);
|
|
|
|
this.tweens = new Phaser.TweenManager(this);
|
|
|
|
this.input = new Phaser.Input(this);
|
|
|
|
this.sound = new Phaser.SoundManager(this);
|
|
|
|
this.physics = new Phaser.Physics(this, this.physicsConfig);
|
|
|
|
this.particles = new Phaser.Particles(this);
|
|
|
|
this.plugins = new Phaser.PluginManager(this);
|
|
|
|
this.net = new Phaser.Net(this);
|
|
|
|
|
|
|
|
this.time.boot();
|
|
|
|
this.stage.boot();
|
|
|
|
this.world.boot();
|
|
|
|
this.scale.boot();
|
|
|
|
this.input.boot();
|
|
|
|
this.sound.boot();
|
|
|
|
this.state.boot();
|
|
|
|
|
|
|
|
if (this.config['enableDebug'])
|
2013-11-25 03:13:04 +00:00
|
|
|
{
|
2014-11-14 02:06:45 +00:00
|
|
|
this.debug = new Phaser.Utils.Debug(this);
|
|
|
|
this.debug.boot();
|
2013-11-25 03:13:04 +00:00
|
|
|
}
|
2014-11-21 10:40:18 +00:00
|
|
|
else
|
|
|
|
{
|
2014-12-03 20:56:39 +00:00
|
|
|
this.debug = { preUpdate: function () {}, update: function () {}, reset: function () {} };
|
2014-11-21 10:40:18 +00:00
|
|
|
}
|
2013-11-25 03:13:04 +00:00
|
|
|
|
2014-11-14 02:06:45 +00:00
|
|
|
this.showDebugHeader();
|
2013-08-29 02:52:59 +00:00
|
|
|
|
2014-11-14 02:06:45 +00:00
|
|
|
this.isRunning = true;
|
2014-02-20 01:31:13 +00:00
|
|
|
|
2014-11-14 02:06:45 +00:00
|
|
|
if (this.config && this.config['forceSetTimeOut'])
|
|
|
|
{
|
|
|
|
this.raf = new Phaser.RequestAnimationFrame(this, this.config['forceSetTimeOut']);
|
2013-11-25 03:13:04 +00:00
|
|
|
}
|
2014-11-14 02:06:45 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
this.raf = new Phaser.RequestAnimationFrame(this, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.raf.start();
|
2013-08-28 06:02:55 +00:00
|
|
|
|
2013-11-25 03:13:04 +00:00
|
|
|
},
|
2013-10-23 12:15:56 +00:00
|
|
|
|
2013-11-25 03:13:04 +00:00
|
|
|
/**
|
2013-11-01 04:58:08 +00:00
|
|
|
* Displays a Phaser version debug header in the console.
|
|
|
|
*
|
|
|
|
* @method Phaser.Game#showDebugHeader
|
|
|
|
* @protected
|
|
|
|
*/
|
2013-11-25 03:13:04 +00:00
|
|
|
showDebugHeader: function () {
|
|
|
|
|
2014-04-26 02:48:06 +00:00
|
|
|
var v = Phaser.VERSION;
|
2013-11-25 03:13:04 +00:00
|
|
|
var r = 'Canvas';
|
|
|
|
var a = 'HTML Audio';
|
2014-03-12 15:26:20 +00:00
|
|
|
var c = 1;
|
2013-11-25 03:13:04 +00:00
|
|
|
|
2014-03-12 15:26:20 +00:00
|
|
|
if (this.renderType === Phaser.WEBGL)
|
2013-11-25 03:13:04 +00:00
|
|
|
{
|
|
|
|
r = 'WebGL';
|
2014-03-12 15:26:20 +00:00
|
|
|
c++;
|
2013-11-25 03:13:04 +00:00
|
|
|
}
|
2013-11-25 14:53:30 +00:00
|
|
|
else if (this.renderType == Phaser.HEADLESS)
|
|
|
|
{
|
|
|
|
r = 'Headless';
|
|
|
|
}
|
2013-11-25 03:13:04 +00:00
|
|
|
|
|
|
|
if (this.device.webAudio)
|
|
|
|
{
|
|
|
|
a = 'WebAudio';
|
2014-03-12 15:26:20 +00:00
|
|
|
c++;
|
2013-11-25 03:13:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (this.device.chrome)
|
|
|
|
{
|
|
|
|
var args = [
|
2014-11-14 02:06:45 +00:00
|
|
|
'%c %c %c Phaser v' + v + ' | Pixi.js ' + PIXI.VERSION + ' | ' + r + ' | ' + a + ' %c %c ' + '%c http://phaser.io %c\u2665%c\u2665%c\u2665',
|
|
|
|
'background: #3db79f',
|
|
|
|
'background: #329582',
|
|
|
|
'color: #ffffff; background: #226558;',
|
|
|
|
'background: #329582',
|
|
|
|
'background: #3db79f',
|
|
|
|
'background: #ffffff'
|
2013-11-25 03:13:04 +00:00
|
|
|
];
|
|
|
|
|
2014-03-12 15:26:20 +00:00
|
|
|
for (var i = 0; i < 3; i++)
|
|
|
|
{
|
|
|
|
if (i < c)
|
|
|
|
{
|
|
|
|
args.push('color: #ff2424; background: #fff');
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
args.push('color: #959595; background: #fff');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-25 03:13:04 +00:00
|
|
|
console.log.apply(console, args);
|
|
|
|
}
|
2014-04-22 22:31:07 +00:00
|
|
|
else if (window['console'])
|
2013-11-25 03:13:04 +00:00
|
|
|
{
|
2014-07-03 09:50:26 +00:00
|
|
|
console.log('Phaser v' + v + ' | Pixi.js ' + PIXI.VERSION + ' | ' + r + ' | ' + a + ' | http://phaser.io');
|
2013-11-25 03:13:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if the device is capable of using the requested renderer and sets it up or an alternative if not.
|
|
|
|
*
|
|
|
|
* @method Phaser.Game#setUpRenderer
|
|
|
|
* @protected
|
|
|
|
*/
|
|
|
|
setUpRenderer: function () {
|
|
|
|
|
2014-05-30 01:01:33 +00:00
|
|
|
if (this.config['canvasID'])
|
|
|
|
{
|
|
|
|
this.canvas = Phaser.Canvas.create(this.width, this.height, this.config['canvasID']);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.canvas = Phaser.Canvas.create(this.width, this.height);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.config['canvasStyle'])
|
|
|
|
{
|
|
|
|
this.canvas.style = this.config['canvasStyle'];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.canvas.style['-webkit-full-screen'] = 'width: 100%; height: 100%';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.device.cocoonJS)
|
|
|
|
{
|
2014-09-08 21:34:38 +00:00
|
|
|
if (this.renderType === Phaser.CANVAS)
|
|
|
|
{
|
|
|
|
this.canvas.screencanvas = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Some issue related to scaling arise with Cocoon using screencanvas and webgl renderer.
|
|
|
|
this.canvas.screencanvas = false;
|
|
|
|
}
|
2014-05-30 01:01:33 +00:00
|
|
|
}
|
|
|
|
|
2013-11-25 14:53:30 +00:00
|
|
|
if (this.renderType === Phaser.HEADLESS || this.renderType === Phaser.CANVAS || (this.renderType === Phaser.AUTO && this.device.webGL === false))
|
2013-11-25 03:13:04 +00:00
|
|
|
{
|
|
|
|
if (this.device.canvas)
|
|
|
|
{
|
2013-11-25 14:53:30 +00:00
|
|
|
if (this.renderType === Phaser.AUTO)
|
|
|
|
{
|
|
|
|
this.renderType = Phaser.CANVAS;
|
|
|
|
}
|
|
|
|
|
2014-10-11 03:18:42 +00:00
|
|
|
this.renderer = new PIXI.CanvasRenderer(this.width, this.height, { "view": this.canvas, "transparent": this.transparent, "resolution": 1, "clearBeforeRender": true });
|
2013-11-25 03:13:04 +00:00
|
|
|
this.context = this.renderer.context;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw new Error('Phaser.Game - cannot create Canvas or WebGL context, aborting.');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-07-10 09:28:23 +00:00
|
|
|
// They requested WebGL and their browser supports it
|
2013-11-25 03:13:04 +00:00
|
|
|
this.renderType = Phaser.WEBGL;
|
2014-10-11 03:18:42 +00:00
|
|
|
|
|
|
|
this.renderer = new PIXI.WebGLRenderer(this.width, this.height, { "view": this.canvas, "transparent": this.transparent, "resolution": 1, "antialias": this.antialias, "preserveDrawingBuffer": this.preserveDrawingBuffer });
|
2013-11-25 03:13:04 +00:00
|
|
|
this.context = null;
|
|
|
|
}
|
2013-08-29 16:20:59 +00:00
|
|
|
|
2014-03-12 13:45:30 +00:00
|
|
|
if (this.renderType !== Phaser.HEADLESS)
|
2014-03-11 16:14:01 +00:00
|
|
|
{
|
|
|
|
this.stage.smoothed = this.antialias;
|
2014-09-08 21:34:38 +00:00
|
|
|
|
2014-06-05 01:33:13 +00:00
|
|
|
Phaser.Canvas.addToDOM(this.canvas, this.parent, false);
|
2014-03-11 16:14:01 +00:00
|
|
|
Phaser.Canvas.setTouchAction(this.canvas);
|
|
|
|
}
|
2013-08-29 16:20:59 +00:00
|
|
|
|
2013-11-25 03:13:04 +00:00
|
|
|
},
|
2013-08-29 16:20:59 +00:00
|
|
|
|
2014-03-11 16:14:01 +00:00
|
|
|
/**
|
2014-07-09 04:38:59 +00:00
|
|
|
* The core game loop.
|
2014-03-11 16:14:01 +00:00
|
|
|
*
|
2014-03-12 13:45:30 +00:00
|
|
|
* @method Phaser.Game#update
|
2014-03-11 16:14:01 +00:00
|
|
|
* @protected
|
2014-11-08 19:11:28 +00:00
|
|
|
* @param {number} time - The current time as provided by RequestAnimationFrame.
|
2014-03-11 16:14:01 +00:00
|
|
|
*/
|
2014-03-12 13:45:30 +00:00
|
|
|
update: function (time) {
|
2014-03-11 16:14:01 +00:00
|
|
|
|
2014-03-12 21:19:00 +00:00
|
|
|
this.time.update(time);
|
|
|
|
|
2014-12-10 10:37:37 +00:00
|
|
|
// if the logic time is spiraling upwards, skip a frame entirely
|
2014-11-11 05:51:47 +00:00
|
|
|
if (this._spiralling > 1 && !this.forceSingleUpdate)
|
2014-11-08 18:52:02 +00:00
|
|
|
{
|
|
|
|
// cause an event to warn the program that this CPU can't keep up with the current desiredFps rate
|
|
|
|
if (this.time.time > this._nextFpsNotification)
|
|
|
|
{
|
|
|
|
// only permit one fps notification per 10 seconds
|
|
|
|
this._nextFpsNotification = this.time.time + 1000 * 10;
|
|
|
|
|
|
|
|
// dispatch the notification signal
|
|
|
|
this.fpsProblemNotifier.dispatch();
|
|
|
|
}
|
|
|
|
|
|
|
|
// reset the _deltaTime accumulator which will cause all pending dropped frames to be permanently skipped
|
|
|
|
this._deltaTime = 0;
|
|
|
|
this._spiralling = 0;
|
2014-11-11 05:51:47 +00:00
|
|
|
|
2014-11-12 02:01:09 +00:00
|
|
|
// call the game render update exactly once every frame
|
|
|
|
this.updateRender(this.time.slowMotion * this.time.desiredFps);
|
2014-11-08 18:52:02 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// step size taking into account the slow motion speed
|
|
|
|
var slowStep = this.time.slowMotion * 1000.0 / this.time.desiredFps;
|
|
|
|
|
2014-11-12 11:00:13 +00:00
|
|
|
// accumulate time until the slowStep threshold is met or exceeded... up to a limit of 3 catch-up frames at slowStep intervals
|
|
|
|
this._deltaTime += Math.max(Math.min(slowStep * 3, this.time.elapsed), 0);
|
2014-11-08 18:52:02 +00:00
|
|
|
|
|
|
|
// call the game update logic multiple times if necessary to "catch up" with dropped frames
|
2014-11-11 05:51:47 +00:00
|
|
|
// unless forceSingleUpdate is true
|
2014-11-25 08:56:23 +00:00
|
|
|
var count = 0;
|
|
|
|
|
|
|
|
this.updatesThisFrame = Math.floor(this._deltaTime / slowStep);
|
2014-11-25 14:18:18 +00:00
|
|
|
|
2014-11-25 08:56:23 +00:00
|
|
|
if (this.forceSingleUpdate)
|
|
|
|
{
|
|
|
|
this.updatesThisFrame = Math.min(1, this.updatesThisFrame);
|
|
|
|
}
|
2014-11-08 18:52:02 +00:00
|
|
|
|
|
|
|
while (this._deltaTime >= slowStep)
|
|
|
|
{
|
|
|
|
this._deltaTime -= slowStep;
|
2014-11-29 06:54:30 +00:00
|
|
|
this.currentUpdateID = count;
|
Simplified call to updateTransform
This change implements the original suggestion of using `updateTransform`,
but applies so globally instead of within a particular postUpdate
function.
Now the game loop calls `updateTransform` after each `updateLogic` call
unconditionally; it is updates that change the world that are accounted
for, not the rendering. This removes some previous checks that were
preventing correct behavior with the previous patch.
This makes the assumption that game objects (eg. Sprites) are only
modified within callbacks triggered before the completion of the
`postUpdate` walking of the scene graph.
- User code that runs outside of the "game update", such as a `setTimeout`
timer, will need to explicitly update transformations so that the world
is synced by the next `preUpdate`: but this is not the expected case and
is already outside the Phaser update model.
- If this assumption does not hold or is too weak, the transformations
could also be applied once at the start of every game update loop
(before any render or update). This change would at most double the time
spent on apply the transformations.
The constant application of `updateTransform` passes all reported failing
cases and resolves #1424 just as the original proposal of having the
change performed in the Sprite postUpdate but will work more consistently
across all scene-bound game objects.
On a desktop Chrome browser the inclusion also has minimal relative impact
as shown by the summarized results. The percentages given are the summed
CPU time of relevant required operations along with that of the
updateTransform itself:
- 10,000 non-collision particles:
- 12% pre/post update, 2.4% updateTransform
- 100 colliding particles:
- 2% pre/post update & collision, 0.3% updateTransform
- 1000 colliding particles:
- 40% pre/post update & collision, 1% updateTransform
With this patch the updateTransform time does creep up _slightly_ (vs just
in `Sprite.postUpdate`) but it is still dominated by required game
updates, and more so, by any actual work like Physics.
2015-01-02 02:01:23 +00:00
|
|
|
|
2014-11-08 18:52:02 +00:00
|
|
|
this.updateLogic(1.0 / this.time.desiredFps);
|
Simplified call to updateTransform
This change implements the original suggestion of using `updateTransform`,
but applies so globally instead of within a particular postUpdate
function.
Now the game loop calls `updateTransform` after each `updateLogic` call
unconditionally; it is updates that change the world that are accounted
for, not the rendering. This removes some previous checks that were
preventing correct behavior with the previous patch.
This makes the assumption that game objects (eg. Sprites) are only
modified within callbacks triggered before the completion of the
`postUpdate` walking of the scene graph.
- User code that runs outside of the "game update", such as a `setTimeout`
timer, will need to explicitly update transformations so that the world
is synced by the next `preUpdate`: but this is not the expected case and
is already outside the Phaser update model.
- If this assumption does not hold or is too weak, the transformations
could also be applied once at the start of every game update loop
(before any render or update). This change would at most double the time
spent on apply the transformations.
The constant application of `updateTransform` passes all reported failing
cases and resolves #1424 just as the original proposal of having the
change performed in the Sprite postUpdate but will work more consistently
across all scene-bound game objects.
On a desktop Chrome browser the inclusion also has minimal relative impact
as shown by the summarized results. The percentages given are the summed
CPU time of relevant required operations along with that of the
updateTransform itself:
- 10,000 non-collision particles:
- 12% pre/post update, 2.4% updateTransform
- 100 colliding particles:
- 2% pre/post update & collision, 0.3% updateTransform
- 1000 colliding particles:
- 40% pre/post update & collision, 1% updateTransform
With this patch the updateTransform time does creep up _slightly_ (vs just
in `Sprite.postUpdate`) but it is still dominated by required game
updates, and more so, by any actual work like Physics.
2015-01-02 02:01:23 +00:00
|
|
|
// Sync the scene graph after _every_ logic update to account for moved game objects
|
|
|
|
this.stage.updateTransform();
|
|
|
|
|
2014-11-25 08:56:23 +00:00
|
|
|
count++;
|
2014-11-11 05:51:47 +00:00
|
|
|
|
2014-11-25 08:56:23 +00:00
|
|
|
if (this.forceSingleUpdate && count === 1)
|
2014-11-11 05:51:47 +00:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2014-11-08 18:52:02 +00:00
|
|
|
}
|
|
|
|
|
2014-12-10 10:37:37 +00:00
|
|
|
// detect spiraling (if the catch-up loop isn't fast enough, the number of iterations will increase constantly)
|
2014-11-25 08:56:23 +00:00
|
|
|
if (count > this._lastCount)
|
2014-11-08 18:52:02 +00:00
|
|
|
{
|
|
|
|
this._spiralling++;
|
|
|
|
}
|
2014-11-25 08:56:23 +00:00
|
|
|
else if (count < this._lastCount)
|
2014-11-08 18:52:02 +00:00
|
|
|
{
|
|
|
|
// looks like it caught up successfully, reset the spiral alert counter
|
|
|
|
this._spiralling = 0;
|
|
|
|
}
|
|
|
|
|
2014-11-25 08:56:23 +00:00
|
|
|
this._lastCount = count;
|
2014-11-08 18:52:02 +00:00
|
|
|
|
2014-11-12 02:01:09 +00:00
|
|
|
// call the game render update exactly once every frame unless we're playing catch-up from a spiral condition
|
|
|
|
this.updateRender(this._deltaTime / slowStep);
|
|
|
|
}
|
2014-11-08 18:52:02 +00:00
|
|
|
|
|
|
|
},
|
|
|
|
|
2014-11-12 22:38:51 +00:00
|
|
|
/**
|
|
|
|
* Updates all logic subsystems in Phaser. Called automatically by Game.update.
|
|
|
|
*
|
|
|
|
* @method Phaser.Game#updateLogic
|
|
|
|
* @protected
|
|
|
|
* @param {number} timeStep - The current timeStep value as determined by Game.update.
|
|
|
|
*/
|
2014-11-08 18:52:02 +00:00
|
|
|
updateLogic: function (timeStep) {
|
|
|
|
|
2014-03-12 13:45:30 +00:00
|
|
|
if (!this._paused && !this.pendingStep)
|
2014-03-11 16:14:01 +00:00
|
|
|
{
|
|
|
|
if (this.stepping)
|
|
|
|
{
|
|
|
|
this.pendingStep = true;
|
2013-11-25 14:53:30 +00:00
|
|
|
}
|
2014-03-11 16:14:01 +00:00
|
|
|
|
2014-09-01 00:02:41 +00:00
|
|
|
this.scale.preUpdate();
|
2014-11-21 10:40:18 +00:00
|
|
|
this.debug.preUpdate();
|
2014-11-18 12:36:25 +00:00
|
|
|
this.world.camera.preUpdate();
|
2014-03-13 21:14:10 +00:00
|
|
|
this.physics.preUpdate();
|
2014-11-08 19:11:28 +00:00
|
|
|
this.state.preUpdate(timeStep);
|
|
|
|
this.plugins.preUpdate(timeStep);
|
2014-03-12 13:45:30 +00:00
|
|
|
this.stage.preUpdate();
|
2013-08-29 02:52:59 +00:00
|
|
|
|
2014-03-28 14:12:32 +00:00
|
|
|
this.state.update();
|
2014-03-12 13:45:30 +00:00
|
|
|
this.stage.update();
|
Tweens have been completely rewritten. They're now much more flexible and efficient than before:
When specifying the ease in `Tween.to` or `Tween.from` you can now use a string instead of the Function. This makes your code less verbose. For example instead of `Phaser.Easing.Sinusoidal.Out` and you can now just use the string "Sine".The string names match those used by TweenMax and includes: "Linear", "Quad", "Cubic", "Quart", "Quint", "Sine", "Expo", "Circ", "Elastic", "Back", "Bounce", "Power0", "Power1", "Power2", "Power3" and "Power4". You can append ".easeIn", ".easeOut" and "easeInOut" variants. All are supported for each ease types.
Tweens now create a TweenData object. The Tween object itself acts like more of a timeline, managing multiple TweenData objects. You can now call `Tween.to` and each call will create a new child tween that is added to the timeline, which are played through in sequence.
Tweens are now bound to the new Time.desiredFps value and update based on the new Game core loop, rather than being bound to time calculations. This means that tweens are now running with the same update logic as physics and the core loop.
Tween.timeScale allows you to scale the duration of a tween (and any child tweens it may have). A value of 1.0 means it should play at the desiredFps rate. A value of 0.5 will run at half the frame rate, 2 at double and so on. You can even tween the timeScale value for interesting effects!
Tween.reverse allows you to instantly reverse an active tween. If the Tween has children then it will smoothly reverse through all child tweens as well.
Tween.repeatAll allows you to control how many times all child tweens will repeat before firing the Tween.onComplete event. You can set the value to -1 to repeat forever.
Tween.loop now controls the looping of all child tweens.
Tween.onRepeat is a new signal that is dispatched whenever a Tween repeats. If a Tween has many child tweens its dispatched once the sequence has repeated.
Tween.onChildComplete is a new signal that is dispatched whenever any child tweens have completed. If a Tween consists of 4 sections you will get 3 onChildComplete events followed by 1 onComplete event as the final tween finishes.
Chained tweens are now more intelligently handled. Because you can easily create child tweens (by simply calling Tween.to multiple times) chained tweens are now used to kick-off longer sequences. You can pass as many Tween objects to `Tween.chain` as you like as they'll all be played in sequence. As one Tween completes it passes on to the next until the entire chain is finished.
Tween.stop has a new `complete` parameter that if set will still fire the onComplete event and start the next chained tween, if there is one.
Tween.delay, Tween.repeat, Tween.yoyo, Tween.easing and Tween.interpolation all have a new `index` parameter. This allows you to target specific child tweens, or if set to -1 it will update all children at once.
Tween.totalDuration reports the total duration of all child tweens in ms.
There are new easing aliases:
* Phaser.Easing.Power0 = Phaser.Easing.Linear.None
* Phaser.Easing.Power1 = Phaser.Easing.Quadratic.Out
* Phaser.Easing.Power2 = Phaser.Easing.Cubic.Out
* Phaser.Easing.Power3 = Phaser.Easing.Quartic.Out
* Phaser.Easing.Power4 = Phaser.Easing.Quintic.Out
2014-11-20 06:04:54 +00:00
|
|
|
this.tweens.update(timeStep);
|
2014-03-12 13:45:30 +00:00
|
|
|
this.sound.update();
|
|
|
|
this.input.update();
|
|
|
|
this.physics.update();
|
2014-03-13 16:49:52 +00:00
|
|
|
this.particles.update();
|
2014-03-12 13:45:30 +00:00
|
|
|
this.plugins.update();
|
2014-03-11 16:14:01 +00:00
|
|
|
|
2014-03-12 13:45:30 +00:00
|
|
|
this.stage.postUpdate();
|
|
|
|
this.plugins.postUpdate();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-11-12 06:30:01 +00:00
|
|
|
// Scaling and device orientation changes are still reflected when paused.
|
|
|
|
this.scale.pauseUpdate();
|
2014-04-27 23:07:40 +00:00
|
|
|
this.state.pauseUpdate();
|
2014-11-21 10:40:18 +00:00
|
|
|
this.debug.preUpdate();
|
2014-03-12 13:45:30 +00:00
|
|
|
}
|
2014-12-10 10:37:37 +00:00
|
|
|
|
2014-11-08 18:52:02 +00:00
|
|
|
},
|
|
|
|
|
2014-11-12 22:38:51 +00:00
|
|
|
/**
|
2014-12-02 09:03:06 +00:00
|
|
|
* Runs the Render cycle.
|
|
|
|
* It starts by calling State.preRender. In here you can do any last minute adjustments of display objects as required.
|
|
|
|
* It then calls the renderer, which renders the entire display list, starting from the Stage object and working down.
|
|
|
|
* It then calls plugin.render on any loaded plugins, in the order in which they were enabled.
|
|
|
|
* After this State.render is called. Any rendering that happens here will take place on-top of the display list.
|
|
|
|
* Finally plugin.postRender is called on any loaded plugins, in the order in which they were enabled.
|
|
|
|
* This method is called automatically by Game.update, you don't need to call it directly.
|
|
|
|
* Should you wish to have fine-grained control over when Phaser renders then use the `Game.lockRender` boolean.
|
|
|
|
* Phaser will only render when this boolean is `false`.
|
2014-11-12 22:38:51 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Game#updateRender
|
|
|
|
* @protected
|
|
|
|
* @param {number} elapsedTime - The time elapsed since the last update.
|
|
|
|
*/
|
2014-11-08 18:52:02 +00:00
|
|
|
updateRender: function (elapsedTime) {
|
|
|
|
|
2014-12-02 09:03:06 +00:00
|
|
|
if (this.lockRender)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.state.preRender(elapsedTime);
|
2014-11-21 10:40:18 +00:00
|
|
|
this.renderer.render(this.stage);
|
2014-05-29 22:52:13 +00:00
|
|
|
|
2014-11-21 10:40:18 +00:00
|
|
|
this.plugins.render(elapsedTime);
|
|
|
|
this.state.render(elapsedTime);
|
|
|
|
this.plugins.postRender(elapsedTime);
|
2014-03-11 16:14:01 +00:00
|
|
|
|
|
|
|
},
|
|
|
|
|
2014-01-31 05:42:20 +00:00
|
|
|
/**
|
|
|
|
* Enable core game loop stepping. When enabled you must call game.step() directly (perhaps via a DOM button?)
|
2014-03-11 16:14:01 +00:00
|
|
|
* Calling step will advance the game loop by one frame. This is extremely useful for hard to track down errors!
|
2014-01-31 05:42:20 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Game#enableStep
|
|
|
|
*/
|
2014-01-29 17:10:13 +00:00
|
|
|
enableStep: function () {
|
|
|
|
|
|
|
|
this.stepping = true;
|
|
|
|
this.pendingStep = false;
|
|
|
|
this.stepCount = 0;
|
|
|
|
|
|
|
|
},
|
|
|
|
|
2014-01-31 05:42:20 +00:00
|
|
|
/**
|
|
|
|
* Disables core game loop stepping.
|
|
|
|
*
|
|
|
|
* @method Phaser.Game#disableStep
|
|
|
|
*/
|
|
|
|
disableStep: function () {
|
|
|
|
|
|
|
|
this.stepping = false;
|
|
|
|
this.pendingStep = false;
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* When stepping is enabled you must call this function directly (perhaps via a DOM button?) to advance the game loop by one frame.
|
|
|
|
* This is extremely useful to hard to track down errors! Use the internal stepCount property to monitor progress.
|
|
|
|
*
|
|
|
|
* @method Phaser.Game#step
|
|
|
|
*/
|
2014-01-29 17:10:13 +00:00
|
|
|
step: function () {
|
|
|
|
|
|
|
|
this.pendingStep = false;
|
|
|
|
this.stepCount++;
|
|
|
|
|
|
|
|
},
|
|
|
|
|
2013-11-25 03:13:04 +00:00
|
|
|
/**
|
2014-08-29 10:37:47 +00:00
|
|
|
* Nukes the entire game from orbit.
|
2013-10-23 12:15:56 +00:00
|
|
|
*
|
2013-10-02 00:16:40 +00:00
|
|
|
* @method Phaser.Game#destroy
|
2013-08-29 02:52:59 +00:00
|
|
|
*/
|
|
|
|
destroy: function () {
|
|
|
|
|
2013-11-25 03:13:04 +00:00
|
|
|
this.raf.stop();
|
2013-10-24 03:27:28 +00:00
|
|
|
|
2014-08-29 10:37:47 +00:00
|
|
|
this.state.destroy();
|
|
|
|
this.sound.destroy();
|
|
|
|
|
2014-08-28 02:31:47 +00:00
|
|
|
this.scale.destroy();
|
|
|
|
this.stage.destroy();
|
2013-11-25 03:13:04 +00:00
|
|
|
this.input.destroy();
|
2014-03-11 15:02:59 +00:00
|
|
|
this.physics.destroy();
|
2013-08-29 14:14:56 +00:00
|
|
|
|
|
|
|
this.state = null;
|
2013-08-29 02:52:59 +00:00
|
|
|
this.cache = null;
|
|
|
|
this.input = null;
|
|
|
|
this.load = null;
|
|
|
|
this.sound = null;
|
|
|
|
this.stage = null;
|
|
|
|
this.time = null;
|
|
|
|
this.world = null;
|
|
|
|
this.isBooted = false;
|
|
|
|
|
2014-10-27 22:09:39 +00:00
|
|
|
if (this.renderType === Phaser.WEBGL)
|
|
|
|
{
|
|
|
|
PIXI.glContexts[this.renderer.glContextId] = null;
|
|
|
|
|
|
|
|
this.renderer.projection = null;
|
|
|
|
this.renderer.offset = null;
|
|
|
|
|
|
|
|
this.renderer.shaderManager.destroy();
|
|
|
|
this.renderer.spriteBatch.destroy();
|
|
|
|
this.renderer.maskManager.destroy();
|
|
|
|
this.renderer.filterManager.destroy();
|
|
|
|
|
|
|
|
this.renderer.shaderManager = null;
|
|
|
|
this.renderer.spriteBatch = null;
|
|
|
|
this.renderer.maskManager = null;
|
|
|
|
this.renderer.filterManager = null;
|
|
|
|
|
|
|
|
this.renderer.gl = null;
|
|
|
|
this.renderer.renderSession = null;
|
|
|
|
Phaser.Canvas.removeFromDOM(this.canvas);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.renderer.destroy(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
Phaser.GAMES[this.id] = null;
|
2014-09-01 01:38:21 +00:00
|
|
|
|
2014-02-25 02:59:24 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called by the Stage visibility handler.
|
|
|
|
*
|
|
|
|
* @method Phaser.Game#gamePaused
|
2014-03-12 21:19:00 +00:00
|
|
|
* @param {object} event - The DOM event that caused the game to pause, if any.
|
2014-03-11 16:14:01 +00:00
|
|
|
* @protected
|
2014-02-25 02:59:24 +00:00
|
|
|
*/
|
2014-03-12 21:19:00 +00:00
|
|
|
gamePaused: function (event) {
|
2014-02-25 02:59:24 +00:00
|
|
|
|
|
|
|
// If the game is already paused it was done via game code, so don't re-pause it
|
|
|
|
if (!this._paused)
|
|
|
|
{
|
|
|
|
this._paused = true;
|
2014-03-12 21:19:00 +00:00
|
|
|
this.time.gamePaused();
|
2014-02-25 03:12:12 +00:00
|
|
|
this.sound.setMute();
|
2014-03-12 21:19:00 +00:00
|
|
|
this.onPause.dispatch(event);
|
2014-02-25 02:59:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called by the Stage visibility handler.
|
|
|
|
*
|
|
|
|
* @method Phaser.Game#gameResumed
|
2014-03-12 21:19:00 +00:00
|
|
|
* @param {object} event - The DOM event that caused the game to pause, if any.
|
2014-03-11 16:14:01 +00:00
|
|
|
* @protected
|
2014-02-25 02:59:24 +00:00
|
|
|
*/
|
2014-03-12 21:19:00 +00:00
|
|
|
gameResumed: function (event) {
|
2014-02-25 02:59:24 +00:00
|
|
|
|
|
|
|
// Game is paused, but wasn't paused via code, so resume it
|
|
|
|
if (this._paused && !this._codePaused)
|
|
|
|
{
|
|
|
|
this._paused = false;
|
2014-03-12 21:19:00 +00:00
|
|
|
this.time.gameResumed();
|
2014-02-25 02:59:24 +00:00
|
|
|
this.input.reset();
|
2014-02-25 03:12:12 +00:00
|
|
|
this.sound.unsetMute();
|
2014-03-12 21:19:00 +00:00
|
|
|
this.onResume.dispatch(event);
|
2014-02-25 02:59:24 +00:00
|
|
|
}
|
|
|
|
|
2014-03-12 21:19:00 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called by the Stage visibility handler.
|
|
|
|
*
|
|
|
|
* @method Phaser.Game#focusLoss
|
|
|
|
* @param {object} event - The DOM event that caused the game to pause, if any.
|
|
|
|
* @protected
|
|
|
|
*/
|
|
|
|
focusLoss: function (event) {
|
|
|
|
|
|
|
|
this.onBlur.dispatch(event);
|
|
|
|
|
2014-07-02 13:57:28 +00:00
|
|
|
if (!this.stage.disableVisibilityChange)
|
|
|
|
{
|
|
|
|
this.gamePaused(event);
|
|
|
|
}
|
2014-03-12 21:19:00 +00:00
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called by the Stage visibility handler.
|
|
|
|
*
|
|
|
|
* @method Phaser.Game#focusGain
|
|
|
|
* @param {object} event - The DOM event that caused the game to pause, if any.
|
|
|
|
* @protected
|
|
|
|
*/
|
|
|
|
focusGain: function (event) {
|
|
|
|
|
|
|
|
this.onFocus.dispatch(event);
|
|
|
|
|
2014-07-02 13:57:28 +00:00
|
|
|
if (!this.stage.disableVisibilityChange)
|
|
|
|
{
|
|
|
|
this.gameResumed(event);
|
|
|
|
}
|
2014-03-12 21:19:00 +00:00
|
|
|
|
2013-08-29 02:52:59 +00:00
|
|
|
}
|
|
|
|
|
2013-08-28 06:02:55 +00:00
|
|
|
};
|
2013-09-10 22:51:35 +00:00
|
|
|
|
2013-12-30 16:54:00 +00:00
|
|
|
Phaser.Game.prototype.constructor = Phaser.Game;
|
|
|
|
|
2013-10-01 12:54:29 +00:00
|
|
|
/**
|
2013-10-02 00:16:40 +00:00
|
|
|
* The paused state of the Game. A paused game doesn't update any of its subsystems.
|
|
|
|
* When a game is paused the onPause event is dispatched. When it is resumed the onResume event is dispatched.
|
|
|
|
* @name Phaser.Game#paused
|
|
|
|
* @property {boolean} paused - Gets and sets the paused state of the Game.
|
2013-10-01 12:54:29 +00:00
|
|
|
*/
|
2013-09-10 22:51:35 +00:00
|
|
|
Object.defineProperty(Phaser.Game.prototype, "paused", {
|
|
|
|
|
|
|
|
get: function () {
|
|
|
|
return this._paused;
|
|
|
|
},
|
|
|
|
|
|
|
|
set: function (value) {
|
|
|
|
|
2013-11-25 03:13:04 +00:00
|
|
|
if (value === true)
|
|
|
|
{
|
|
|
|
if (this._paused === false)
|
|
|
|
{
|
|
|
|
this._paused = true;
|
2014-04-28 19:30:34 +00:00
|
|
|
this.sound.setMute();
|
2014-02-25 02:59:24 +00:00
|
|
|
this.time.gamePaused();
|
2013-11-25 03:13:04 +00:00
|
|
|
this.onPause.dispatch(this);
|
|
|
|
}
|
2014-07-14 19:57:37 +00:00
|
|
|
this._codePaused = true;
|
2013-11-25 03:13:04 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (this._paused)
|
|
|
|
{
|
|
|
|
this._paused = false;
|
2014-02-24 15:58:02 +00:00
|
|
|
this.input.reset();
|
2014-04-28 19:30:34 +00:00
|
|
|
this.sound.unsetMute();
|
2014-02-25 02:59:24 +00:00
|
|
|
this.time.gameResumed();
|
2013-11-25 03:13:04 +00:00
|
|
|
this.onResume.dispatch(this);
|
|
|
|
}
|
2014-07-14 19:57:37 +00:00
|
|
|
this._codePaused = false;
|
2013-11-25 03:13:04 +00:00
|
|
|
}
|
2013-09-10 22:51:35 +00:00
|
|
|
|
2013-09-11 12:21:07 +00:00
|
|
|
}
|
2013-09-10 22:51:35 +00:00
|
|
|
|
|
|
|
});
|
|
|
|
|
2013-10-07 09:21:22 +00:00
|
|
|
/**
|
|
|
|
* "Deleted code is debugged code." - Jeff Sickel
|
|
|
|
*/
|