/*
    http://www.JSON.org/json2.js
    2009-08-17

    Public Domain.

    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.

    See http://www.JSON.org/js.html

    This file creates a global JSON object containing two methods: stringify
    and parse.

        JSON.stringify(value, replacer, space)
            value       any JavaScript value, usually an object or array.

            replacer    an optional parameter that determines how object
                        values are stringified for objects. It can be a
                        function or an array of strings.

            space       an optional parameter that specifies the indentation
                        of nested structures. If it is omitted, the text will
                        be packed without extra whitespace. If it is a number,
                        it will specify the number of spaces to indent at each
                        level. If it is a string (such as '\t' or ' '),
                        it contains the characters used to indent at each level.

            This method produces a JSON text from a JavaScript value.

            When an object value is found, if the object contains a toJSON
            method, its toJSON method will be called and the result will be
            stringified. A toJSON method does not serialize: it returns the
            value represented by the name/value pair that should be serialized,
            or undefined if nothing should be serialized. The toJSON method
            will be passed the key associated with the value, and this will be
            bound to the value

            For example, this would serialize Dates as ISO strings.

                Date.prototype.toJSON = function (key) {
                    function f(n) {
                        // Format integers to have at least two digits.
                        return n < 10 ? '0' + n : n;
                    }

                    return this.getUTCFullYear()   + '-' +
                         f(this.getUTCMonth() + 1) + '-' +
                         f(this.getUTCDate())      + 'T' +
                         f(this.getUTCHours())     + ':' +
                         f(this.getUTCMinutes())   + ':' +
                         f(this.getUTCSeconds())   + 'Z';
                };

            You can provide an optional replacer method. It will be passed the
            key and value of each member, with this bound to the containing
            object. The value that is returned from your method will be
            serialized. If your method returns undefined, then the member will
            be excluded from the serialization.

            If the replacer parameter is an array of strings, then it will be
            used to select the members to be serialized. It filters the results
            such that only members with keys listed in the replacer array are
            stringified.

            Values that do not have JSON representations, such as undefined or
            functions, will not be serialized. Such values in objects will be
            dropped; in arrays they will be replaced with null. You can use
            a replacer function to replace those with JSON values.
            JSON.stringify(undefined) returns undefined.

            The optional space parameter produces a stringification of the
            value that is filled with line breaks and indentation to make it
            easier to read.

            If the space parameter is a non-empty string, then that string will
            be used for indentation. If the space parameter is a number, then
            the indentation will be that many spaces.

            Example:

            text = JSON.stringify(['e', {pluribus: 'unum'}]);
            // text is '["e",{"pluribus":"unum"}]'

            text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
            // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'

            text = JSON.stringify([new Date()], function (key, value) {
                return this[key] instanceof Date ?
                    'Date(' + this[key] + ')' : value;
            });
            // text is '["Date(---current time---)"]'

        JSON.parse(text, reviver)
            This method parses a JSON text to produce an object or array.
            It can throw a SyntaxError exception.

            The optional reviver parameter is a function that can filter and
            transform the results. It receives each of the keys and values,
            and its return value is used instead of the original value.
            If it returns what it received, then the structure is not modified.
            If it returns undefined then the member is deleted.

            Example:

            // Parse the text. Values that look like ISO date strings will
            // be converted to Date objects.

            myData = JSON.parse(text, function (key, value) {
                var a;
                if (typeof value === 'string') {
                    a =
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
                    if (a) {
                        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
                            +a[5], +a[6]));
                    }
                }
                return value;
            });

            myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
                var d;
                if (typeof value === 'string' &&
                        value.slice(0, 5) === 'Date(' &&
                        value.slice(-1) === ')') {
                    d = new Date(value.slice(5, -1));
                    if (d) {
                        return d;
                    }
                }
                return value;
            });

    This is a reference implementation. You are free to copy, modify, or
    redistribute.

    This code should be minified before deployment.
    See http://javascript.crockford.com/jsmin.html

    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
    NOT CONTROL.
*/

/*jslint evil: true */

/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
    lastIndex, length, parse, prototype, push, replace, slice, stringify,
    test, toJSON, toString, valueOf
*/

"use strict";

// Create a JSON object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.

if (!this.JSON) {
    this.JSON = {};
}

