phaser/src/core/Game.js

1267 lines
36 KiB
JavaScript
Raw Normal View History

/**
2013-10-01 12:54:29 +00:00
* @author Richard Davey <rich@photonstorm.com>
2016-04-04 21:15:01 +00:00
* @copyright 2016 Photon Storm Ltd.
2013-10-01 12:54:29 +00:00
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
/**
* The Phaser.Game object is the main controller for the entire Phaser game. It is responsible
* for handling the boot process, parsing the configuration values, creating the renderer,
* and setting-up all of the Phaser systems, such as physics, sound and input.
* Once that is complete it will start the default State, and then begin the main game loop.
*
* You can access lots of the Phaser systems via the properties on the `game` object. For
* example `game.renderer` is the Renderer, `game.sound` is the Sound Manager, and so on.
*
* Anywhere you can access the `game` property, you can access all of these core systems.
* For example a Sprite has a `game` property, allowing you to talk to the various parts
* of Phaser directly, without having to look after your own references.
*
* In it's most simplest form, a Phaser game can be created by providing the arguments
* to the constructor:
*
* ```
* var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create });
* ```
*
* In the example above it is passing in a State object directly. You can also use the State
* Manager to do this:
*
* ```
* var game = new Phaser.Game(800, 600, Phaser.AUTO);
* game.state.add('Boot', BasicGame.Boot);
* game.state.add('Preloader', BasicGame.Preloader);
* game.state.add('MainMenu', BasicGame.MainMenu);
* game.state.add('Game', BasicGame.Game);
* game.state.start('Boot');
2014-11-21 10:40:18 +00:00
*
* ```
* In the example above, 4 States are added to the State Manager, and Phaser is told to
* start running the `Boot` state when it has finished initializing. There are example
* project templates you can use in the Phaser GitHub repo, inside the `resources` folder.
*
* Instead of specifying arguments you can also pass a single object instead:
*
* ```
* var config = {
* width: 800,
* height: 600,
* renderer: Phaser.AUTO,
* antialias: true,
* multiTexture: true,
* state: {
* preload: preload,
* create: create,
* update: update
* }
* }
*
* var game = new Phaser.Game(config);
* ```
*
* @class Phaser.Game
* @constructor
* @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.
* @param {number} [renderer=Phaser.AUTO] - Which renderer to use: Phaser.AUTO will auto-detect, Phaser.WEBGL, Phaser.WEBGL_MULTI, Phaser.CANVAS or Phaser.HEADLESS (no rendering at all).
* @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.
* @param {boolean} [pixelArt=false] - Draw all image textures anti-aliased or not. The default is for smooth textures (false), but set to `true` if your game features all pixel art.
*/
Phaser.Game = function (width, height, renderer, parent, state, pixelArt)
{
/**
* TODO: Remove this
* @property {number} id - Phaser Game ID
* @readonly
*/
this.id = Phaser.GAMES.push(this) - 1;
/**
* @property {object} config - The Phaser.Game configuration object.
*/
this.config = null;
/**
* @property {object} physicsConfig - The Phaser.Physics.World configuration object.
*/
this.physicsConfig = null;
/**
* @property {string|HTMLElement} parent - The Games DOM parent.
* @default
*/
this.parent = '';
/**
* The current Game Width in pixels.
*
* _Do not modify this property directly:_ use {@link Phaser.ScaleManager#setGameSize} - eg. `game.scale.setGameSize(width, height)` - instead.
*
* @property {integer} width
* @readonly
* @default
*/
this.width = 800;
/**
* The current Game Height in pixels.
*
* _Do not modify this property directly:_ use {@link Phaser.ScaleManager#setGameSize} - eg. `game.scale.setGameSize(width, height)` - instead.
*
* @property {integer} height
* @readonly
* @default
*/
this.height = 600;
/**
* The resolution of your game. This value is read only, but can be changed at start time it via a game configuration object.
*
* @property {integer} resolution
* @readonly
* @default
*/
this.resolution = 1;
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
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;
/**
* @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.
* @default
*/
this.antialias = true;
/**
* Has support for Multiple bound Textures in WebGL been enabled? This is a read-only property.
* To set it you need to either specify `Phaser.WEBGL_MULTI` as the renderer type, or use the Game
* Configuration object with the property `multiTexture` set to true. It has to be enabled before
* Pixi boots, and cannot be changed after the game is running. Once enabled, take advantage of it
* via the `game.renderer.setTexturePriority` method.
*
* @property {boolean} multiTexture
* @default
* @readOnly
*/
this.multiTexture = false;
/**
* @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;
2015-09-15 11:52:08 +00:00
/**
* Clear the Canvas each frame before rendering the display list.
* You can set this to `false` to gain some performance if your game always contains a background that completely fills the display.
* @property {boolean} clearBeforeRender
* @default
*/
this.clearBeforeRender = true;
/**
* @property {PIXI.CanvasRenderer|PIXI.WebGLRenderer} renderer - The Pixi Renderer.
* @protected
*/
this.renderer = null;
/**
* @property {number} renderType - The Renderer this game will use. Either Phaser.AUTO, Phaser.CANVAS, Phaser.WEBGL, Phaser.WEBGL_MULTI or Phaser.HEADLESS.
* @readonly
*/
this.renderType = Phaser.AUTO;
/**
* @property {Phaser.StateManager} state - The StateManager.
*/
this.state = null;
/**
* @property {boolean} isBooted - Whether the game engine is booted, aka available.
* @readonly
*/
this.isBooted = false;
/**
2014-11-30 12:05:23 +00:00
* @property {boolean} isRunning - Is game running or paused?
* @readonly
*/
this.isRunning = false;
/**
* @property {Phaser.RequestAnimationFrame} raf - Automatically handles the core game loop via requestAnimationFrame or setTimeout
* @protected
*/
this.raf = null;
/**
* @property {Phaser.GameObject.Factory} add - Reference to the Phaser GameObject Factory.
*/
this.add = null;
/**
* @property {Phaser.GameObjectCreator} make - Reference to the GameObject Creator.
*/
this.make = null;
/**
* @property {Phaser.TextureManager} textures - Reference to the Phaser Texture Manager.
*/
this.textures = null;
/**
2016-10-14 07:58:12 +00:00
* @property {Phaser.UpdateManager} updates - Reference to the Phaser Update Manager.
*/
2016-10-14 07:58:12 +00:00
this.updates = null;
/**
* @property {Phaser.Cache} cache - Reference to the assets cache.
*/
this.cache = null;
/**
* @property {Phaser.Input} input - Reference to the input manager
*/
this.input = null;
/**
* @property {Phaser.Loader} load - Reference to the assets loader.
*/
this.load = null;
/**
* @property {Phaser.Math} math - Reference to the math helper.
*/
this.math = null;
/**
* @property {Phaser.Net} net - Reference to the network class.
*/
this.net = null;
/**
* @property {Phaser.ScaleManager} scale - The game scale manager.
*/
this.scale = null;
/**
* @property {Phaser.SoundManager} sound - Reference to the sound manager.
*/
this.sound = null;
/**
* @property {Phaser.Stage} stage - Reference to the stage.
*/
this.stage = null;
/**
2014-04-02 09:40:38 +00:00
* @property {Phaser.Time} time - Reference to the core game clock.
*/
this.time = null;
/**
* @property {Phaser.TweenManager} tweens - Reference to the tween manager.
*/
this.tweens = null;
/**
* @property {Phaser.World} world - Reference to the world.
*/
this.world = null;
/**
* @property {Phaser.Physics} physics - Reference to the physics manager.
*/
this.physics = null;
/**
* @property {Phaser.PluginManager} plugins - Reference to the plugin manager.
*/
this.plugins = null;
/**
* @property {Phaser.RandomDataGenerator} rnd - Instance of repeatable random data generator helper.
*/
this.rnd = null;
/**
* @property {Phaser.Device} device - Contains device information and capabilities.
*/
this.device = Phaser.Device;
2013-10-01 12:54:29 +00:00
/**
* @property {Phaser.Camera} camera - A handy reference to world.camera.
*/
this.camera = null;
/**
* @property {HTMLCanvasElement} canvas - A handy reference to renderer.view, the canvas that the game is being rendered in to.
*/
this.canvas = null;
/**
* @property {CanvasRenderingContext2D} context - A handy reference to renderer.context (only set for CANVAS games, not WebGL)
*/
this.context = null;
2013-10-01 12:54:29 +00:00
/**
* @property {Phaser.Utils.Debug} debug - A set of useful debug utilities.
*/
this.debug = null;
/**
* @property {Phaser.Particles} particles - The Particle Manager.
*/
this.particles = null;
2015-07-08 23:19:21 +00:00
/**
* @property {Phaser.Create} create - The Asset Generator.
*/
this.create = null;
/**
* 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;
/**
* @property {boolean} stepping - Enable core loop stepping with Game.enableStep().
* @default
* @readonly
*/
this.stepping = false;
/**
* @property {boolean} pendingStep - An internal property used by enableStep, but also useful to query from your own game objects.
* @default
* @readonly
*/
this.pendingStep = false;
/**
* @property {number} stepCount - When stepping is enabled this contains the current step cycle.
* @default
* @readonly
*/
this.stepCount = 0;
/**
* @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;
/**
* @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;
/**
* The ID of the current/last logic update applied this render frame, starting from 0.
* The first update is `currentUpdateID === 0` and the last update is `currentUpdateID === updatesThisFrame.`
* @property {integer} currentUpdateID
* @protected
*/
this.currentUpdateID = 0;
/**
2015-02-17 06:01:09 +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;
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
2014-11-08 18:52:02 +00:00
/**
2015-02-17 06:01:09 +00:00
* @property {number} _deltaTime - Accumulate elapsed time until a logic update is due.
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
2014-11-08 18:52:02 +00:00
* @private
*/
this._deltaTime = 0;
/**
2015-02-17 06:01:09 +00:00
* @property {number} _lastCount - Remember how many 'catch-up' iterations were used on the logicUpdate last frame.
* @private
*/
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
2014-11-08 18:52:02 +00:00
this._lastCount = 0;
/**
2015-02-17 06:01:09 +00:00
* @property {number} _spiraling - If the 'catch-up' iterations are spiraling out of control, this counter is incremented.
* @private
*/
this._spiraling = 0;
/**
2015-02-17 06:01:09 +00:00
* @property {boolean} _kickstart - Force a logic update + render by default (always set on Boot and State swap)
* @private
*/
this._kickstart = true;
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
2014-11-08 18:52:02 +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
*/
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
2014-11-08 18:52:02 +00:00
this.fpsProblemNotifier = new Phaser.Signal();
/**
* @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.
*/
this.forceSingleUpdate = true;
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
2014-11-08 18:52:02 +00:00
/**
2015-02-17 06:01:09 +00:00
* @property {number} _nextNotification - The soonest game.time.time value that the next fpsProblemNotifier can be dispatched.
* @private
*/
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
2014-11-08 18:52:02 +00:00
this._nextFpsNotification = 0;
// Parse the configuration object (if any)
if (arguments.length === 1 && typeof arguments[0] === 'object')
{
this.parseConfig(arguments[0]);
}
else
{
this.config = { enableDebug: true };
2014-05-30 04:33:30 +00:00
if (typeof width !== 'undefined')
{
this._width = width;
}
if (typeof height !== 'undefined')
{
this._height = height;
}
if (typeof renderer !== 'undefined')
{
this.renderType = renderer;
}
if (typeof parent !== 'undefined')
{
this.parent = parent;
}
if (typeof pixelArt !== 'undefined')
{
this.antialias = !pixelArt;
}
this.rnd = new Phaser.RandomDataGenerator([(Date.now() * Math.random()).toString()]);
this.state = new Phaser.StateManager(this, state);
}
this.device.whenReady(this.boot, this);
return this;
};
Phaser.Game.prototype = {
/**
* Parses a Game configuration object.
*
* @method Phaser.Game#parseConfig
* @protected
*/
parseConfig: function (config)
{
this.config = config;
if (config['enableDebug'] === undefined)
{
this.config.enableDebug = true;
}
if (config['width'])
{
this._width = config['width'];
}
if (config['height'])
{
this._height = config['height'];
}
if (config['renderer'])
{
this.renderType = config['renderer'];
}
if (config['parent'])
{
this.parent = config['parent'];
}
if (config['antialias'] !== undefined)
{
this.antialias = config['antialias'];
}
if (config['multiTexture'] !== undefined)
{
this.multiTexture = config['multiTexture'];
}
if (config['resolution'])
{
this.resolution = config['resolution'];
}
if (config['preserveDrawingBuffer'] !== undefined)
{
this.preserveDrawingBuffer = config['preserveDrawingBuffer'];
}
if (config['physicsConfig'])
{
this.physicsConfig = config['physicsConfig'];
}
var seed = [(Date.now() * Math.random()).toString()];
if (config['seed'])
{
seed = config['seed'];
}
this.rnd = new Phaser.RandomDataGenerator(seed);
var state = null;
if (config['state'])
{
state = config['state'];
}
this.state = new Phaser.StateManager(this, state);
},
/**
* Initialize engine sub modules and start the game.
*
* @method Phaser.Game#boot
* @protected
*/
boot: function ()
{
if (this.isBooted)
{
return;
}
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.camera = {
_shake: {
x: 0,
y: 0
}
};
2016-10-14 07:58:12 +00:00
this.updates = new Phaser.UpdateManager(this);
this.scale = new Phaser.ScaleManager(this, this._width, this._height);
2016-11-04 02:08:17 +00:00
// this.stage = new Phaser.Stage(this);
this.setUpRenderer();
this.textures = new Phaser.TextureManager(this);
// this.world = new Phaser.World(this);
2016-10-08 15:31:08 +00:00
2016-11-03 22:26:28 +00:00
// Inject any new Factory helpers that exist in the build
for (var gameobject in Phaser.GameObject)
{
if (Phaser.GameObject[gameobject].hasOwnProperty('FACTORY_KEY'))
{
var key = Phaser.GameObject[gameobject]['FACTORY_KEY'];
// console.log('found', key);
Phaser.GameObject.Factory.prototype[key] = Phaser.GameObject[gameobject]['FACTORY_ADD'];
}
}
this.add = new Phaser.GameObject.Factory(this);
2016-10-08 15:31:08 +00:00
2016-11-04 02:08:17 +00:00
// 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);
2015-07-08 23:19:21 +00:00
this.create = new Phaser.Create(this);
this.plugins = new Phaser.PluginManager(this);
this.net = new Phaser.Net(this);
this.time.boot();
2016-11-04 02:08:17 +00:00
// this.stage.boot();
// this.world.boot();
this.scale.boot();
this.input.boot();
this.sound.boot();
this.state.boot();
2016-10-13 00:54:01 +00:00
// if (this.config['enableDebug'])
// {
// this.debug = new Phaser.Utils.Debug(this);
// this.debug.boot();
// }
// else
// {
this.debug = { preUpdate: function () {}, update: function () {}, reset: function () {} };
2016-10-13 00:54:01 +00:00
// }
this.showDebugHeader();
this.isRunning = true;
if (this.config && this.config['forceSetTimeOut'])
{
this.raf = new Phaser.RequestAnimationFrame(this, this.config['forceSetTimeOut']);
}
else
{
this.raf = new Phaser.RequestAnimationFrame(this, false);
}
this._kickstart = true;
if (window['focus'])
{
if (!window['PhaserGlobal'] || (window['PhaserGlobal'] && !window['PhaserGlobal'].stopFocus))
{
window.focus();
}
}
this.raf.start();
},
2013-10-23 12:15:56 +00:00
/**
* Displays a Phaser version debug header in the console.
*
* @method Phaser.Game#showDebugHeader
* @protected
*/
showDebugHeader: function () {
if (window['PhaserGlobal'] && window['PhaserGlobal'].hideBanner)
{
return;
}
var c = (this.renderType === Phaser.CANVAS) ? 'Canvas' : 'WebGL';
if (!this.device.ie)
{
var args = [
'%c %c %c %c %c Phaser v' + Phaser.VERSION + ' / Pixi.js / ' + c + ' %c http://phaser.io',
'background: #ff0000',
'background: #ffff00',
'background: #00ff00',
'background: #00ffff',
'color: #ffffff; background: #000;',
'background: #fff'
];
console.log.apply(console, args);
}
else if (window['console'])
{
console.log('Phaser v' + Phaser.VERSION + ' / Pixi.js / http://phaser.io');
}
},
/**
* 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 () {
if (this.config['canvas'])
{
this.canvas = this.config['canvas'];
}
else
{
this.canvas = Phaser.Canvas.create(this, this.width, this.height, this.config['canvasID'], true);
}
if (this.config['canvasStyle'])
{
this.canvas.style = this.config['canvasStyle'];
}
else
{
this.canvas.style['-webkit-full-screen'] = 'width: 100%; height: 100%';
}
if (this.renderType === Phaser.HEADLESS || this.renderType === Phaser.CANVAS || (this.renderType === Phaser.AUTO && !this.device.webGL))
{
if (this.device.canvas)
{
// They requested Canvas and their browser supports it
this.renderType = Phaser.CANVAS;
// this.renderer = new PIXI.CanvasRenderer(this);
this.renderer = new Phaser.Renderer.Canvas(this);
this.context = this.renderer.context;
}
else
{
throw new Error('Phaser.Game - Cannot create Canvas or WebGL context, aborting.');
}
}
else
{
// They requested WebGL and their browser supports it
this.renderType = Phaser.WEBGL;
2014-10-11 03:18:42 +00:00
this.renderer = new Phaser.Renderer.WebGL(this);
this.context = null;
// Move to renderer class
this.canvas.addEventListener('webglcontextlost', this.contextLost.bind(this), false);
this.canvas.addEventListener('webglcontextrestored', this.contextRestored.bind(this), false);
}
2016-11-04 02:08:17 +00:00
// if (this.device.cocoonJS)
// {
// this.canvas.screencanvas = (this.renderType === Phaser.CANVAS) ? true : false;
// }
if (this.renderType !== Phaser.HEADLESS)
{
2016-11-04 02:08:17 +00:00
// this.stage.smoothed = this.antialias;
2014-06-05 01:33:13 +00:00
Phaser.Canvas.addToDOM(this.canvas, this.parent, false);
Phaser.Canvas.setTouchAction(this.canvas);
}
},
/**
* Handles WebGL context loss.
*
* @method Phaser.Game#contextLost
* @private
* @param {Event} event - The webglcontextlost event.
*/
contextLost: function (event) {
event.preventDefault();
this.renderer.contextLost = true;
},
/**
* Handles WebGL context restoration.
*
* @method Phaser.Game#contextRestored
* @private
*/
contextRestored: function () {
this.renderer.initContext();
this.cache.clearGLTextures();
this.renderer.contextLost = false;
},
/**
2014-07-09 04:38:59 +00:00
* The core game loop.
*
* @method Phaser.Game#update
* @protected
2014-11-08 19:11:28 +00:00
* @param {number} time - The current time as provided by RequestAnimationFrame.
*/
update: function (time) {
this.time.update(time);
2016-10-14 07:58:12 +00:00
this.updateLogic(this.time.desiredFpsMult);
this.updateRender(this.time.slowMotion * this.time.desiredFps);
return;
/*
if (this._kickstart)
{
this.updateLogic(this.time.desiredFpsMult);
// call the game render update exactly once every frame
this.updateRender(this.time.slowMotion * this.time.desiredFps);
this._kickstart = false;
return;
}
// if the logic time is spiraling upwards, skip a frame entirely
if (this._spiraling > 1 && !this.forceSingleUpdate)
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
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 + 10000;
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
2014-11-08 18:52:02 +00:00
// 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._spiraling = 0;
// call the game render update exactly once every frame
this.updateRender(this.time.slowMotion * this.time.desiredFps);
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
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;
// 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);
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
2014-11-08 18:52:02 +00:00
// call the game update logic multiple times if necessary to "catch up" with dropped frames
// unless forceSingleUpdate is true
var count = 0;
this.updatesThisFrame = Math.floor(this._deltaTime / slowStep);
if (this.forceSingleUpdate)
{
this.updatesThisFrame = Math.min(1, this.updatesThisFrame);
}
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
2014-11-08 18:52:02 +00:00
while (this._deltaTime >= slowStep)
{
this._deltaTime -= slowStep;
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
this.updateLogic(this.time.desiredFpsMult);
2015-02-25 00:59:27 +00:00
count++;
if (this.forceSingleUpdate && count === 1)
{
break;
}
2015-09-08 16:44:28 +00:00
else
{
this.time.refresh();
}
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
2014-11-08 18:52:02 +00:00
}
// detect spiraling (if the catch-up loop isn't fast enough, the number of iterations will increase constantly)
if (count > this._lastCount)
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
2014-11-08 18:52:02 +00:00
{
this._spiraling++;
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
2014-11-08 18:52:02 +00:00
}
else if (count < this._lastCount)
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
2014-11-08 18:52:02 +00:00
{
// looks like it caught up successfully, reset the spiral alert counter
this._spiraling = 0;
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
2014-11-08 18:52:02 +00:00
}
this._lastCount = count;
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
2014-11-08 18:52:02 +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);
}
*/
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
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.
*/
updateLogic: function (timeStep)
{
if (!this._paused && !this.pendingStep)
{
if (this.stepping)
{
this.pendingStep = true;
}
2016-10-14 07:58:12 +00:00
// this.updates.preUpdate();
// this.scale.preUpdate();
// this.debug.preUpdate();
// this.camera.preUpdate();
// this.physics.preUpdate();
2014-11-08 19:11:28 +00:00
this.state.preUpdate(timeStep);
// this.plugins.preUpdate(timeStep);
2016-11-04 02:08:17 +00:00
// this.stage.preUpdate();
this.tweens.update();
this.state.update();
2016-11-04 02:08:17 +00:00
// this.stage.update();
// this.tweens.update();
// this.sound.update();
// this.input.update();
// this.physics.update();
// this.particles.update();
// this.plugins.update();
2016-11-04 02:08:17 +00:00
this.state.postUpdate();
this.plugins.postUpdate();
}
else
{
ScaleManager - orientation - FIX #1306, hopefully, where an orientation change did not correclty cause a screen/layout update. - FIX/CHANGE where Paused games would not update the scale - The new behavior "runs" the ScaleManager in a paused state via `pauseUpdate`; a User paused game will now correctly track scale changes. This is closer to the 2.1.3 behavior in some cases, such as window resizing, when the updates were done in the DOM event. - This change also affects device orientation change monitoring and events, which are also deferred to the update cycle - The update cycle is set to the maximum and is still dependent on the RAF / primary loop running, so it should not affect background apps/tabs - FIX/CHANGE New better backoff timing; ie. continuous window resizing is limited to ~10 fps update calculations. This makes it much harder to crash Chrome by rapidly and continously resizing the window. Also increases the scaling from 0..10..20..40 to 0..25..50..100. - FIX an issue where the incorrect orientation was "one frame behind" the scaling. - UPDATE The contract for when the change orientation events occurs is better defined - it now always happens in the update context as with game sizing. - UPDATE Unifies orientation-change code / handling and duplicate. - CHANGE Added DOM.getScreenOrientation which obtains the orientation via the Device Orientation API (WD) and provides comprehensive fallbacks - This should cover all modern browsers - FIX: Orientation on desktops now computed as screen ratio by default which fixesi the false-portrait chain/detection when the page is made more narrow than it is tall. - CHANGE/FIX: window.orientation is now only used as fallback, if requested (due to device differences). It may be appropriate to enable this (via `scale.compatibility` on boot, for instance) in some environments. Signed-off-by: Paul <pstickne@gmail.com>
2014-11-12 06:30:01 +00:00
// Scaling and device orientation changes are still reflected when paused.
this.scale.pauseUpdate();
this.state.pauseUpdate();
2014-11-21 10:40:18 +00:00
this.debug.preUpdate();
}
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes. We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc) Once per frame calling for rendering and tweening to keep things as smooth as possible Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly. Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs. It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans. Signals to the game program if there is a problem which might be fixed by lowering the desiredFps Time.desiredFps is the new desired frame rate for your game. Time.suggestedFps is the suggested frame rate for the game based on system load. Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on. Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
2014-11-08 18:52:02 +00:00
},
2014-11-12 22:38:51 +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.
*/
updateRender: function (elapsedTime)
{
if (this.lockRender)
{
return;
}
2016-11-04 02:08:17 +00:00
// this.state.preRender(elapsedTime);
2016-10-14 07:58:12 +00:00
this.updates.start();
2016-11-04 02:08:17 +00:00
this.state.render(this.renderer);
2016-11-04 02:08:17 +00:00
// Disabled while building out the new State Manager
// this.renderer.render();
2016-11-04 02:08:17 +00:00
// this.plugins.render(elapsedTime);
// this.state.render(elapsedTime);
// this.plugins.postRender(elapsedTime);
2016-10-14 07:58:12 +00:00
this.updates.stop();
},
/**
* Enable core game loop stepping. When enabled you must call game.step() directly (perhaps via a DOM button?)
* Calling step will advance the game loop by one frame. This is extremely useful for hard to track down errors!
*
* @method Phaser.Game#enableStep
*/
enableStep: function () {
this.stepping = true;
this.pendingStep = false;
this.stepCount = 0;
},
/**
* 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
*/
step: function () {
this.pendingStep = false;
this.stepCount++;
},
/**
* Nukes the entire game from orbit.
2013-10-23 12:15:56 +00:00
*
* Calls destroy on Game.state, Game.sound, Game.scale, Game.stage, Game.input, Game.physics and Game.plugins.
*
* Then sets all of those local handlers to null, destroys the renderer, removes the canvas from the DOM
* and resets the PIXI default renderer.
*
2013-10-02 00:16:40 +00:00
* @method Phaser.Game#destroy
*/
destroy: function () {
this.raf.stop();
this.state.destroy();
this.sound.destroy();
this.scale.destroy();
this.stage.destroy();
this.input.destroy();
this.physics.destroy();
this.plugins.destroy();
this.state = null;
this.sound = null;
this.scale = null;
this.stage = null;
this.input = null;
this.physics = null;
this.plugins = null;
this.cache = null;
this.load = null;
this.time = null;
this.world = null;
this.isBooted = false;
this.renderer.destroy(false);
Phaser.Canvas.removeFromDOM(this.canvas);
PIXI.defaultRenderer = null;
Phaser.GAMES[this.id] = null;
},
/**
* Called by the Stage visibility handler.
*
* @method Phaser.Game#gamePaused
* @param {object} event - The DOM event that caused the game to pause, if any.
* @protected
*/
gamePaused: function (event) {
// If the game is already paused it was done via game code, so don't re-pause it
if (!this._paused)
{
this._paused = true;
this.time.gamePaused();
if (this.sound.muteOnPause)
{
this.sound.setMute();
}
this.onPause.dispatch(event);
// Avoids Cordova iOS crash event: https://github.com/photonstorm/phaser/issues/1800
if (this.device.cordova && this.device.iOS)
{
this.lockRender = true;
}
}
},
/**
* Called by the Stage visibility handler.
*
* @method Phaser.Game#gameResumed
* @param {object} event - The DOM event that caused the game to pause, if any.
* @protected
*/
gameResumed: function (event) {
// Game is paused, but wasn't paused via code, so resume it
if (this._paused && !this._codePaused)
{
this._paused = false;
this.time.gameResumed();
this.input.reset();
if (this.sound.muteOnPause)
{
this.sound.unsetMute();
}
this.onResume.dispatch(event);
// Avoids Cordova iOS crash event: https://github.com/photonstorm/phaser/issues/1800
if (this.device.cordova && this.device.iOS)
{
this.lockRender = false;
}
}
},
/**
* 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);
if (!this.stage.disableVisibilityChange)
{
this.gamePaused(event);
}
},
/**
* 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);
if (!this.stage.disableVisibilityChange)
{
this.gameResumed(event);
}
}
};
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
*/
Object.defineProperty(Phaser.Game.prototype, "paused", {
get: function () {
return this._paused;
},
set: function (value) {
if (value === true)
{
if (this._paused === false)
{
this._paused = true;
this.sound.setMute();
this.time.gamePaused();
this.onPause.dispatch(this);
}
this._codePaused = true;
}
else
{
if (this._paused)
{
this._paused = false;
this.input.reset();
this.sound.unsetMute();
this.time.gameResumed();
this.onResume.dispatch(this);
}
this._codePaused = false;
}
}
});
2013-10-07 09:21:22 +00:00
/**
2015-06-21 23:31:54 +00:00
*
* "Deleted code is debugged code." - Jeff Sickel
*
* ()
*
2013-10-07 09:21:22 +00:00
*/