Merge branch 'master' into rendering-cleanup

This commit is contained in:
Felipe Alfonso 2018-01-10 17:05:32 -03:00
commit 8e66cf9f98
17 changed files with 356 additions and 29 deletions

84
.github/CODE_OF_CONDUCT.md vendored Normal file
View file

@ -0,0 +1,84 @@
# Code of Conduct
## 1. Purpose
A primary goal of Phaser is to be inclusive to the largest number of contributors, with the most varied and diverse backgrounds possible. As such, we are committed to providing a friendly, safe and welcoming environment for all, regardless of gender, sexual orientation, ability, ethnicity, socioeconomic status, and religion (or lack thereof).
This code of conduct outlines our expectations for all those who participate in our community, as well as the consequences for unacceptable behavior.
We invite all those who participate in Phaser to help us create safe and positive experiences for everyone.
## 2. Open Source Citizenship
A supplemental goal of this Code of Conduct is to increase open source citizenship by encouraging participants to recognize and strengthen the relationships between our actions and their effects on our community.
Communities mirror the societies in which they exist and positive action is essential to counteract the many forms of inequality and abuses of power that exist in society.
If you see someone who is making an extra effort to ensure our community is welcoming, friendly, and encourages all participants to contribute to the fullest extent, we want to know.
## 3. Expected Behavior
The following behaviors are expected and requested of all community members:
* Participate in an authentic and active way. In doing so, you contribute to the health and longevity of this community.
* Exercise consideration and respect in your speech and actions.
* Attempt collaboration before conflict.
* Refrain from demeaning, discriminatory, or harassing behavior and speech.
* Be mindful of your surroundings and of your fellow participants. Alert community leaders if you notice a dangerous situation, someone in distress, or violations of this Code of Conduct, even if they seem inconsequential.
* Remember that community event venues may be shared with members of the public; please be respectful to all patrons of these locations.
## 4. Unacceptable Behavior
The following behaviors are considered harassment and are unacceptable within our community:
* Violence, threats of violence or violent language directed against another person.
* Sexist, racist, homophobic, transphobic, ableist or otherwise discriminatory jokes and language.
* Posting or displaying sexually explicit or violent material.
* Posting or threatening to post other peoples personally identifying information ("doxing").
* Personal insults, particularly those related to gender, sexual orientation, race, religion, or disability.
* Inappropriate photography or recording.
* Inappropriate physical contact. You should have someones consent before touching them.
* Unwelcome sexual attention. This includes, sexualized comments or jokes; inappropriate touching, groping, and unwelcomed sexual advances.
* Deliberate intimidation, stalking or following (online or in person).
* Advocating for, or encouraging, any of the above behavior.
* Sustained disruption of community events, including talks and presentations.
## 5. Consequences of Unacceptable Behavior
Unacceptable behavior from any community member, including sponsors and those with decision-making authority, will not be tolerated.
Anyone asked to stop unacceptable behavior is expected to comply immediately.
If a community member engages in unacceptable behavior, the community organizers may take any action they deem appropriate, up to and including a temporary ban or permanent expulsion from the community without warning (and without refund in the case of a paid event).
## 6. Reporting Guidelines
If you are subject to or witness unacceptable behavior, or have any other concerns, please notify a community organizer as soon as possible. support@phaser.io.
Additionally, community organizers are available to help community members engage with local law enforcement or to otherwise help those experiencing unacceptable behavior feel safe. In the context of in-person events, organizers will also provide escorts as desired by the person experiencing distress.
## 7. Addressing Grievances
If you feel you have been falsely or unfairly accused of violating this Code of Conduct, you should notify Photon Storm Ltd with a concise description of your grievance. Your grievance will be handled in accordance with our existing governing policies.
## 8. Scope
We expect all community participants (contributors, paid or otherwise; sponsors; and other guests) to abide by this Code of Conduct in all community venuesonline and in-personas well as in all one-on-one communications pertaining to community business.
This code of conduct and its related procedures also applies to unacceptable behavior occurring outside the scope of community activities when such behavior has the potential to adversely affect the safety and well-being of community members.
## 9. Contact info
support@phaser.io
## 10. License and attribution
This Code of Conduct is distributed under a [Creative Commons Attribution-ShareAlike license](http://creativecommons.org/licenses/by-sa/3.0/).
Portions of text derived from the [Django Code of Conduct](https://www.djangoproject.com/conduct/) and the [Geek Feminism Anti-Harassment Policy](http://geekfeminism.wikia.com/wiki/Conference_anti-harassment/Policy).
Retrieved on November 22, 2016 from [http://citizencodeofconduct.org/](http://citizencodeofconduct.org/)

View file

@ -13,7 +13,7 @@ var ValueToColor = require('../display/color/ValueToColor');
/** /**
* @typedef {object} FPSConfig * @typedef {object} FPSConfig
* *
* @property {integer} [min=10] - [description] * @property {integer} [min=10] - [description]
* @property {integer} [target=60] - [description] * @property {integer} [target=60] - [description]
* @property {boolean} [forceSetTimeOut=false] - [description] * @property {boolean} [forceSetTimeOut=false] - [description]
@ -25,7 +25,7 @@ var ValueToColor = require('../display/color/ValueToColor');
* @typedef {object} GameConfig * @typedef {object} GameConfig
* *
* @todo Add Physics Config * @todo Add Physics Config
* *
* @property {integer|string} [width=1024] - [description] * @property {integer|string} [width=1024] - [description]
* @property {integer|string} [height=768] - [description] * @property {integer|string} [height=768] - [description]
* @property {number} [zoom=1] - [description] * @property {number} [zoom=1] - [description]
@ -81,7 +81,7 @@ var Config = new Class({
* @since 3.0.0 * @since 3.0.0
* *
* @param {object} [GameConfig] - The configuration object for your Phaser Game instance. * @param {object} [GameConfig] - The configuration object for your Phaser Game instance.
* *
*/ */
function Config (config) function Config (config)
{ {
@ -135,6 +135,8 @@ var Config = new Class({
this.disableContextMenu = GetValue(config, 'disableContextMenu', false); this.disableContextMenu = GetValue(config, 'disableContextMenu', false);
this.audio = GetValue(config, 'audio');
// If you do: { banner: false } it won't display any banner at all // If you do: { banner: false } it won't display any banner at all
this.hideBanner = (GetValue(config, 'banner', null) === false); this.hideBanner = (GetValue(config, 'banner', null) === false);
@ -146,7 +148,7 @@ var Config = new Class({
{ {
this.hideBanner = true; this.hideBanner = true;
} }
// Frame Rate config // Frame Rate config
// fps: { // fps: {
// min: 10, // min: 10,

View file

@ -20,6 +20,24 @@ var DebugHeader = function (game)
var renderType = (config.renderType === CONST.CANVAS) ? 'Canvas' : 'WebGL'; var renderType = (config.renderType === CONST.CANVAS) ? 'Canvas' : 'WebGL';
var audioConfig = game.config.audio;
var deviceAudio = game.device.Audio;
var audioType;
if(deviceAudio.webAudio && !(audioConfig && audioConfig.disableWebAudio))
{
audioType = 'Web Audio';
}
else if((audioConfig && audioConfig.noAudio) || (!deviceAudio.webAudio && !deviceAudio.audioData))
{
audioType = 'No Audio';
}
else
{
audioType = 'HTML5 Audio';
}
var ie = false; var ie = false;
if (!ie) if (!ie)
@ -71,8 +89,7 @@ var DebugHeader = function (game)
if (!config.hidePhaser) if (!config.hidePhaser)
{ {
// TODO add audio c = c.concat('Phaser v' + CONST.VERSION + ' (' + renderType + ' | ' + audioType + ')');
c = c.concat('Phaser v' + CONST.VERSION + ' (' + renderType + ')');
} }
c = c.concat(' %c ' + config.gameURL); c = c.concat(' %c ' + config.gameURL);

View file

@ -11,7 +11,7 @@ var VisibilityHandler = require('./VisibilityHandler');
var AnimationManager = require('../animations/manager/AnimationManager'); var AnimationManager = require('../animations/manager/AnimationManager');
var CreateRenderer = require('./CreateRenderer'); var CreateRenderer = require('./CreateRenderer');
var Data = require('../scene/plugins/Data'); var Data = require('../data/Data');
var GlobalCache = require('../cache/GlobalCache'); var GlobalCache = require('../cache/GlobalCache');
var GlobalInputManager = require('../input/global/GlobalInputManager'); var GlobalInputManager = require('../input/global/GlobalInputManager');
var GlobalSceneManager = require('../scene/global/GlobalSceneManager'); var GlobalSceneManager = require('../scene/global/GlobalSceneManager');

View file

@ -1,6 +1,6 @@
var Class = require('../../utils/Class'); var Class = require('../utils/Class');
var Event = require('../../events/Event'); var Event = require('../events/Event');
var EventDispatcher = require('../../events/EventDispatcher'); var EventDispatcher = require('../events/EventDispatcher');
/** /**
* The Data Component features a means to store pieces of data specific to a Game Object, * The Data Component features a means to store pieces of data specific to a Game Object,

View file

@ -1,4 +1,4 @@
var Class = require('../../utils/Class'); var Class = require('../utils/Class');
var Data = require('./Data'); var Data = require('./Data');
var DataStore = new Class({ var DataStore = new Class({

View file

@ -20,7 +20,8 @@ var GetTilesWithin = require('./GetTilesWithin');
* @param {integer} [width=max width based on tileX] - [description] * @param {integer} [width=max width based on tileX] - [description]
* @param {integer} [height=max height based on tileY] - [description] * @param {integer} [height=max height based on tileY] - [description]
* @param {object[]} [weightedIndexes] - An array of objects to randomly draw from during * @param {object[]} [weightedIndexes] - An array of objects to randomly draw from during
* randomization. They should be in the form: { index: 0, weight: 4 }. * randomization. They should be in the form: { index: 0, weight: 4 } or
* { index: [0, 1], weight: 4 } if you wish to draw from multiple tile indexes.
* @param {LayerData} layer - [description] * @param {LayerData} layer - [description]
*/ */
var WeightedRandomize = function (tileX, tileY, width, height, weightedIndexes, layer) var WeightedRandomize = function (tileX, tileY, width, height, weightedIndexes, layer)
@ -48,7 +49,10 @@ var WeightedRandomize = function (tileX, tileY, width, height, weightedIndexes,
sum += weightedIndexes[j].weight; sum += weightedIndexes[j].weight;
if (rand <= sum) if (rand <= sum)
{ {
randomIndex = weightedIndexes[j].index; var chosen = weightedIndexes[j].index;
randomIndex = Array.isArray(chosen)
? chosen[Math.floor(Math.random() * chosen.length)]
: chosen;
break; break;
} }
} }

View file

@ -12,7 +12,7 @@ var GetMagnitude = require('./GetMagnitude');
*/ */
var Normalize = function (point) var Normalize = function (point)
{ {
if (point.x !== 0 && point.y !== 0) if (point.x !== 0 || point.y !== 0)
{ {
var m = GetMagnitude(point); var m = GetMagnitude(point);

View file

@ -194,6 +194,11 @@ var BaseLoader = new Class({
{ {
// console.log('---> BaseLoader.finishedLoading PROCESSING', this.queue.size, 'files'); // console.log('---> BaseLoader.finishedLoading PROCESSING', this.queue.size, 'files');
if(this.state === CONST.LOADER_PROCESSING)
{
return;
}
this.state = CONST.LOADER_PROCESSING; this.state = CONST.LOADER_PROCESSING;
this.storage.clear(); this.storage.clear();

View file

@ -2,6 +2,7 @@ var Class = require('../../utils/Class');
var File = require('../File'); var File = require('../File');
var GetFastValue = require('../../utils/object/GetFastValue'); var GetFastValue = require('../../utils/object/GetFastValue');
var CONST = require('../../const'); var CONST = require('../../const');
var HTML5AudioFile = require('./HTML5AudioFile');
// Phaser.Loader.FileTypes.AudioFile // Phaser.Loader.FileTypes.AudioFile
@ -46,7 +47,6 @@ var AudioFile = new Class({
}, },
function (e) function (e)
{ {
// TODO properly log decoding error
console.error('Error with decoding audio data for \'' + this.key + '\':', e.message); console.error('Error with decoding audio data for \'' + this.key + '\':', e.message);
_this.state = CONST.FILE_ERRORED; _this.state = CONST.FILE_ERRORED;
@ -66,7 +66,6 @@ AudioFile.create = function (loader, key, urls, config, xhrSettings)
if ((audioConfig && audioConfig.noAudio) || (!deviceAudio.webAudio && !deviceAudio.audioData)) if ((audioConfig && audioConfig.noAudio) || (!deviceAudio.webAudio && !deviceAudio.audioData))
{ {
// TODO log not loading audio because sounds are disabled
console.info('Skipping loading audio \'' + key + '\' since sounds are disabled.'); console.info('Skipping loading audio \'' + key + '\' since sounds are disabled.');
return null; return null;
} }
@ -75,7 +74,6 @@ AudioFile.create = function (loader, key, urls, config, xhrSettings)
if (!url) if (!url)
{ {
// TODO log no supported types
console.warn('No supported url provided for audio \'' + key + '\'!'); console.warn('No supported url provided for audio \'' + key + '\'!');
return null; return null;
} }
@ -85,8 +83,7 @@ AudioFile.create = function (loader, key, urls, config, xhrSettings)
return new AudioFile(key, url, loader.path, xhrSettings, game.sound.context); return new AudioFile(key, url, loader.path, xhrSettings, game.sound.context);
} }
// TODO handle loading audio tags return new HTML5AudioFile(key, url, loader.path, config);
return null;
}; };
// this.load.audio('sound', 'assets/audio/booom.ogg', config, xhrSettings); // this.load.audio('sound', 'assets/audio/booom.ogg', config, xhrSettings);

View file

@ -0,0 +1,96 @@
var Class = require('../../utils/Class');
var File = require('../File');
var GetFastValue = require('../../utils/object/GetFastValue');
var GetURL = require('../GetURL');
// Phaser.Loader.FileTypes.HTML5AudioFile
var HTML5AudioFile = new Class({
Extends: File,
initialize:
function HTML5AudioFile (key, url, path, config)
{
var fileConfig = {
type: 'audio',
extension: GetFastValue(url, 'type', ''),
key: key,
url: GetFastValue(url, 'uri', url),
path: path,
config: config
};
File.call(this, fileConfig);
},
onLoad: function ()
{
this.callback(this, true);
},
onError: function (event)
{
for (var i = 0; i < this.data.length; i++)
{
var audio = this.data[i];
audio.oncanplaythrough = null;
audio.onerror = null;
}
this.callback(this, false);
},
onProgress: function (event)
{
var audio = event.target;
audio.oncanplaythrough = null;
audio.onerror = null;
if(++this.filesLoaded === this.filesTotal)
{
this.onLoad();
}
this.percentComplete = Math.min((this.filesLoaded / this.filesTotal), 1);
},
// Called by the Loader, starts the actual file downloading
load: function (callback, baseURL)
{
this.callback = callback;
this.data = [];
var instances = (this.config && this.config.instances) || 1;
this.filesTotal = instances;
this.filesLoaded = 0;
this.percentComplete = 0;
for(var i = 0; i < instances; i++)
{
var audio = new Audio();
audio.name = this.key;
audio.preload = 'auto';
// TODO check if ios is locked
audio.oncanplaythrough = this.onProgress.bind(this);
audio.onerror = this.onError.bind(this);
this.data.push(audio);
}
for (i = 0; i < this.data.length; i++)
{
audio = this.data[i];
audio.src = GetURL(this, baseURL || '');
audio.load();
}
}
});
module.exports = HTML5AudioFile;

View file

@ -1,8 +1,8 @@
var CameraManager = require('../../camera/local/CameraManager'); var CameraManager = require('../../camera/local/CameraManager');
var Class = require('../../utils/Class'); var Class = require('../../utils/Class');
var Clock = require('../../time/Clock'); var Clock = require('../../time/Clock');
var Data = require('../plugins/Data'); var Data = require('../../data/Data');
var DataStore = require('../plugins/DataStore'); var DataStore = require('../../data/DataStore');
var DisplayList = require('../plugins/DisplayList'); var DisplayList = require('../plugins/DisplayList');
var EventDispatcher = require('../../events/EventDispatcher'); var EventDispatcher = require('../../events/EventDispatcher');
var GameObjectCreator = require('../plugins/GameObjectCreator'); var GameObjectCreator = require('../plugins/GameObjectCreator');
@ -16,6 +16,8 @@ var StableSort = require('../../utils/array/StableSort');
var TweenManager = require('../../tweens/manager/TweenManager'); var TweenManager = require('../../tweens/manager/TweenManager');
var UpdateList = require('../plugins/UpdateList'); var UpdateList = require('../plugins/UpdateList');
var PluginManager = require('../../plugins/PluginManager');
var Systems = new Class({ var Systems = new Class({
initialize: initialize:
@ -27,8 +29,6 @@ var Systems = new Class({
this.config = config; this.config = config;
this.settings = Settings.create(config); this.settings = Settings.create(config);
this.renderList = [];
this.sortChildrenFlag = false; this.sortChildrenFlag = false;
// Set by the GlobalSceneManager // Set by the GlobalSceneManager
@ -59,6 +59,8 @@ var Systems = new Class({
this.time; this.time;
this.tweens; this.tweens;
this.updateList; this.updateList;
this.plugins;
}, },
init: function (game) init: function (game)
@ -74,6 +76,8 @@ var Systems = new Class({
this.registry = game.registry; this.registry = game.registry;
this.textures = game.textures; this.textures = game.textures;
this.plugins = new PluginManager(scene);
// Scene specific managers (Factory, Tweens, Loader, Physics, etc) // Scene specific managers (Factory, Tweens, Loader, Physics, etc)
this.add = new GameObjectFactory(scene); this.add = new GameObjectFactory(scene);

View file

@ -303,6 +303,7 @@ var BaseSoundManager = new Class({
this.forEachActiveSound(function (sound) { this.forEachActiveSound(function (sound) {
sound.destroy(); sound.destroy();
}); });
this.sounds.length = 0;
this.sounds = null; this.sounds = null;
}, },
/** /**
@ -336,7 +337,7 @@ Object.defineProperty(BaseSoundManager.prototype, 'rate', {
this._rate = value; this._rate = value;
this.forEachActiveSound(function (sound) { this.forEachActiveSound(function (sound) {
sound.setRate(); sound.setRate();
}, this); });
this.events.dispatch(new SoundValueEvent(this, 'SOUND_RATE', value)); this.events.dispatch(new SoundValueEvent(this, 'SOUND_RATE', value));
} }
}); });
@ -354,7 +355,7 @@ Object.defineProperty(BaseSoundManager.prototype, 'detune', {
this._detune = value; this._detune = value;
this.forEachActiveSound(function (sound) { this.forEachActiveSound(function (sound) {
sound.setRate(); sound.setRate();
}, this); });
this.events.dispatch(new SoundValueEvent(this, 'SOUND_DETUNE', value)); this.events.dispatch(new SoundValueEvent(this, 'SOUND_DETUNE', value));
} }
}); });

View file

@ -0,0 +1,18 @@
var Class = require('../../utils/Class');
var BaseSound = require('../BaseSound');
var HTML5AudioSound = new Class({
Extends: BaseSound,
initialize: function HTML5AudioSound(manager, key, config) {
if (config === void 0) { config = {}; }
/**
* Reference to HTML5 Audio tag used for playing sound.
*
* @private
* @property {HTMLAudioElement} audio
* @default null
*/
this.audio = null;
BaseSound.call(this, manager, key, config);
}
});
module.exports = HTML5AudioSound;

View file

@ -0,0 +1,95 @@
var Class = require('../../utils/Class');
var BaseSoundManager = require('../BaseSoundManager');
var HTML5AudioSound = require('./HTML5AudioSound');
var HTML5AudioSoundManager = new Class({
Extends: BaseSoundManager,
initialize: function HTML5AudioSoundManager(game) {
/**
* An array for keeping track of all the sounds
* that were paused when game lost focus.
*
* @private
* @property {Phaser.Sound.HTML5AudioSound[]} onBlurPausedSounds
* @default []
*/
this.onBlurPausedSounds = [];
/**
* Property that actually holds the value of global mute
* for HTML5 Audio sound manager implementation.
*
* @private
* @property {boolean} _mute
* @default false
*/
this._mute = false;
/**
* Property that actually holds the value of global volume
* for HTML5 Audio sound manager implementation.
*
* @private
* @property {boolean} _volume
* @default 1
*/
this._volume = 1;
BaseSoundManager.call(this, game);
},
add: function (key, config) {
var sound = new HTML5AudioSound(this, key, config);
this.sounds.push(sound);
return sound;
},
onBlur: function () {
this.forEachActiveSound(function (sound) {
if (sound.isPlaying) {
this.onBlurPausedSounds.push(sound);
sound.pause();
}
});
},
onFocus: function () {
this.onBlurPausedSounds.forEach(function (sound) {
sound.resume();
});
this.onBlurPausedSounds.length = 0;
},
destroy: function () {
BaseSoundManager.prototype.destroy.call(this);
this.onBlurPausedSounds.length = 0;
this.onBlurPausedSounds = null;
}
});
/**
* Global mute setting.
*
* @name Phaser.Sound.HTML5AudioSoundManager#mute
* @property {boolean} mute
*/
Object.defineProperty(HTML5AudioSoundManager.prototype, 'mute', {
get: function () {
return this._mute;
},
set: function (value) {
this._mute = value;
this.forEachActiveSound(function (sound) {
sound.setMute();
});
}
});
/**
* Global volume setting.
*
* @name Phaser.Sound.HTML5AudioSoundManager#volume
* @property {number} volume
*/
Object.defineProperty(HTML5AudioSoundManager.prototype, 'volume', {
get: function () {
return this._volume;
},
set: function (value) {
this._volume = value;
this.forEachActiveSound(function (sound) {
sound.setVolume();
});
}
});
module.exports = HTML5AudioSoundManager;

View file

@ -10,6 +10,9 @@ module.exports = {
WebAudioSound: require('./webaudio/WebAudioSound'), WebAudioSound: require('./webaudio/WebAudioSound'),
WebAudioSoundManager: require('./webaudio/WebAudioSoundManager'), WebAudioSoundManager: require('./webaudio/WebAudioSoundManager'),
HTML5AudioSound: require('./html5/HTML5AudioSound'),
HTML5AudioSoundManager: require('./html5/HTML5AudioSoundManager'),
SoundEvent: require('./SoundEvent'), SoundEvent: require('./SoundEvent'),
SoundValueEvent: require('./SoundValueEvent') SoundValueEvent: require('./SoundValueEvent')
}; };

View file

@ -336,6 +336,7 @@ var WebAudioSound = new Class({
this.muteNode = null; this.muteNode = null;
this.volumeNode.disconnect(); this.volumeNode.disconnect();
this.volumeNode = null; this.volumeNode = null;
this.rateUpdates.length = 0;
this.rateUpdates = null; this.rateUpdates = null;
}, },
/** /**
@ -491,12 +492,12 @@ Object.defineProperty(WebAudioSound.prototype, 'seek', {
if (this.isPlaying || this.isPaused) { if (this.isPlaying || this.isPaused) {
value = Math.min(Math.max(0, value), this.duration); value = Math.min(Math.max(0, value), this.duration);
this.currentConfig.seek = value; this.currentConfig.seek = value;
if (this.isPlaying) {
this.stopAndRemoveBufferSource();
this.createAndStartBufferSource();
}
this.events.dispatch(new SoundValueEvent(this, 'SOUND_SEEK', value)); this.events.dispatch(new SoundValueEvent(this, 'SOUND_SEEK', value));
} }
if (this.isPlaying) {
this.stopAndRemoveBufferSource();
this.createAndStartBufferSource();
}
} }
}); });
/** /**