(function () {

    function f(n) {
        // Format integers to have at least two digits.
        return n < 10 ? '0' + n : n;
    }

    if (typeof Date.prototype.toJSON !== 'function') {

        Date.prototype.toJSON = function (key) {

            return isFinite(this.valueOf()) ?
                   this.getUTCFullYear()   + '-' +
                 f(this.getUTCMonth() + 1) + '-' +
                 f(this.getUTCDate())      + 'T' +
                 f(this.getUTCHours())     + ':' +
                 f(this.getUTCMinutes())   + ':' +
                 f(this.getUTCSeconds())   + 'Z' : null;
        };

        String.prototype.toJSON =
        Number.prototype.toJSON =
        Boolean.prototype.toJSON = function (key) {
            return this.valueOf();
        };
    }

    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        gap,
        indent,
        meta = {    // table of character substitutions
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        },
        rep;

    function quote(string) {

// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.

        escapable.lastIndex = 0;
        return escapable.test(string) ?
            '"' + string.replace(escapable, function (a) {
                var c = meta[a];
                return typeof c === 'string' ? c :
                    '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
            }) + '"' :
            '"' + string + '"';
    }

    function str(key, holder) {
// Produce a string from holder[key].

        var i,          // The loop counter.
            k,          // The member key.
            v,          // The member value.
            length,
            mind = gap,
            partial,
            value = holder[key];

// If the value has a toJSON method, call it to obtain a replacement value.

        if (value && typeof value === 'object' &&
                typeof value.toJSON === 'function') {
            value = value.toJSON(key);
        }

// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.

        if (typeof rep === 'function') {
            value = rep.call(holder, key, value);
        }

// What happens next depends on the value's type.

        switch (typeof value) {
        case 'string':
            return quote(value);

        case 'number':

// JSON numbers must be finite. Encode non-finite numbers as null.

            return isFinite(value) ? String(value) : 'null';

        case 'boolean':
        case 'null':

// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.

            return String(value);

// If the type is 'object', we might be dealing with an object or an array or
// null.

        case 'object':

// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.

            if (!value) {
                return 'null';
            }

// Make an array to hold the partial results of stringifying this object value.

            gap += indent;
            partial = [];

// Is the value an array?

            if (Object.prototype.toString.apply(value) === '[object Array]') {

// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.

                length = value.length;
                for (i = 0; i < length; i += 1) {
                    partial[i] = str(i, value) || 'null';
                }

// Join all of the elements together, separated with commas, and wrap them in
// brackets.

                v = partial.length === 0 ? '[]' :
                    gap ? '[\n' + gap +
                            partial.join(',\n' + gap) + '\n' +
                                mind + ']' :
                          '[' + partial.join(',') + ']';
                gap = mind;
                return v;
            }

// If the replacer is an array, use it to select the members to be stringified.

            if (rep && typeof rep === 'object') {
                length = rep.length;
                for (i = 0; i < length; i += 1) {
                    k = rep[i];
                    if (typeof k === 'string') {
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
            } else {

// Otherwise, iterate through all of the keys in the object.

                for (k in value) {
                    if (Object.hasOwnProperty.call(value, k)) {
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
            }

// Join all of the member texts together, separated with commas,
// and wrap them in braces.

            v = partial.length === 0 ? '{}' :
                gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
                        mind + '}' : '{' + partial.join(',') + '}';
            gap = mind;
            return v;
        }
    }

// If the JSON object does not yet have a stringify method, give it one.

    if (typeof JSON.stringify !== 'function') {
        JSON.stringify = function (value, replacer, space) {
// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.

            var i;
            gap = '';
            indent = '';

// If the space parameter is a number, make an indent string containing that
// many spaces.

            if (typeof space === 'number') {
                for (i = 0; i < space; i += 1) {
                    indent += ' ';
                }

// If the space parameter is a string, it will be used as the indent string.

            } else if (typeof space === 'string') {
                indent = space;
            }

// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.

            rep = replacer;
            if (replacer && typeof replacer !== 'function' &&
                    (typeof replacer !== 'object' ||
                     typeof replacer.length !== 'number')) {
                throw new Error('JSON.stringify');
            }

// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.

            return str('', {'': value});
        };
    }

// If the JSON object does not yet have a parse method, give it one.

    if (typeof JSON.parse !== 'function') {
        JSON.parse = function (text, reviver) {

// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.

            var j;

            function walk(holder, key) {

// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.

                var k, v, value = holder[key];
                if (value && typeof value === 'object') {
                    for (k in value) {
                        if (Object.hasOwnProperty.call(value, k)) {
                            v = walk(value, k);
                            if (v !== undefined) {
                                value[k] = v;
                            } else {
                                delete value[k];
                            }
                        }
                    }
                }
                return reviver.call(holder, key, value);
            }

// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.

            cx.lastIndex = 0;
            if (cx.test(text)) {
                text = text.replace(cx, function (a) {
                    return '\\u' +
                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
                });
            }

// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.

// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.

            if (/^[\],:{}\s]*$/.
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.

                j = eval('(' + text + ')');

// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.

                return typeof reviver === 'function' ?
                    walk({'': j}, '') : j;
            }

// If the text is not JSON parseable, then a SyntaxError is thrown.

            throw new SyntaxError('JSON.parse');
        };
    }
}());


* Sound.restart and Sound.stop now properly disconnect the sound from the gainNode (or external node) before stopping it, allowing restart to work correctly (thanks @eofs #1796)

* When loading an Audio Sprite from an Asset Pack the wrong Loader method was being used (thanks @boniatillo-com #1777)

* Due to a Pixi 2 issue TileSprite when running under WebGL didn't respect the world alpha setting and would only work with its own alpha (thanks @hanenbro #1774)

* TileSprite now fully supports animation again, having been broken for several versions due to a Pixi upgrade. We've updated the way TileSprites generate their textures internally considerably and animation support is back across both Canvas and WebGL as a result (#1653)

* Setting mute to false on Sound that was never muted caused its volume to be set to zero (thanks @brianbunch #1870)

/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2015 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* The Sound class constructor.
*
* @class Phaser.Sound
* @constructor
* @param {Phaser.Game} game - Reference to the current game instance.
* @param {string} key - Asset key for the sound.
* @param {number} [volume=1] - Default value for the volume, between 0 and 1.
* @param {boolean} [loop=false] - Whether or not the sound will loop.
*/
Phaser.Sound = function (game, key, volume, loop, connect) {

    if (typeof volume === 'undefined') { volume = 1; }
    if (typeof loop === 'undefined') { loop = false; }
    if (typeof connect === 'undefined') { connect = game.sound.connectToMaster; }

    /**
    * A reference to the currently running Game.
    * @property {Phaser.Game} game
    */
    this.game = game;

    /**
    * @property {string} name - Name of the sound.
    */
    this.name = key;

    /**
    * @property {string} key - Asset key for the sound.
    */
    this.key = key;

    /**
    * @property {boolean} loop - Whether or not the sound or current sound marker will loop.
    */
    this.loop = loop;

    /**
    * @property {number} volume - The sound or sound marker volume. A value between 0 (silence) and 1 (full volume).
    */
    this.volume = volume;

    /**
    * @property {object} markers - The sound markers.
    */
    this.markers = {};

    /**
    * @property {AudioContext} context - Reference to the AudioContext instance.
    */
    this.context = null;

    /**
    * @property {boolean} autoplay - Boolean indicating whether the sound should start automatically.
    */
    this.autoplay = false;

    /**
    * @property {number} totalDuration - The total duration of the sound in seconds.
    */
    this.totalDuration = 0;

    /**
    * @property {number} startTime - The time the Sound starts at (typically 0 unless starting from a marker)
    * @default
    */
    this.startTime = 0;

    /**
    * @property {number} currentTime - The current time the sound is at.
    */
    this.currentTime = 0;

    /**
    * @property {number} duration - The duration of the current sound marker in seconds.
    */
    this.duration = 0;

    /**
    * @property {number} durationMS - The duration of the current sound marker in ms.
    */
    this.durationMS = 0;

    /**
    * @property {number} position - The position of the current sound marker.
    */
    this.position = 0;

    /**
    * @property {number} stopTime - The time the sound stopped.
    */
    this.stopTime = 0;

    /**
    * @property {boolean} paused - true if the sound is paused, otherwise false.
    * @default
    */
    this.paused = false;

    /**
    * @property {number} pausedPosition - The position the sound had reached when it was paused.
    */
    this.pausedPosition = 0;

    /**
    * @property {number} pausedTime - The game time at which the sound was paused.
    */
    this.pausedTime = 0;

    /**
    * @property {boolean} isPlaying - true if the sound is currently playing, otherwise false.
    * @default
    */
    this.isPlaying = false;

    /**
    * @property {string} currentMarker - The string ID of the currently playing marker, if any.
    * @default
    */
    this.currentMarker = '';

    /**
    * @property {Phaser.Tween} fadeTween - The tween that fades the audio, set via Sound.fadeIn and Sound.fadeOut.
    */
    this.fadeTween = null;

    /**
    * @property {boolean} pendingPlayback - true if the sound file is pending playback
    * @readonly
    */
    this.pendingPlayback = false;

    /**
    * @property {boolean} override - if true when you play this sound it will always start from the beginning.
    * @default
    */
    this.override = false;

    /**
    * @property {boolean} allowMultiple - This will allow you to have multiple instances of this Sound playing at once. This is only useful when running under Web Audio, and we recommend you implement a local pooling system to not flood the sound channels.
    * @default
    */
    this.allowMultiple = false;

    /**
    * @property {boolean} usingWebAudio - true if this sound is being played with Web Audio.
    * @readonly
    */
    this.usingWebAudio = this.game.sound.usingWebAudio;

    /**
    * @property {boolean} usingAudioTag - true if the sound is being played via the Audio tag.
    */
    this.usingAudioTag = this.game.sound.usingAudioTag;

    /**
    * @property {object} externalNode - If defined this Sound won't connect to the SoundManager master gain node, but will instead connect to externalNode.
    */
    this.externalNode = null;

    /**
    * @property {object} masterGainNode - The master gain node in a Web Audio system.
    */
    this.masterGainNode = null;

    /**
    * @property {object} gainNode - The gain node in a Web Audio system.
    */
    this.gainNode = null;

    /**
    * @property {object} _sound - Internal var.
    * @private
    */
    this._sound = null;

    if (this.usingWebAudio)
    {
        this.context = this.game.sound.context;
        this.masterGainNode = this.game.sound.masterGain;

        if (typeof this.context.createGain === 'undefined')
        {
            this.gainNode = this.context.createGainNode();
        }
        else
        {
            this.gainNode = this.context.createGain();
        }

        this.gainNode.gain.value = volume * this.game.sound.volume;

        if (connect)
        {
            this.gainNode.connect(this.masterGainNode);
        }
    }
    else if (this.usingAudioTag)
    {
        if (this.game.cache.getSound(key) && this.game.cache.isSoundReady(key))
        {
            this._sound = this.game.cache.getSoundData(key);
            this.totalDuration = 0;

            if (this._sound.duration)
            {
                this.totalDuration = this._sound.duration;
            }
        }
        else
        {
            this.game.cache.onSoundUnlock.add(this.soundHasUnlocked, this);
        }
    }

    /**
    * @property {Phaser.Signal} onDecoded - The onDecoded event is dispatched when the sound has finished decoding (typically for mp3 files)
    */
    this.onDecoded = new Phaser.Signal();

    /**
    * @property {Phaser.Signal} onPlay - The onPlay event is dispatched each time this sound is played.
    */
    this.onPlay = new Phaser.Signal();

    /**
    * @property {Phaser.Signal} onPause - The onPause event is dispatched when this sound is paused.
    */
    this.onPause = new Phaser.Signal();

    /**
    * @property {Phaser.Signal} onResume - The onResume event is dispatched when this sound is resumed from a paused state.
    */
    this.onResume = new Phaser.Signal();

    /**
    * @property {Phaser.Signal} onLoop - The onLoop event is dispatched when this sound loops during playback.
    */
    this.onLoop = new Phaser.Signal();

    /**
    * @property {Phaser.Signal} onStop - The onStop event is dispatched when this sound stops playback.
    */
    this.onStop = new Phaser.Signal();

    /**
    * @property {Phaser.Signal} onMute - The onMouse event is dispatched when this sound is muted.
    */
    this.onMute = new Phaser.Signal();

    /**
    * @property {Phaser.Signal} onMarkerComplete - The onMarkerComplete event is dispatched when a marker within this sound completes playback.
    */
    this.onMarkerComplete = new Phaser.Signal();

    /**
    * @property {Phaser.Signal} onFadeComplete - The onFadeComplete event is dispatched when this sound finishes fading either in or out.
    */
    this.onFadeComplete = new Phaser.Signal();

    /**
    * @property {number} _volume - The global audio volume. A value between 0 (silence) and 1 (full volume).
    * @private
    */
    this._volume = volume;

    /**
    * @property {any} _buffer - Decoded data buffer / Audio tag.
    * @private
    */
    this._buffer = null;

    /**
    * @property {boolean} _muted - Boolean indicating whether the sound is muted or not.
    * @private
    */
    this._muted = false;

    /**
    * @property {number} _tempMarker - Internal marker var.
    * @private
    */
    this._tempMarker = 0;

    /**
    * @property {number} _tempPosition - Internal marker var.
    * @private
    */
    this._tempPosition = 0;

    /**
    * @property {number} _tempVolume - Internal marker var.
    * @private
    */
    this._tempVolume = 0;

    /**
    * @property {number} _muteVolume - Internal cache var.
    * @private
    */
    this._muteVolume = 0;

    /**
    * @property {boolean} _tempLoop - Internal cache var.
    * @private
    */
    this._tempLoop = 0;

    /**
    * @property {boolean} _paused - Was this sound paused via code or a game event?
    * @private
    */
    this._paused = false;

    /**
    * @property {boolean} _onDecodedEventDispatched - Was the onDecoded event dispatched?
    * @private
    */
    this._onDecodedEventDispatched = false;

};

Phaser.Sound.prototype = {

    /**
    * Called automatically when this sound is unlocked.
    * @method Phaser.Sound#soundHasUnlocked
    * @param {string} key - The Phaser.Cache key of the sound file to check for decoding.
    * @protected
    */
    soundHasUnlocked: function (key) {

        if (key === this.key)
        {
            this._sound = this.game.cache.getSoundData(this.key);
            this.totalDuration = this._sound.duration;
        }

    },

    /**
    * Adds a marker into the current Sound. A marker is represented by a unique key and a start time and duration.
    * This allows you to bundle multiple sounds together into a single audio file and use markers to jump between them for playback.
    *
    * @method Phaser.Sound#addMarker
    * @param {string} name - A unique name for this marker, i.e. 'explosion', 'gunshot', etc.
    * @param {number} start - The start point of this marker in the audio file, given in seconds. 2.5 = 2500ms, 0.5 = 500ms, etc.
    * @param {number} duration - The duration of the marker in seconds. 2.5 = 2500ms, 0.5 = 500ms, etc.
    * @param {number} [volume=1] - The volume the sound will play back at, between 0 (silent) and 1 (full volume).
    * @param {boolean} [loop=false] - Sets if the sound will loop or not.
    */
    addMarker: function (name, start, duration, volume, loop) {

        if (typeof volume === 'undefined' || volume === null) { volume = 1; }
        if (typeof loop === 'undefined') { loop = false; }

        this.markers[name] = {
            name: name,
            start: start,
            stop: start + duration,
            volume: volume,
            duration: duration,
            durationMS: duration * 1000,
            loop: loop
        };

    },

    /**
    * Removes a marker from the sound.
    * @method Phaser.Sound#removeMarker
    * @param {string} name - The key of the marker to remove.
    */
    removeMarker: function (name) {

        delete this.markers[name];

    },

    /**
    * Called automatically by the AudioContext when the sound stops playing.
    * Doesn't get called if the sound is set to loop or is a section of an Audio Sprite.
    *
    * @method Phaser.Sound#onEndedHandler
    * @protected
    */
    onEndedHandler: function () {

        this.isPlaying = false;
        this.stop();

    },

    /**
    * Called automatically by Phaser.SoundManager.
    * @method Phaser.Sound#update
    * @protected
    */
    update: function () {

        if (this.isDecoded && !this._onDecodedEventDispatched)
        {
            this.onDecoded.dispatch(this);
            this._onDecodedEventDispatched = true;
        }

        if (this.pendingPlayback && this.game.cache.isSoundReady(this.key))
        {
            this.pendingPlayback = false;
            this.play(this._tempMarker, this._tempPosition, this._tempVolume, this._tempLoop);
        }

        if (this.isPlaying)
        {
            this.currentTime = this.game.time.time - this.startTime;

            if (this.currentTime >= this.durationMS)
            {
                if (this.usingWebAudio)
                {
                    if (this.loop)
                    {
                        //  won't work with markers, needs to reset the position
                        this.onLoop.dispatch(this);

                        if (this.currentMarker === '')
                        {
                            this.currentTime = 0;
                            this.startTime = this.game.time.time;
                        }
                        else
                        {
                            this.onMarkerComplete.dispatch(this.currentMarker, this);
                            this.play(this.currentMarker, 0, this.volume, true, true);
                        }
                    }
                    else
                    {
                        //  Stop if we're using an audio marker, otherwise we let onended handle it
                        if (this.currentMarker !== '')
                        {
                            this.stop();
                        }
                    }
                }
                else
                {
                    if (this.loop)
                    {
                        this.onLoop.dispatch(this);
                        this.play(this.currentMarker, 0, this.volume, true, true);
                    }
                    else
                    {
                        this.stop();
                    }
                }
            }
        }
    },

    /**
     * Loops this entire sound. If you need to loop a section of it then use Sound.play and the marker and loop parameters.
     *
     * @method Phaser.Sound#loopFull
     * @param {number} [volume=1] - Volume of the sound you want to play. If none is given it will use the volume given to the Sound when it was created (which defaults to 1 if none was specified).
     * @return {Phaser.Sound} This sound instance.
     */
    loopFull: function (volume) {

        this.play(null, 0, volume, true);

    },

    /**
    * Play this sound, or a marked section of it.
    *
    * @method Phaser.Sound#play
    * @param {string} [marker=''] - If you want to play a marker then give the key here, otherwise leave blank to play the full sound.
    * @param {number} [position=0] - The starting position to play the sound from - this is ignored if you provide a marker.
    * @param {number} [volume=1] - Volume of the sound you want to play. If none is given it will use the volume given to the Sound when it was created (which defaults to 1 if none was specified).
    * @param {boolean} [loop=false] - Loop when finished playing? If not using a marker / audio sprite the looping will be done via the WebAudio loop property, otherwise it's time based.
    * @param {boolean} [forceRestart=true] - If the sound is already playing you can set forceRestart to restart it from the beginning.
    * @return {Phaser.Sound} This sound instance.
    */
    play: function (marker, position, volume, loop, forceRestart) {

        if (typeof marker === 'undefined' || marker === false || marker === null) { marker = ''; }
        if (typeof forceRestart === 'undefined') { forceRestart = true; }

        if (this.isPlaying && !this.allowMultiple && !forceRestart && !this.override)
        {
            //  Use Restart instead
            return this;
        }

        if (this._sound && this.isPlaying && !this.allowMultiple && (this.override || forceRestart))
        {
            if (this.usingWebAudio)
            {
                if (this.externalNode)
                {
                    this._sound.disconnect(this.externalNode);
                }
                else
                {
                    this._sound.disconnect(this.gainNode);
                }

                if (typeof this._sound.stop === 'undefined')
                {
                    this._sound.noteOff(0);
                }
                else
                {
                    try {
                        this._sound.stop(0);
                    }
                    catch (e) {
                    }
                }
            }
            else if (this.usingAudioTag)
            {
                this._sound.pause();
                this._sound.currentTime = 0;
            }
        }

        if (marker === '' && Object.keys(this.markers).length > 0)
        {
            //  If they didn't specify a marker but this is an audio sprite,
            //  we should never play the entire thing
            return this;
        }

        if (marker !== '')
        {
            this.currentMarker = marker;

            if (this.markers[marker])
            {
                //  Playing a marker? Then we default to the marker values
                this.position = this.markers[marker].start;
                this.volume = this.markers[marker].volume;
                this.loop = this.markers[marker].loop;
                this.duration = this.markers[marker].duration;
                this.durationMS = this.markers[marker].durationMS;

                if (typeof volume !== 'undefined')
                {
                    this.volume = volume;
                }

                if (typeof loop !== 'undefined')
                {
                    this.loop = loop;
                }

                this._tempMarker = marker;
                this._tempPosition = this.position;
                this._tempVolume = this.volume;
                this._tempLoop = this.loop;
            }
            else
            {
                // console.warn("Phaser.Sound.play: audio marker " + marker + " doesn't exist");
                return this;
            }
        }
        else
        {
            position = position || 0;

            if (typeof volume === 'undefined') { volume = this._volume; }
            if (typeof loop === 'undefined') { loop = this.loop; }

            this.position = position;
            this.volume = volume;
            this.loop = loop;
            this.duration = 0;
            this.durationMS = 0;

            this._tempMarker = marker;
            this._tempPosition = position;
            this._tempVolume = volume;
            this._tempLoop = loop;
        }

        if (this.usingWebAudio)
        {
            //  Does the sound need decoding?
            if (this.game.cache.isSoundDecoded(this.key))
            {
                this._sound = this.context.createBufferSource();

                if (this.externalNode)
                {
                    this._sound.connect(this.externalNode);
                }
                else
                {
                    this._sound.connect(this.gainNode);
                }

                this._buffer = this.game.cache.getSoundData(this.key);
                this._sound.buffer = this._buffer;

                if (this.loop && marker === '')
                {
                    this._sound.loop = true;
                }

                if (!this.loop && marker === '')
                {
                    this._sound.onended = this.onEndedHandler.bind(this);
                }

                this.totalDuration = this._sound.buffer.duration;

                if (this.duration === 0)
                {
                    this.duration = this.totalDuration;
                    this.durationMS = Math.ceil(this.totalDuration * 1000);
                }

                //  Useful to cache this somewhere perhaps?
                if (typeof this._sound.start === 'undefined')
                {
                    this._sound.noteGrainOn(0, this.position, this.duration);
                }
                else
                {
                    if (this.loop && marker === '')
                    {
                        this._sound.start(0, 0);
                    }
                    else
                    {
                        this._sound.start(0, this.position, this.duration);
                    }
                }

                this.isPlaying = true;
                this.startTime = this.game.time.time;
                this.currentTime = 0;
                this.stopTime = this.startTime + this.durationMS;
                this.onPlay.dispatch(this);
            }
            else
            {
                this.pendingPlayback = true;

                if (this.game.cache.getSound(this.key) && this.game.cache.getSound(this.key).isDecoding === false)
                {
                    this.game.sound.decode(this.key, this);
                }
            }
        }
        else
        {
            if (this.game.cache.getSound(this.key) && this.game.cache.getSound(this.key).locked)
            {
                this.game.cache.reloadSound(this.key);
                this.pendingPlayback = true;
            }
            else
            {
                if (this._sound && (this.game.device.cocoonJS || this._sound.readyState === 4))
                {
                    this._sound.play();
                    //  This doesn't become available until you call play(), wonderful ...
                    this.totalDuration = this._sound.duration;

                    if (this.duration === 0)
                    {
                        this.duration = this.totalDuration;
                        this.durationMS = this.totalDuration * 1000;
                    }

                    this._sound.currentTime = this.position;
                    this._sound.muted = this._muted;

                    if (this._muted)
                    {
                        this._sound.volume = 0;
                    }
                    else
                    {
                        this._sound.volume = this._volume;
                    }

                    this.isPlaying = true;
                    this.startTime = this.game.time.time;
                    this.currentTime = 0;
                    this.stopTime = this.startTime + this.durationMS;
                    this.onPlay.dispatch(this);
                }
                else
                {
                    this.pendingPlayback = true;
                }
            }
        }

        return this;

    },

    /**
    * Restart the sound, or a marked section of it.
    *
    * @method Phaser.Sound#restart
    * @param {string} [marker=''] - If you want to play a marker then give the key here, otherwise leave blank to play the full sound.
    * @param {number} [position=0] - The starting position to play the sound from - this is ignored if you provide a marker.
    * @param {number} [volume=1] - Volume of the sound you want to play.
    * @param {boolean} [loop=false] - Loop when it finished playing?
    */
    restart: function (marker, position, volume, loop) {

        marker = marker || '';
        position = position || 0;
        volume = volume || 1;
        if (typeof loop === 'undefined') { loop = false; }

        this.play(marker, position, volume, loop, true);

    },

    /**
    * Pauses the sound.
    *
    * @method Phaser.Sound#pause
    */
    pause: function () {

        if (this.isPlaying && this._sound)
        {
            this.paused = true;
            this.pausedPosition = this.currentTime;
            this.pausedTime = this.game.time.time;
            this.onPause.dispatch(this);
            this.stop();
        }

    },

    /**
    * Resumes the sound.
    *
    * @method Phaser.Sound#resume
    */
    resume: function () {

        if (this.paused && this._sound)
        {
            if (this.usingWebAudio)
            {
                var p = this.position + (this.pausedPosition / 1000);

                this._sound = this.context.createBufferSource();
                this._sound.buffer = this._buffer;

                if (this.externalNode)
                {
                    this._sound.connect(this.externalNode);
                }
                else
                {
                    this._sound.connect(this.gainNode);
                }

                if (this.loop)
                {
                    this._sound.loop = true;
                }

                if (!this.loop && this.currentMarker === '')
                {
                    this._sound.onended = this.onEndedHandler.bind(this);
                }

                var duration = this.duration - (this.pausedPosition / 1000);

                if (typeof this._sound.start === 'undefined')
                {
                    this._sound.noteGrainOn(0, p, duration);
                    //this._sound.noteOn(0); // the zero is vitally important, crashes iOS6 without it
                }
                else
                {
                    if (this.loop && this.game.device.chrome)
                    {
                        //  Handle chrome bug: https://code.google.com/p/chromium/issues/detail?id=457099
                        if (this.game.device.chromeVersion === 42)
                        {
                            this._sound.start(0);
                        }
                        else
                        {
                            this._sound.start(0, p);
                        }
                    }
                    else
                    {
                        this._sound.start(0, p, duration);
                    }
                }
            }
            else
            {
                this._sound.play();
            }

            this.isPlaying = true;
            this.paused = false;
            this.startTime += (this.game.time.time - this.pausedTime);
            this.onResume.dispatch(this);
        }

    },

    /**
    * Stop playing this sound.
    *
    * @method Phaser.Sound#stop
    */
    stop: function () {

        if (this.isPlaying && this._sound)
        {
            if (this.usingWebAudio)
            {
                if (this.externalNode)
                {
                    this._sound.disconnect(this.externalNode);
                }
                else
                {
                    this._sound.disconnect(this.gainNode);
                }

                if (typeof this._sound.stop === 'undefined')
                {
                    this._sound.noteOff(0);
                }
                else
                {
                    try {
                        this._sound.stop(0);
                    }
                    catch (e)
                    {
                        //  Thanks Android 4.4
                    }
                }
            }
            else if (this.usingAudioTag)
            {
                this._sound.pause();
                this._sound.currentTime = 0;
            }
        }

        this.pendingPlayback = false;
        this.isPlaying = false;
        var prevMarker = this.currentMarker;

        if (this.currentMarker !== '')
        {
            this.onMarkerComplete.dispatch(this.currentMarker, this);
        }

        this.currentMarker = '';

        if (this.fadeTween !== null)
        {
            this.fadeTween.stop();
        }

        if (!this.paused)
        {
            this.onStop.dispatch(this, prevMarker);
        }

    },

    /**
     * Starts this sound playing (or restarts it if already doing so) and sets the volume to zero.
     * Then increases the volume from 0 to 1 over the duration specified.
     *
     * At the end of the fade Sound.onFadeComplete is dispatched with this Sound object as the first parameter,
     * and the final volume (1) as the second parameter.
     *
     * @method Phaser.Sound#fadeIn
     * @param {number} [duration=1000] - The time in milliseconds over which the Sound should fade in.
     * @param {boolean} [loop=false] - Should the Sound be set to loop? Note that this doesn't cause the fade to repeat.
     * @param {string} [marker=(current marker)] - The marker to start at; defaults to the current (last played) marker. To start playing from the beginning specify specify a marker of `''`.
     */
    fadeIn: function (duration, loop, marker) {

        if (typeof loop === 'undefined') { loop = false; }
        if (typeof marker === 'undefined') { marker = this.currentMarker; }

        if (this.paused)
        {
            return;
        }

        this.play(marker, 0, 0, loop);

        this.fadeTo(duration, 1);

    },

    /**
     * Decreases the volume of this Sound from its current value to 0 over the duration specified.
     * At the end of the fade Sound.onFadeComplete is dispatched with this Sound object as the first parameter,
     * and the final volume (0) as the second parameter.
     *
     * @method Phaser.Sound#fadeOut
     * @param {number} [duration=1000] - The time in milliseconds over which the Sound should fade out.
     */
    fadeOut: function (duration) {

        this.fadeTo(duration, 0);

    },

    /**
     * Fades the volume of this Sound from its current value to the given volume over the duration specified.
     * At the end of the fade Sound.onFadeComplete is dispatched with this Sound object as the first parameter,
     * and the final volume (volume) as the second parameter.
     *
     * @method Phaser.Sound#fadeTo
     * @param {number} [duration=1000] - The time in milliseconds during which the Sound should fade out.
     * @param {number} [volume] - The volume which the Sound should fade to. This is a value between 0 and 1.
     */
    fadeTo: function (duration, volume) {

        if (!this.isPlaying || this.paused || volume === this.volume)
        {
            return;
        }

        if (typeof duration === 'undefined') { duration = 1000; }

        if (typeof volume === 'undefined')
        {
            console.warn("Phaser.Sound.fadeTo: No Volume Specified.");
            return;
        }

        this.fadeTween = this.game.add.tween(this).to( { volume: volume }, duration, Phaser.Easing.Linear.None, true);

        this.fadeTween.onComplete.add(this.fadeComplete, this);

    },

    /**
     * Internal handler for Sound.fadeIn, Sound.fadeOut and Sound.fadeTo.
     *
     * @method Phaser.Sound#fadeComplete
     * @private
     */
    fadeComplete: function () {

        this.onFadeComplete.dispatch(this, this.volume);

        if (this.volume === 0)
        {
            this.stop();
        }

    },

    /**
    * Destroys this sound and all associated events and removes it from the SoundManager.
    *
    * @method Phaser.Sound#destroy
    * @param {boolean} [remove=true] - If true this Sound is automatically removed from the SoundManager.
    */
    destroy: function (remove) {

        if (typeof remove === 'undefined') { remove = true; }

        this.stop();

        if (remove)
        {
            this.game.sound.remove(this);
        }
        else
        {
            this.markers = {};
            this.context = null;
            this._buffer = null;
            this.externalNode = null;

            this.onDecoded.dispose();
            this.onPlay.dispose();
            this.onPause.dispose();
            this.onResume.dispose();
            this.onLoop.dispose();
            this.onStop.dispose();
            this.onMute.dispose();
            this.onMarkerComplete.dispose();
        }

    }

};

Phaser.Sound.prototype.constructor = Phaser.Sound;

/**
* @name Phaser.Sound#isDecoding
* @property {boolean} isDecoding - Returns true if the sound file is still decoding.
* @readonly
*/
Object.defineProperty(Phaser.Sound.prototype, "isDecoding", {

    get: function () {
        return this.game.cache.getSound(this.key).isDecoding;
    }

});

/**
* @name Phaser.Sound#isDecoded
* @property {boolean} isDecoded - Returns true if the sound file has decoded.
* @readonly
*/
Object.defineProperty(Phaser.Sound.prototype, "isDecoded", {

    get: function () {
        return this.game.cache.isSoundDecoded(this.key);
    }

});

/**
* @name Phaser.Sound#mute
* @property {boolean} mute - Gets or sets the muted state of this sound.
*/
Object.defineProperty(Phaser.Sound.prototype, "mute", {

    get: function () {

        return (this._muted || this.game.sound.mute);

    },

    set: function (value) {

        value = value || null;

        if (value)
        {
            this._muted = true;

            if (this.usingWebAudio)
            {
                this._muteVolume = this.gainNode.gain.value;
                this.gainNode.gain.value = 0;
            }
            else if (this.usingAudioTag && this._sound)
            {
                this._muteVolume = this._sound.volume;
                this._sound.volume = 0;
            }
        }
        else
        {
            this._muted = false;

            if (this.usingWebAudio)
            {
                this.gainNode.gain.value = this._muteVolume;
            }
            else if (this.usingAudioTag && this._sound)
            {
                this._sound.volume = this._muteVolume;
            }
        }

        this.onMute.dispatch(this);

    }

});

/**
* @name Phaser.Sound#volume
* @property {number} volume - Gets or sets the volume of this sound, a value between 0 and 1.
* @readonly
*/
Object.defineProperty(Phaser.Sound.prototype, "volume", {

    get: function () {
        return this._volume;
    },

    set: function (value) {

        if (this.usingWebAudio)
        {
            this._volume = value;
            this.gainNode.gain.value = value;
        }
        else if (this.usingAudioTag && this._sound)
        {
            //  Causes an Index size error in Firefox if you don't clamp the value
            if (value >= 0 && value <= 1)
            {
                this._volume = value;
                this._sound.volume = value;
            }
        }
    }

});


<!DOCTYPE html>

	<meta charset="utf-8">
	<title>Phaser Source: src/physics/ninja/Tile.js</title>

	<link type="text/css" rel="stylesheet" href="styles/default.css">

	<link type="text/css" rel="stylesheet" href="styles/sunlight.default.css">

	<link type="text/css" rel="stylesheet" href="styles/site.cerulean.css">

			Phaser API

					Namespaces

							Phaser

							PIXI

					Classes

							Matrix

							Animation

							AnimationManager

							AnimationParser

							ArrayList

							ArraySet

							ArrayUtils

							AudioSprite

							BitmapData

							BitmapText

							Button

							Cache

							Camera

							Canvas

							Circle

							Color

							Angle

							Animation

							AutoCull

							Bounds

							BringToTop

							Core

							Crop

							Delta

							Destroy

							FixedToCamera

							Health

							InCamera

							InputEnabled

							InWorld

							LifeSpan

							LoadTexture

							Overlap

							PhysicsBody

							Reset

							ScaleMinMax

							Smoothed

							Device

							DOM

							Easing

							Back

							Bounce

							Circular

							Cubic

							Elastic

							Exponential

							Linear

							Quadratic

							Quartic

							Quintic

							Sinusoidal

							Ellipse

							Events

							Filter

							FlexGrid

							FlexLayer

							Frame

							FrameData

							Game

							GameObjectCreator

							GameObjectFactory

							Gamepad

							GamepadButton

							Graphics

							Group

							Image

							Input

							InputHandler

							Key

							Keyboard

							Line

							LinkedList

							Loader

							LoaderParser

							Math

							Mouse

							MSPointer

							Net

							Particle

							Particles

							Arcade

							Emitter

							Physics

							Arcade

							Body

							TilemapCollision

							Ninja

							AABB

							Body

							Circle

							Tile

							P2

							Body

							BodyDebug

							CollisionGroup

							ContactMaterial

							DistanceConstraint

							FixtureList

							GearConstraint

							InversePointProxy

							LockConstraint

							Material

							PointProxy

							PrismaticConstraint

							RevoluteConstraint

							RotationalSpring

							Spring

							Plugin

							PluginManager

							Point

							Pointer

							Polygon

							QuadTree

							RandomDataGenerator

							Rectangle

							RenderTexture

							RequestAnimationFrame

							RetroFont

							Rope

							ScaleManager

							Signal

							SignalBinding

							SinglePad

							Sound

							SoundManager

							Sprite

							SpriteBatch

							Stage

							State

							StateManager

							Text

							Tile

							Tilemap

							TilemapLayer

							TilemapParser

							Tileset

							TileSprite

							Time

							Timer

							TimerEvent

							Touch

							Tween

							TweenData

							TweenManager

							Utils

							Debug

							World

							AbstractFilter

							BaseTexture

							BitmapText

							CanvasBuffer

							CanvasGraphics

							CanvasMaskManager

							CanvasRenderer

							CanvasTinter

							ComplexPrimitiveShader

							DisplayObject

							DisplayObjectContainer

							Event

							EventTarget

							FilterTexture

							Graphics

							GraphicsData

							PIXI

							PixiFastShader

							PixiShader

							PolyK

							PrimitiveShader

							RenderTexture

							Rope

							Sprite

							SpriteBatch

							Stage

							Strip

							StripShader

							Text

							Texture

							TilingSprite

							VideoTexture

							WebGLBlendModeManager

							WebGLFastSpriteBatch

							WebGLFilterManager

							WebGLRenderer

							RoundedRectangle

					Global

							append

							apply

							applyInverse

							blendModes

							clone

							contains

							fromArray

							identity

							rotate

							scale

							scaleModes

							sort

							toArray

							translate

					Core

Game

Group

World

Loader

Time

Camera

State Manager

Tween Manager

Sound Manager

Input Manager

Scale Manager

					Game Objects

Factory (game.add)

Creator (game.make)

Sprite

Image

Sound

Particle Emitter

Particle

Text

Tween

BitmapText

Tilemap

BitmapData

RetroFont

Button

Animation

Graphics

RenderTexture

TileSprite

					Geometry

Circle

Rectangle

Point

Line

Ellipse

Polygon

					Physics

Arcade Physics

Body

P2 Physics

Body

Spring

CollisionGroup

ContactMaterial

Ninja Physics

Body

					Input

Input Handler

Pointer

Mouse

Keyboard

Key

Gamepad

					Community

Phaser Web Site

Phaser Github

Phaser Examples

Phaser Plugins

Forum

Stack Overflow

Weekly Coding Tips

Newsletter

Twitter

IRC

Donate to the project

Texture Packer

Source: src/physics/ninja/Tile.js

/* jshint camelcase: false */
/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2015 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* Ninja Physics Tile constructor.
* A Tile is defined by its width, height and type. It's type can include slope data, such as 45 degree slopes, or convex slopes.
* Understand that for any type including a slope (types 2 to 29) the Tile must be SQUARE, i.e. have an equal width and height.
* Also note that as Tiles are primarily used for levels they have gravity disabled and world bounds collision disabled by default.
*
* Note: This class could be massively optimised and reduced in size. I leave that challenge up to you.
*
* @class Phaser.Physics.Ninja.Tile
* @constructor
* @param {Phaser.Physics.Ninja.Body} body - The body that owns this shape.
* @param {number} x - The x coordinate to create this shape at.
* @param {number} y - The y coordinate to create this shape at.
* @param {number} width - The width of this AABB.
* @param {number} height - The height of this AABB.
* @param {number} [type=1] - The type of Ninja shape to create. 1 = AABB, 2 = Circle or 3 = Tile.
*/
Phaser.Physics.Ninja.Tile = function (body, x, y, width, height, type) {

    if (typeof type === 'undefined') { type = Phaser.Physics.Ninja.Tile.EMPTY; }

    /**
    * @property {Phaser.Physics.Ninja.Body} system - A reference to the body that owns this shape.
    */
    this.body = body;

    /**
    * @property {Phaser.Physics.Ninja} system - A reference to the physics system.
    */
    this.system = body.system;

    /**
    * @property {number} id - The ID of this Tile.
    * @readonly
    */
    this.id = type;

    /**
    * @property {number} type - The type of this Tile.
    * @readonly
    */
    this.type = Phaser.Physics.Ninja.Tile.TYPE_EMPTY;

    /**
    * @property {Phaser.Point} pos - The position of this object.
    */
    this.pos = new Phaser.Point(x, y);

    /**
    * @property {Phaser.Point} oldpos - The position of this object in the previous update.
    */
    this.oldpos = new Phaser.Point(x, y);

    if (this.id > 1 && this.id < 30)
    {
        //  Tile Types 2 to 29 require square tile dimensions, so use the width as the base
        height = width;
    }

    /**
    * @property {number} xw - Half the width.
    * @readonly
    */
    this.xw = Math.abs(width / 2);

    /**
    * @property {number} xw - Half the height.
    * @readonly
    */
    this.yw = Math.abs(height / 2);

    /**
    * @property {number} width - The width.
    * @readonly
    */
    this.width = width;

    /**
    * @property {number} height - The height.
    * @readonly
    */
    this.height = height;

    /**
    * @property {Phaser.Point} velocity - The velocity of this object.
    */
    this.velocity = new Phaser.Point();

    /**
    * @property {number} signx - Internal var.
    * @private
    */
    this.signx = 0;

    /**
    * @property {number} signy - Internal var.
    * @private
    */
    this.signy = 0;

    /**
    * @property {number} sx - Internal var.
    * @private
    */
    this.sx = 0;

    /**
    * @property {number} sy - Internal var.
    * @private
    */
    this.sy = 0;

    //  By default Tiles disable gravity and world bounds collision
    this.body.gravityScale = 0;
    this.body.collideWorldBounds = false;

    if (this.id > 0)
    {
        this.setType(this.id);
    }

};

Phaser.Physics.Ninja.Tile.prototype.constructor = Phaser.Physics.Ninja.Tile;

Phaser.Physics.Ninja.Tile.prototype = {

    /**
    * Updates this objects position.
    *
    * @method Phaser.Physics.Ninja.Tile#integrate
    */
    integrate: function () {

        var px = this.pos.x;
        var py = this.pos.y;

        this.pos.x += (this.body.drag * this.pos.x) - (this.body.drag * this.oldpos.x);
        this.pos.y += (this.body.drag * this.pos.y) - (this.body.drag * this.oldpos.y) + (this.system.gravity * this.body.gravityScale);

        this.velocity.set(this.pos.x - px, this.pos.y - py);
        this.oldpos.set(px, py);

    },

    /**
    * Tiles cannot collide with the world bounds, it's up to you to keep them where you want them. But we need this API stub to satisfy the Body.
    *
    * @method Phaser.Physics.Ninja.Tile#collideWorldBounds
    */
    collideWorldBounds: function () {

        var dx = this.system.bounds.x - (this.pos.x - this.xw);

        if (0 < dx)
        {
            this.reportCollisionVsWorld(dx, 0, 1, 0, null);
        }
        else
        {
            dx = (this.pos.x + this.xw) - this.system.bounds.right;

            if (0 < dx)
            {
                this.reportCollisionVsWorld(-dx, 0, -1, 0, null);
            }
        }

        var dy = this.system.bounds.y - (this.pos.y - this.yw);

        if (0 < dy)
        {
            this.reportCollisionVsWorld(0, dy, 0, 1, null);
        }
        else
        {
            dy = (this.pos.y + this.yw) - this.system.bounds.bottom;

            if (0 < dy)
            {
                this.reportCollisionVsWorld(0, -dy, 0, -1, null);
            }
        }

    },

    /**
    * Process a world collision and apply the resulting forces.
    *
    * @method Phaser.Physics.Ninja.Tile#reportCollisionVsWorld
    * @param {number} px - The tangent velocity
    * @param {number} py - The tangent velocity
    * @param {number} dx - Collision normal
    * @param {number} dy - Collision normal
    * @param {number} obj - Object this Tile collided with
    */
    reportCollisionVsWorld: function (px, py, dx, dy) {
        var p = this.pos;
        var o = this.oldpos;

        //  Calc velocity
        var vx = p.x - o.x;
        var vy = p.y - o.y;

        //  Find component of velocity parallel to collision normal
        var dp = (vx * dx + vy * dy);
        var nx = dp * dx;   //project velocity onto collision normal

        var ny = dp * dy;   //nx,ny is normal velocity

        var tx = vx - nx;   //px,py is tangent velocity
        var ty = vy - ny;

        //  We only want to apply collision response forces if the object is travelling into, and not out of, the collision
        var b, bx, by, fx, fy;

        if (dp < 0)
        {
            fx = tx * this.body.friction;
            fy = ty * this.body.friction;

            b = 1 + this.body.bounce;

            bx = (nx * b);
            by = (ny * b);

            if (dx === 1)
            {
                this.body.touching.left = true;
            }
            else if (dx === -1)
            {
                this.body.touching.right = true;
            }

            if (dy === 1)
            {
                this.body.touching.up = true;
            }
            else if (dy === -1)
            {
                this.body.touching.down = true;
            }
        }
        else
        {
            //  Moving out of collision, do not apply forces
            bx = by = fx = fy = 0;
        }

        //  Project object out of collision
        p.x += px;
        p.y += py;

        //  Apply bounce+friction impulses which alter velocity
        o.x += px + bx + fx;
        o.y += py + by + fy;

    },

    /**
    * Tiles cannot collide with the world bounds, it's up to you to keep them where you want them. But we need this API stub to satisfy the Body.
    *
    * @method Phaser.Physics.Ninja.Tile#setType
    * @param {number} id - The type of Tile this will use, i.e. Phaser.Physics.Ninja.Tile.SLOPE_45DEGpn, Phaser.Physics.Ninja.Tile.CONVEXpp, etc.
    */
    setType: function (id) {

        if (id === Phaser.Physics.Ninja.Tile.EMPTY)
        {
            this.clear();
        }
        else
        {
            this.id = id;
            this.updateType();
        }

        return this;

    },

    /**
    * Sets this tile to be empty.
    *
    * @method Phaser.Physics.Ninja.Tile#clear
    */
    clear: function () {

        this.id = Phaser.Physics.Ninja.Tile.EMPTY;
        this.updateType();

    },

    /**
    * Destroys this Tiles reference to Body and System.
    *
    * @method Phaser.Physics.Ninja.Tile#destroy
    */
    destroy: function () {

        this.body = null;
        this.system = null;

    },

    /**
    * This converts a tile from implicitly-defined (via id), to explicit (via properties).
    * Don't call directly, instead of setType.
    *
    * @method Phaser.Physics.Ninja.Tile#updateType
    * @private
    */
    updateType: function () {

        if (this.id === 0)
        {
            //EMPTY
            this.type = Phaser.Physics.Ninja.Tile.TYPE_EMPTY;
            this.signx = 0;
            this.signy = 0;
            this.sx = 0;
            this.sy = 0;

            return true;
        }

        //tile is non-empty; collide
        if (this.id < Phaser.Physics.Ninja.Tile.TYPE_45DEG)
        {
            //FULL
            this.type = Phaser.Physics.Ninja.Tile.TYPE_FULL;
            this.signx = 0;
            this.signy = 0;
            this.sx = 0;
            this.sy = 0;
        }
        else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_CONCAVE)
        {
            //  45deg
            this.type = Phaser.Physics.Ninja.Tile.TYPE_45DEG;

            if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_45DEGpn)
            {
                this.signx = 1;
                this.signy = -1;
                this.sx = this.signx / Math.SQRT2;//get slope _unit_ normal
                this.sy = this.signy / Math.SQRT2;//since normal is (1,-1), length is sqrt(1*1 + -1*-1) = sqrt(2)
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_45DEGnn)
            {
                this.signx = -1;
                this.signy = -1;
                this.sx = this.signx / Math.SQRT2;//get slope _unit_ normal
                this.sy = this.signy / Math.SQRT2;//since normal is (1,-1), length is sqrt(1*1 + -1*-1) = sqrt(2)
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_45DEGnp)
            {
                this.signx = -1;
                this.signy = 1;
                this.sx = this.signx / Math.SQRT2;//get slope _unit_ normal
                this.sy = this.signy / Math.SQRT2;//since normal is (1,-1), length is sqrt(1*1 + -1*-1) = sqrt(2)
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_45DEGpp)
            {
                this.signx = 1;
                this.signy = 1;
                this.sx = this.signx / Math.SQRT2;//get slope _unit_ normal
                this.sy = this.signy / Math.SQRT2;//since normal is (1,-1), length is sqrt(1*1 + -1*-1) = sqrt(2)
            }
            else
            {
                return false;
            }
        }
        else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_CONVEX)
        {
            //  Concave
            this.type = Phaser.Physics.Ninja.Tile.TYPE_CONCAVE;

            if (this.id == Phaser.Physics.Ninja.Tile.CONCAVEpn)
            {
                this.signx = 1;
                this.signy = -1;
                this.sx = 0;
                this.sy = 0;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.CONCAVEnn)
            {
                this.signx = -1;
                this.signy = -1;
                this.sx = 0;
                this.sy = 0;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.CONCAVEnp)
            {
                this.signx = -1;
                this.signy = 1;
                this.sx = 0;
                this.sy = 0;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.CONCAVEpp)
            {
                this.signx = 1;
                this.signy = 1;
                this.sx = 0;
                this.sy = 0;
            }
            else
            {
                return false;
            }
        }
        else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_22DEGs)
        {
            //  Convex
            this.type = Phaser.Physics.Ninja.Tile.TYPE_CONVEX;

            if (this.id == Phaser.Physics.Ninja.Tile.CONVEXpn)
            {
                this.signx = 1;
                this.signy = -1;
                this.sx = 0;
                this.sy = 0;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.CONVEXnn)
            {
                this.signx = -1;
                this.signy = -1;
                this.sx = 0;
                this.sy = 0;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.CONVEXnp)
            {
                this.signx = -1;
                this.signy = 1;
                this.sx = 0;
                this.sy = 0;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.CONVEXpp)
            {
                this.signx = 1;
                this.signy = 1;
                this.sx = 0;
                this.sy = 0;
            }
            else
            {
                return false;
            }
        }
        else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_22DEGb)
        {
            //  22deg small
            this.type = Phaser.Physics.Ninja.Tile.TYPE_22DEGs;

            if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGpnS)
            {
                this.signx = 1;
                this.signy = -1;
                var slen = Math.sqrt(2 * 2 + 1 * 1);
                this.sx = (this.signx * 1) / slen;
                this.sy = (this.signy * 2) / slen;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGnnS)
            {
                this.signx = -1;
                this.signy = -1;
                var slen = Math.sqrt(2 * 2 + 1 * 1);
                this.sx = (this.signx * 1) / slen;
                this.sy = (this.signy * 2) / slen;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGnpS)
            {
                this.signx = -1;
                this.signy = 1;
                var slen = Math.sqrt(2 * 2 + 1 * 1);
                this.sx = (this.signx * 1) / slen;
                this.sy = (this.signy * 2) / slen;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGppS)
            {
                this.signx = 1;
                this.signy = 1;
                var slen = Math.sqrt(2 * 2 + 1 * 1);
                this.sx = (this.signx * 1) / slen;
                this.sy = (this.signy * 2) / slen;
            }
            else
            {
                return false;
            }
        }
        else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_67DEGs)
        {
            //  22deg big
            this.type = Phaser.Physics.Ninja.Tile.TYPE_22DEGb;

            if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGpnB)
            {
                this.signx = 1;
                this.signy = -1;
                var slen = Math.sqrt(2 * 2 + 1 * 1);
                this.sx = (this.signx * 1) / slen;
                this.sy = (this.signy * 2) / slen;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGnnB)
            {
                this.signx = -1;
                this.signy = -1;
                var slen = Math.sqrt(2 * 2 + 1 * 1);
                this.sx = (this.signx * 1) / slen;
                this.sy = (this.signy * 2) / slen;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGnpB)
            {
                this.signx = -1;
                this.signy = 1;
                var slen = Math.sqrt(2 * 2 + 1 * 1);
                this.sx = (this.signx * 1) / slen;
                this.sy = (this.signy * 2) / slen;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGppB)
            {
                this.signx = 1;
                this.signy = 1;
                var slen = Math.sqrt(2 * 2 + 1 * 1);
                this.sx = (this.signx * 1) / slen;
                this.sy = (this.signy * 2) / slen;
            }
            else
            {
                return false;
            }
        }
        else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_67DEGb)
        {
            //  67deg small
            this.type = Phaser.Physics.Ninja.Tile.TYPE_67DEGs;

            if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGpnS)
            {
                this.signx = 1;
                this.signy = -1;
                var slen = Math.sqrt(2 * 2 + 1 * 1);
                this.sx = (this.signx * 2) / slen;
                this.sy = (this.signy * 1) / slen;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGnnS)
            {
                this.signx = -1;
                this.signy = -1;
                var slen = Math.sqrt(2 * 2 + 1 * 1);
                this.sx = (this.signx * 2) / slen;
                this.sy = (this.signy * 1) / slen;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGnpS)
            {
                this.signx = -1;
                this.signy = 1;
                var slen = Math.sqrt(2 * 2 + 1 * 1);
                this.sx = (this.signx * 2) / slen;
                this.sy = (this.signy * 1) / slen;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGppS)
            {
                this.signx = 1;
                this.signy = 1;
                var slen = Math.sqrt(2 * 2 + 1 * 1);
                this.sx = (this.signx * 2) / slen;
                this.sy = (this.signy * 1) / slen;
            }
            else
            {
                return false;
            }
        }
        else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_HALF)
        {
            //  67deg big
            this.type = Phaser.Physics.Ninja.Tile.TYPE_67DEGb;

            if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGpnB)
            {
                this.signx = 1;
                this.signy = -1;
                var slen = Math.sqrt(2 * 2 + 1 * 1);
                this.sx = (this.signx * 2) / slen;
                this.sy = (this.signy * 1) / slen;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGnnB)
            {
                this.signx = -1;
                this.signy = -1;
                var slen = Math.sqrt(2 * 2 + 1 * 1);
                this.sx = (this.signx * 2) / slen;
                this.sy = (this.signy * 1) / slen;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGnpB)
            {
                this.signx = -1;
                this.signy = 1;
                var slen = Math.sqrt(2 * 2 + 1 * 1);
                this.sx = (this.signx * 2) / slen;
                this.sy = (this.signy * 1) / slen;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGppB)
            {
                this.signx = 1;
                this.signy = 1;
                var slen = Math.sqrt(2 * 2 + 1 * 1);
                this.sx = (this.signx * 2) / slen;
                this.sy = (this.signy * 1) / slen;
            }
            else
            {
                return false;
            }
        }
        else
        {
            //  Half-full tile
            this.type = Phaser.Physics.Ninja.Tile.TYPE_HALF;

            if (this.id == Phaser.Physics.Ninja.Tile.HALFd)
            {
                this.signx = 0;
                this.signy = -1;
                this.sx = this.signx;
                this.sy = this.signy;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.HALFu)
            {
                this.signx = 0;
                this.signy = 1;
                this.sx = this.signx;
                this.sy = this.signy;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.HALFl)
            {
                this.signx = 1;
                this.signy = 0;
                this.sx = this.signx;
                this.sy = this.signy;
            }
            else if (this.id == Phaser.Physics.Ninja.Tile.HALFr)
            {
                this.signx = -1;
                this.signy = 0;
                this.sx = this.signx;
                this.sy = this.signy;
            }
            else
            {
                return false;
            }
        }
    }

};

/**
* @name Phaser.Physics.Ninja.Tile#x
* @property {number} x - The x position.
*/
Object.defineProperty(Phaser.Physics.Ninja.Tile.prototype, "x", {

    get: function () {
        return this.pos.x - this.xw;
    },

    set: function (value) {
        this.pos.x = value;
    }

});

/**
* @name Phaser.Physics.Ninja.Tile#y
* @property {number} y - The y position.
*/
Object.defineProperty(Phaser.Physics.Ninja.Tile.prototype, "y", {

    get: function () {
        return this.pos.y - this.yw;
    },

    set: function (value) {
        this.pos.y = value;
    }

});

/**
* @name Phaser.Physics.Ninja.Tile#bottom
* @property {number} bottom - The bottom value of this Body (same as Body.y + Body.height)
* @readonly
*/
Object.defineProperty(Phaser.Physics.Ninja.Tile.prototype, "bottom", {

    get: function () {
        return this.pos.y + this.yw;
    }

});

/**
* @name Phaser.Physics.Ninja.Tile#right
* @property {number} right - The right value of this Body (same as Body.x + Body.width)
* @readonly
*/
Object.defineProperty(Phaser.Physics.Ninja.Tile.prototype, "right", {

    get: function () {
        return this.pos.x + this.xw;
    }

});

Phaser.Physics.Ninja.Tile.EMPTY = 0;
Phaser.Physics.Ninja.Tile.FULL = 1;//fullAABB tile
Phaser.Physics.Ninja.Tile.SLOPE_45DEGpn = 2;//45-degree triangle, whose normal is (+ve,-ve)
Phaser.Physics.Ninja.Tile.SLOPE_45DEGnn = 3;//(+ve,+ve)
Phaser.Physics.Ninja.Tile.SLOPE_45DEGnp = 4;//(-ve,+ve)
Phaser.Physics.Ninja.Tile.SLOPE_45DEGpp = 5;//(-ve,-ve)
Phaser.Physics.Ninja.Tile.CONCAVEpn = 6;//1/4-circle cutout
Phaser.Physics.Ninja.Tile.CONCAVEnn = 7;
Phaser.Physics.Ninja.Tile.CONCAVEnp = 8;
Phaser.Physics.Ninja.Tile.CONCAVEpp = 9;
Phaser.Physics.Ninja.Tile.CONVEXpn = 10;//1/4/circle
Phaser.Physics.Ninja.Tile.CONVEXnn = 11;
Phaser.Physics.Ninja.Tile.CONVEXnp = 12;
Phaser.Physics.Ninja.Tile.CONVEXpp = 13;
Phaser.Physics.Ninja.Tile.SLOPE_22DEGpnS = 14;//22.5 degree slope
Phaser.Physics.Ninja.Tile.SLOPE_22DEGnnS = 15;
Phaser.Physics.Ninja.Tile.SLOPE_22DEGnpS = 16;
Phaser.Physics.Ninja.Tile.SLOPE_22DEGppS = 17;
Phaser.Physics.Ninja.Tile.SLOPE_22DEGpnB = 18;
Phaser.Physics.Ninja.Tile.SLOPE_22DEGnnB = 19;
Phaser.Physics.Ninja.Tile.SLOPE_22DEGnpB = 20;
Phaser.Physics.Ninja.Tile.SLOPE_22DEGppB = 21;
Phaser.Physics.Ninja.Tile.SLOPE_67DEGpnS = 22;//67.5 degree slope
Phaser.Physics.Ninja.Tile.SLOPE_67DEGnnS = 23;
Phaser.Physics.Ninja.Tile.SLOPE_67DEGnpS = 24;
Phaser.Physics.Ninja.Tile.SLOPE_67DEGppS = 25;
Phaser.Physics.Ninja.Tile.SLOPE_67DEGpnB = 26;
Phaser.Physics.Ninja.Tile.SLOPE_67DEGnnB = 27;
Phaser.Physics.Ninja.Tile.SLOPE_67DEGnpB = 28;
Phaser.Physics.Ninja.Tile.SLOPE_67DEGppB = 29;
Phaser.Physics.Ninja.Tile.HALFd = 30;//half-full tiles
Phaser.Physics.Ninja.Tile.HALFr = 31;
Phaser.Physics.Ninja.Tile.HALFu = 32;
Phaser.Physics.Ninja.Tile.HALFl = 33;

Phaser.Physics.Ninja.Tile.TYPE_EMPTY = 0;
Phaser.Physics.Ninja.Tile.TYPE_FULL = 1;
Phaser.Physics.Ninja.Tile.TYPE_45DEG = 2;
Phaser.Physics.Ninja.Tile.TYPE_CONCAVE = 6;
Phaser.Physics.Ninja.Tile.TYPE_CONVEX = 10;
Phaser.Physics.Ninja.Tile.TYPE_22DEGs = 14;
Phaser.Physics.Ninja.Tile.TYPE_22DEGb = 18;
Phaser.Physics.Ninja.Tile.TYPE_67DEGs = 22;
Phaser.Physics.Ninja.Tile.TYPE_67DEGb = 26;
Phaser.Physics.Ninja.Tile.TYPE_HALF = 30;

		Phaser Copyright © 2012-2015 Photon Storm Ltd.

		Documentation generated by JSDoc 3.3.0-alpha10
		on Thu Mar 26 2015 02:53:48 GMT+0000 (GMT Standard Time) using the DocStrap template.


/**
 * @author Mat Groves http://matgroves.com/ @Doormat23
 */

/**
 * A Stage represents the root of the display tree. Everything connected to the stage is rendered
 *
 * @class Stage
 * @extends DisplayObjectContainer
 * @constructor
 * @param backgroundColor {Number} the background color of the stage, you have to pass this in is in hex format
 *      like: 0xFFFFFF for white
 *
 * Creating a stage is a mandatory process when you use Pixi, which is as simple as this :
 * var stage = new PIXI.Stage(0xFFFFFF);
 * where the parameter given is the background colour of the stage, in hex
 * you will use this stage instance to add your sprites to it and therefore to the renderer
 * Here is how to add a sprite to the stage :
 * stage.addChild(sprite);
 */
PIXI.Stage = function(backgroundColor)
{
    PIXI.DisplayObjectContainer.call( this );

    /**
     * [read-only] Current transform of the object based on world (parent) factors
     *
     * @property worldTransform
     * @type Matrix
     * @readOnly
     * @private
     */
    this.worldTransform = new PIXI.Matrix();

    //the stage is its own stage
    this.stage = this;

    this.setBackgroundColor(backgroundColor);
};

// constructor
PIXI.Stage.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
PIXI.Stage.prototype.constructor = PIXI.Stage;

/*
 * Updates the object transform for rendering
 *
 * @method updateTransform
 * @private
 */
PIXI.Stage.prototype.updateTransform = function()
{
    this.worldAlpha = 1;

    for (var i = 0; i < this.children.length; i++)
    {
        this.children[i].updateTransform();
    }
};

/**
 * Sets the background color for the stage
 *
 * @method setBackgroundColor
 * @param backgroundColor {Number} the color of the background, easiest way to pass this in is in hex format
 *      like: 0xFFFFFF for white
 */
PIXI.Stage.prototype.setBackgroundColor = function(backgroundColor)
{
    this.backgroundColor = backgroundColor || 0x000000;
    this.backgroundColorSplit = PIXI.hex2rgb(this.backgroundColor);
    var hex = this.backgroundColor.toString(16);
    hex = '000000'.substr(0, 6 - hex.length) + hex;
    this.backgroundColorString = '#' + hex;
};


Phaser.Physics.Arcade

The Arcade Physics world. Contains Arcade Physics related collision, overlap and motion methods.

accelerateToObject

The angle (in radians) that the object should be visually set to in order to match its new trajectory.

Sets the acceleration.x/y property on the display object so it will move towards the target at the given speed (in pixels per second sq.)\nYou must give a maximum speed value, beyond which the display object won't go any faster.\nNote: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course.\nNote: The display object doesn't stop moving once it reaches the destination coordinates.

destination

The display object to move towards. Can be any object but must have visible x/y properties.

speed

The speed it will accelerate in pixels per second.

xSpeedMax

The maximum x velocity the display object can reach.

ySpeedMax

The maximum y velocity the display object can reach.

accelerateToPointer

pointer

The pointer to move towards. Defaults to Phaser.Input.activePointer.

accelerateToXY

Sets the acceleration.x/y property on the display object so it will move towards the x/y coordinates at the given speed (in pixels per second sq.)\nYou must give a maximum speed value, beyond which the display object won't go any faster.\nNote: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course.\nNote: The display object doesn't stop moving once it reaches the destination coordinates.

accelerationFromRotation

- A Point where point.x contains the acceleration x value and point.y contains the acceleration y value.

Given the rotation (in radians) and speed calculate the acceleration and return it as a Point object, or set it to the given point object.\nOne way to use this is: accelerationFromRotation(rotation, 200, sprite.acceleration) which will set the values directly to the sprites acceleration and not create a new Point object.

speed

The speed it will move, in pixels per second sq.

point

The Point object in which the x and y properties will be set to the calculated acceleration.

angleBetween

The angle in radians between the source and target display objects.

Find the angle in radians between two display objects (like Sprites).

angleToPointer

The angle in radians between displayObject.x/y to Pointer.x/y

Find the angle in radians between a display object (like a Sprite) and a Pointer, taking their x/y and center into account.

pointer

The Phaser.Pointer to test to. If none is given then Input.activePointer is used.

angleToXY

Find the angle in radians between a display object (like a Sprite) and the given x/y coordinate.

collide

True if a collision occured otherwise false.

Checks for collision between two game objects. You can perform Sprite vs. Sprite, Sprite vs. Group, Group vs. Group, Sprite vs. Tilemap Layer or Group vs. Tilemap Layer collisions.\nBoth the first and second parameter can be arrays of objects, of differing types.\nIf two arrays are passed, the contents of the first parameter will be tested against all contents of the 2nd parameter.\nThe objects are also automatically separated. If you don't require separation then use ArcadePhysics.overlap instead.\nAn optional processCallback can be provided. If given this function will be called when two sprites are found to be colliding. It is called before any separation takes place,\ngiving you the chance to perform additional checks. If the function returns true then the collision and separation is carried out. If it returns false it is skipped.\nThe collideCallback is an optional function that is only called if two sprites collide. If a processCallback has been set then it needs to return true for collideCallback to be called.\nNOTE: This function is not recursive, and will not test against children of objects passed (i.e. Groups or Tilemaps within other Groups).

The first object or array of objects to check. Can be Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.TilemapLayer.

The second object or array of objects to check. Can be Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.TilemapLayer.

collideCallback

An optional callback function that is called if the objects collide. The two objects will be passed to this function in the same order in which you specified them, unless you are colliding Group vs. Sprite, in which case Sprite will always be the first parameter.

processCallback

A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collision will only happen if processCallback returns true. The two objects will be passed to this function in the same order in which you specified them.

callbackContext

The context in which to run the callbacks.

computeVelocity

A tween-like function that takes a starting velocity and some other factors and returns an altered velocity.\nBased on a function in Flixel by @ADAMATOMIC

axis

0 for nothing, 1 for horizontal, 2 for vertical.

drag

Really kind of a deceleration, this is how much the velocity changes if Acceleration is not set.

distanceBetween

The distance between the source and target objects.

Find the distance between two display objects (like Sprites).

distanceToPointer

The distance between the object and the Pointer.

Find the distance between a display object (like a Sprite) and a Pointer. If no Pointer is given the Input.activePointer is used.\nThe calculation is made from the display objects x/y coordinate. This may be the top-left if its anchor hasn't been changed.\nIf you need to calculate from the center of a display object instead use the method distanceBetweenCenters()

distanceToXY

The distance between the object and the x/y coordinates.

Find the distance between a display object (like a Sprite) and the given x/y coordinates.\nThe calculation is made from the display objects x/y coordinate. This may be the top-left if its anchor hasn't been changed.\nIf you need to calculate from the center of a display object instead use the method distanceBetweenCenters()

enable

This will create an Arcade Physics body on the given game object or array of game objects.\nA game object can only have 1 physics body active at any one time, and it can't be changed until the object is destroyed.

object

The game object to create the physics body on. Can also be an array or Group of objects, a body will be created on every child that has a `body` property.

children

Should a body be created on all children of this object? If true it will recurse down the display list as far as it can go.

enableBody

Creates an Arcade Physics body on the given game object.\nA game object can only have 1 physics body active at any one time, and it can't be changed until the body is nulled.

object

The game object to create the physics body on. A body will only be created if this object has a null `body` property.

getObjectsUnderPointer

An array of the Sprites from the Group that overlapped the Pointer coordinates.

Given a Group and a Pointer this will check to see which Group children overlap with the Pointer coordinates.\nEach child will be sent to the given callback for further processing.\nNote that the children are not checked for depth order, but simply if they overlap the Pointer or not.

callback

A callback function that is called if the object overlaps with the Pointer. The callback will be sent two parameters: the Pointer and the Object that overlapped with it.

callbackContext

The context in which to run the callback.

intersects

True if they intersect, otherwise false.

Check for intersection against two bodies.

moveToObject

The angle (in radians) that the object should be visually set to in order to match its new velocity.

Move the given display object towards the destination object at a steady velocity.\nIf you specify a maxTime then it will adjust the speed (overwriting what you set) so it arrives at the destination in that number of seconds.\nTimings are approximate due to the way browser timers work. Allow for a variance of +- 50ms.\nNote: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course.\nNote: The display object doesn't stop moving once it reaches the destination coordinates.\nNote: Doesn't take into account acceleration, maxVelocity or drag (if you've set drag or acceleration too high this object may not move at all)

speed

The speed it will move, in pixels per second (default is 60 pixels/sec)

maxTime

Time given in milliseconds (1000 = 1 sec). If set the speed is adjusted so the object will arrive at destination in the given number of ms.

moveToPointer

Move the given display object towards the pointer at a steady velocity. If no pointer is given it will use Phaser.Input.activePointer.\nIf you specify a maxTime then it will adjust the speed (over-writing what you set) so it arrives at the destination in that number of seconds.\nTimings are approximate due to the way browser timers work. Allow for a variance of +- 50ms.\nNote: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course.\nNote: The display object doesn't stop moving once it reaches the destination coordinates.

moveToXY

Move the given display object towards the x/y coordinates at a steady velocity.\nIf you specify a maxTime then it will adjust the speed (over-writing what you set) so it arrives at the destination in that number of seconds.\nTimings are approximate due to the way browser timers work. Allow for a variance of +- 50ms.\nNote: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course.\nNote: The display object doesn't stop moving once it reaches the destination coordinates.\nNote: Doesn't take into account acceleration, maxVelocity or drag (if you've set drag or acceleration too high this object may not move at all)

overlap

True if an overlap occurred otherwise false.

Checks for overlaps between two game objects. The objects can be Sprites, Groups or Emitters.\nYou can perform Sprite vs. Sprite, Sprite vs. Group and Group vs. Group overlap checks.\nUnlike collide the objects are NOT automatically separated or have any physics applied, they merely test for overlap results.\nBoth the first and second parameter can be arrays of objects, of differing types.\nIf two arrays are passed, the contents of the first parameter will be tested against all contents of the 2nd parameter.\nNOTE: This function is not recursive, and will not test against children of objects passed (i.e. Groups within Groups).

The first object or array of objects to check. Can be Phaser.Sprite, Phaser.Group or Phaser.Particles.Emitter.

The second object or array of objects to check. Can be Phaser.Sprite, Phaser.Group or Phaser.Particles.Emitter.

overlapCallback

An optional callback function that is called if the objects overlap. The two objects will be passed to this function in the same order in which you specified them.

processCallback

A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then overlapCallback will only be called if processCallback returns true.

callbackContext

The context in which to run the callbacks.

setBounds

width

New width of the world. Can never be smaller than the Game.width.

height

New height of the world. Can never be smaller than the Game.height.

setBoundsToWorld

Updates the size of this physics world to match the size of the game world.

updateMotion

Called automatically by a Physics body, it updates all motion related values on the Body.

velocityFromAngle

- A Point where point.x contains the velocity x value and point.y contains the velocity y value.

Given the angle (in degrees) and speed calculate the velocity and return it as a Point object, or set it to the given point object.\nOne way to use this is: velocityFromAngle(angle, 200, sprite.velocity) which will set the values directly to the sprites velocity and not create a new Point object.

angle

The angle in degrees calculated in clockwise positive direction (down = 90 degrees positive, right = 0 degrees positive, up = 90 degrees negative)

speed

The speed it will move, in pixels per second sq.

point

The Point object in which the x and y properties will be set to the calculated velocity.

velocityFromRotation

Given the rotation (in radians) and speed calculate the velocity and return it as a Point object, or set it to the given point object.\nOne way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) which will set the values directly to the sprites velocity and not create a new Point object.

collideGroupVsGroup

An internal function. Use Phaser.Physics.Arcade.collide instead.

collideCallback

An optional callback function that is called if the objects collide. The two objects will be passed to this function in the same order in which you specified them.

overlapOnly

Just run an overlap or a full collision.

collideGroupVsSelf

True if there was a collision, otherwise false.

collideHandler

The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.TilemapLayer.

The second object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.TilemapLayer. Can also be an array of objects to check.

callbackContext

The context in which to run the callbacks.

processTileSeparationX

Returns true as a pass-thru to the separateTile method.

Internal function to process the separation of a physics body from a tile.

separate

Returns true if the bodies collided, otherwise false.

The core separation function to separate two physics bodies.

processCallback

A callback function that lets you perform additional checks against the two objects if they overlap. If this function is set then the sprites will only be collided if it returns true.

callbackContext

The context in which to run the process callback.

separateTile

Returns true if the body was separated, otherwise false.

The core separation function to separate a physics body and a tile.

separateX

Returns true if the bodies were separated, otherwise false.

The core separation function to separate two physics bodies on the x axis.

overlapOnly

If true the bodies will only have their overlap data set, no separation or exchange of velocity will take place.

separateY

The core separation function to separate two physics bodies on the y axis.

tileCheckX

Check the body against the given tile on the X axis.

tileCheckY

Check the body against the given tile on the Y axis.

A value added to the delta values during collision checks.

A value added to the delta values during collision with tiles. Adjust this if you get tunnelling.

bounds

The bounds inside of which the physics world exists. Defaults to match the world bounds.

checkCollision

Set the checkCollision properties to control for which bounds collision is processed.\nFor example checkCollision.down = false means Bodies cannot collide with the World.bounds.bottom.

An object containing allowed collision flags.

forceX

If true World.separate will always separate on the X axis before Y. Otherwise it will check gravity totals first.

gravity

The World gravity setting. Defaults to x: 0, y: 0, or no gravity.

maxLevels

Used by the QuadTree to set the maximum number of iteration levels.

maxObjects

Used by the QuadTree to set the maximum number of objects per quad.

skipQuadTree

If true a QuadTree will never be used for any collision. Handy for tightly packed games. See also Body.skipQuadTree.