Merge branch 'master' into rendering-cleanup

This commit is contained in:
Felipe Alfonso 2018-01-22 12:18:38 -03:00
commit e8610734b7
15 changed files with 409 additions and 50 deletions

View file

@ -46,7 +46,7 @@
"indent": [ "error", 4, { "SwitchCase": 1 } ], "indent": [ "error", 4, { "SwitchCase": 1 } ],
"key-spacing": [ "error", { "beforeColon": false, "afterColon": true }], "key-spacing": [ "error", { "beforeColon": false, "afterColon": true }],
"linebreak-style": [ "off" ], "linebreak-style": [ "off" ],
"lines-around-comment": [ "error", { "beforeBlockComment": true, "afterBlockComment": false, "beforeLineComment": true, "afterLineComment": false, "allowBlockStart": true, "allowBlockEnd": false, "allowObjectStart": true, "allowArrayStart": true, "allowBlockEnd": true }], "lines-around-comment": [ "error", { "beforeBlockComment": true, "afterBlockComment": false, "beforeLineComment": true, "afterLineComment": false, "allowBlockStart": true, "allowBlockEnd": false, "allowObjectStart": true, "allowArrayStart": true }],
"new-parens": "error", "new-parens": "error",
"no-array-constructor": "error", "no-array-constructor": "error",
"no-lonely-if": "error", "no-lonely-if": "error",
@ -66,7 +66,7 @@
"space-in-parens": [ "error", "never" ], "space-in-parens": [ "error", "never" ],
"space-infix-ops": [ "error", { "int32Hint": true } ], "space-infix-ops": [ "error", { "int32Hint": true } ],
"wrap-regex": "error", "wrap-regex": "error",
"spaced-comment": [ "error", "always", { "block": { "balanced": true }} ] "spaced-comment": [ "error", "always", { "block": { "balanced": true, "exceptions": ["*", "!"] }} ]
} }
} }

View file

@ -1,7 +1,7 @@
{ {
"//": "npm publish --tag beta", "//": "npm publish --tag beta",
"name": "phaser", "name": "phaser",
"version": "3.0.0-beta.18", "version": "3.0.0-beta.19",
"release": "Shadow Coast", "release": "Shadow Coast",
"description": "A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers.", "description": "A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers.",
"author": "Richard Davey <rdavey@gmail.com> (http://www.photonstorm.com)", "author": "Richard Davey <rdavey@gmail.com> (http://www.photonstorm.com)",

View file

@ -576,6 +576,9 @@ var Text = new Class({
w *= this.resolution; w *= this.resolution;
h *= this.resolution; h *= this.resolution;
w = Math.max(w, 1);
h = Math.max(h, 1);
if (canvas.width !== w || canvas.height !== h) if (canvas.width !== w || canvas.height !== h)
{ {
canvas.width = w; canvas.width = w;

View file

@ -182,6 +182,12 @@ var Tile = new Class({
* @default * @default
*/ */
this.tint = 0xffffff; this.tint = 0xffffff;
/**
* An empty object where physics-engine specific information (e.g. bodies) may be stored.
* @property {object} physics
*/
this.physics = {};
}, },
/** /**

View file

@ -1,14 +1,15 @@
// Phaser.Input.InputManager
var Class = require('../utils/Class'); var Class = require('../utils/Class');
var EventEmitter = require('eventemitter3'); var EventEmitter = require('eventemitter3');
var Gamepad = require('./gamepad/GamepadManager'); var Gamepad = require('./gamepad/GamepadManager');
var Keyboard = require('./keyboard/KeyboardManager'); var Keyboard = require('./keyboard/KeyboardManager');
var Mouse = require('./mouse/MouseManager'); var Mouse = require('./mouse/MouseManager');
var Pointer = require('./Pointer'); var Pointer = require('./Pointer');
var Rectangle = require('../geom/rectangle/Rectangle');
var Touch = require('./touch/TouchManager'); var Touch = require('./touch/TouchManager');
var TransformXY = require('../math/TransformXY'); var TransformXY = require('../math/TransformXY');
// Phaser.Input.InputManager
var InputManager = new Class({ var InputManager = new Class({
initialize: initialize:
@ -46,7 +47,7 @@ var InputManager = new Class({
this.ignoreEvents = false; this.ignoreEvents = false;
this.bounds; this.bounds = new Rectangle();
this._tempPoint = { x: 0, y: 0 }; this._tempPoint = { x: 0, y: 0 };
this._tempHitTest = []; this._tempHitTest = [];
@ -72,22 +73,16 @@ var InputManager = new Class({
updateBounds: function () updateBounds: function ()
{ {
var bounds = this.canvas.getBoundingClientRect(); var clientRect = this.canvas.getBoundingClientRect();
var bounds = this.bounds;
if (window.scrollX) bounds.left = clientRect.left + window.pageXOffset;
{ bounds.top = clientRect.top + window.pageYOffset;
bounds.left += window.scrollX; bounds.width = clientRect.width;
} bounds.height = clientRect.height;
if (window.scrollY)
{
bounds.top += window.scrollY;
}
this.bounds = bounds;
}, },
update: function (time, delta) update: function (time)
{ {
this.keyboard.update(); this.keyboard.update();
this.gamepad.update(); this.gamepad.update();

View file

@ -15,6 +15,8 @@ var HTML5AudioFile = new Class({
{ {
this.locked = locked; this.locked = locked;
this.loaded = false;
var fileConfig = { var fileConfig = {
type: 'audio', type: 'audio',
extension: GetFastValue(url, 'type', ''), extension: GetFastValue(url, 'type', ''),
@ -29,7 +31,14 @@ var HTML5AudioFile = new Class({
onLoad: function () onLoad: function ()
{ {
this.callback(this, true); if(this.loaded)
{
return;
}
this.loaded = true;
this.loader.nextFile(this, true);
}, },
onError: function (event) onError: function (event)
@ -41,7 +50,7 @@ var HTML5AudioFile = new Class({
audio.onerror = null; audio.onerror = null;
} }
this.callback(this, false); this.loader.nextFile(this, false);
}, },
onProgress: function (event) onProgress: function (event)
@ -50,18 +59,22 @@ var HTML5AudioFile = new Class({
audio.oncanplaythrough = null; audio.oncanplaythrough = null;
audio.onerror = null; audio.onerror = null;
if(++this.filesLoaded === this.filesTotal) this.filesLoaded++;
this.percentComplete = Math.min((this.filesLoaded / this.filesTotal), 1);
this.loader.emit('fileprogress', this, this.percentComplete);
if(this.filesLoaded === this.filesTotal)
{ {
this.onLoad(); this.onLoad();
} }
this.percentComplete = Math.min((this.filesLoaded / this.filesTotal), 1);
}, },
// Called by the Loader, starts the actual file downloading // Called by the Loader, starts the actual file downloading
load: function (callback, baseURL) load: function (loader)
{ {
this.callback = callback; this.loader = loader;
this.data = []; this.data = [];
@ -90,7 +103,7 @@ var HTML5AudioFile = new Class({
for (i = 0; i < this.data.length; i++) for (i = 0; i < this.data.length; i++)
{ {
audio = this.data[i]; audio = this.data[i];
audio.src = GetURL(this, baseURL || ''); audio.src = GetURL(this, loader.baseURL);
if (!this.locked) if (!this.locked)
{ {
@ -100,13 +113,7 @@ var HTML5AudioFile = new Class({
if (this.locked) if (this.locked)
{ {
setTimeout(function () setTimeout(this.onLoad.bind(this));
{
this.filesLoaded = this.filesTotal;
this.percentComplete = 1;
this.onLoad();
}.bind(this));
} }
} }

View file

@ -17,9 +17,9 @@ var TilemapJSONFile = function (key, url, path, format, xhrSettings)
}; };
// When registering a factory function 'this' refers to the Loader context. // When registering a factory function 'this' refers to the Loader context.
// //
// There are several properties available to use: // There are several properties available to use:
// //
// this.scene - a reference to the Scene that owns the GameObjectFactory // this.scene - a reference to the Scene that owns the GameObjectFactory
FileTypesManager.register('tilemapTiledJSON', function (key, url, xhrSettings) FileTypesManager.register('tilemapTiledJSON', function (key, url, xhrSettings)
@ -48,12 +48,12 @@ FileTypesManager.register('tilemapWeltmeister', function (key, url, xhrSettings)
for (var i = 0; i < key.length; i++) for (var i = 0; i < key.length; i++)
{ {
// If it's an array it has to be an array of Objects, so we get everything out of the 'key' object // If it's an array it has to be an array of Objects, so we get everything out of the 'key' object
this.addFile(TilemapJSONFile(key[i], url, this.path, TILEMAP_FORMATS.WELTMEISTER.TILED_JSON, xhrSettings)); this.addFile(TilemapJSONFile(key[i], url, this.path, TILEMAP_FORMATS.WELTMEISTER, xhrSettings));
} }
} }
else else
{ {
this.addFile(TilemapJSONFile(key, url, this.path, TILEMAP_FORMATS.WELTMEISTER.TILED_JSON, xhrSettings)); this.addFile(TilemapJSONFile(key, url, this.path, TILEMAP_FORMATS.WELTMEISTER, xhrSettings));
} }
// For method chaining // For method chaining

View file

@ -5,11 +5,12 @@ var Constraint = require('./lib/constraint/Constraint');
var MatterImage = require('./MatterImage'); var MatterImage = require('./MatterImage');
var MatterSprite = require('./MatterSprite'); var MatterSprite = require('./MatterSprite');
var PointerConstraint = require('./PointerConstraint'); var PointerConstraint = require('./PointerConstraint');
var MatterTileBody = require('./MatterTileBody');
// When registering a factory function 'this' refers to the GameObjectFactory context. // When registering a factory function 'this' refers to the GameObjectFactory context.
// //
// There are several properties available to use: // There are several properties available to use:
// //
// this.scene - a reference to the Scene that owns the GameObjectFactory // this.scene - a reference to the Scene that owns the GameObjectFactory
// this.displayList - a reference to the Display List the Scene owns // this.displayList - a reference to the Display List the Scene owns
// this.updateList - a reference to the Update List the Scene owns // this.updateList - a reference to the Update List the Scene owns
@ -219,6 +220,13 @@ var Factory = new Class({
return image; return image;
}, },
tileBody: function (tile, options)
{
var tileBody = new MatterTileBody(this.world, tile, options);
return tileBody;
},
sprite: function (x, y, key, frame, options) sprite: function (x, y, key, frame, options)
{ {
var sprite = new MatterSprite(this.world, x, y, key, frame, options); var sprite = new MatterSprite(this.world, x, y, key, frame, options);

View file

@ -0,0 +1,188 @@
var AnimationComponent = require('../../gameobjects/components/Animation');
var Bodies = require('./lib/factory/Bodies');
var Class = require('../../utils/Class');
var Components = require('./components');
var GetFastValue = require('../../utils/object/GetFastValue');
var HasValue = require('../../utils/object/HasValue');
var Extend = require('../../utils/object/Extend');
var Body = require('./lib/body/Body');
var Vertices = require('./lib/geometry/Vertices');
var MatterTileBody = new Class({
Mixins: [
Components.Bounce,
Components.Collision,
Components.Friction,
Components.Gravity,
Components.Mass,
Components.Sensor,
Components.Sleep,
Components.Static
],
initialize:
function MatterTileBody (world, tile, options)
{
this.tile = tile;
this.world = world;
// A tile is only allowed one matter body
if (tile.physics.matterBody)
{
tile.physics.matterBody.destroy();
}
tile.physics.matterBody = this;
// Set the body either from an existing body (if provided), the shapes in the tileset
// collision layer (if it exists) or a rectangle matching the tile.
var body = GetFastValue(options, 'body', null);
var addToWorld = GetFastValue(options, 'addToWorld', true);
if (!body)
{
var tileset = tile.layer.tilemapLayer.tileset;
var collisionGroup = tileset.getTileCollisionGroup(tile.index);
var collisionObjects = GetFastValue(collisionGroup, 'objects', []);
if (collisionObjects.length > 0)
{
this.setFromTileCollision(options);
}
else
{
this.setFromTileRectangle(options);
}
}
else
{
this.setBody(body, addToWorld);
}
},
setFromTileRectangle: function (options)
{
if (options === undefined) { options = {}; }
if (!HasValue(options, "isStatic")) { options.isStatic = true; }
if (!HasValue(options, "addToWorld")) { options.addToWorld = true; }
var tile = this.tile;
var tilemapLayer = tile.layer.tilemapLayer;
var tileset = tilemapLayer.tileset;
var w = tile.width * tilemapLayer.scaleX;
var h = tile.height * tilemapLayer.scaleY;
var x = tilemapLayer.tileToWorldX(tile.x);
var y = tilemapLayer.tileToWorldY(tile.y);
var body = Bodies.rectangle(x + (w / 2), y + (h / 2), w, h, options);
this.setBody(body, options.addToWorld);
return this;
},
setFromTileCollision: function (options)
{
if (options === undefined) { options = {}; }
if (!HasValue(options, "isStatic")) { options.isStatic = true; }
if (!HasValue(options, "addToWorld")) { options.addToWorld = true; }
var tile = this.tile;
var tilemapLayer = tile.layer.tilemapLayer;
var tileset = tilemapLayer.tileset;
var w = tile.width * tilemapLayer.scaleX;
var h = tile.height * tilemapLayer.scaleY;
var x = tilemapLayer.tileToWorldX(tile.x);
var y = tilemapLayer.tileToWorldY(tile.y);
var collisionGroup = tileset.getTileCollisionGroup(tile.index);
var collisionObjects = GetFastValue(collisionGroup, 'objects', []);
var parts = [];
for (var i = 0; i < collisionObjects.length; i++)
{
var object = collisionObjects[i];
var ox = x + object.x;
var oy = y + object.y;
var ow = object.width;
var oh = object.height;
var body = null;
if (object.rectangle)
{
body = Bodies.rectangle(ox + ow / 2, oy + oh / 2, ow, oh, options);
}
else if (object.ellipse)
{
body = Bodies.circle(ox + ow / 2, oy + oh / 2, ow / 2, options);
}
else if (object.polygon || object.polyline)
{
// Polygons and polylines are both treated as closed polygons. Concave shapes are
// supported if poly-decomp library is included, but it's best to manually create
// convex polygons.
var originalPoints = object.polygon ? object.polygon : object.polyline;
var points = originalPoints.map(function (p) {
return { x: p[0], y: p[1] };
});
var vertices = Vertices.create(points);
// Translate from object position to center of mass
var center = Vertices.centre(vertices);
body = Bodies.fromVertices(ox + center.x, oy + center.y, vertices, options);
}
if (body)
{
parts.push(body);
}
}
if (parts.length === 1)
{
this.setBody(parts[0], options.addToWorld);
}
else if (parts.length > 1)
{
options.parts = parts;
this.setBody(Body.create(options), options.addToWorld);
}
return this;
},
setBody: function (body, addToWorld)
{
if (addToWorld === undefined) { addToWorld = true; }
if (this.body)
{
this.removeBody();
}
this.body = body;
this.body.gameObject = this;
if (addToWorld)
{
this.world.add(this.body);
}
return this;
},
removeBody: function ()
{
if (this.body)
{
this.world.remove(this.body);
this.body.gameObject = undefined;
this.body = undefined;
}
},
destroy: function ()
{
this.removeBody();
tile.physics.matterBody = undefined;
}
});
module.exports = MatterTileBody;

View file

@ -10,6 +10,7 @@ var GetValue = require('../../utils/object/GetValue');
var MatterBody = require('./lib/body/Body'); var MatterBody = require('./lib/body/Body');
var MatterEvents = require('./lib/core/Events'); var MatterEvents = require('./lib/core/Events');
var MatterWorld = require('./lib/body/World'); var MatterWorld = require('./lib/body/World');
var MatterTileBody = require('./MatterTileBody');
var World = new Class({ var World = new Class({
@ -38,7 +39,7 @@ var World = new Class({
* @property {object} walls - An object containing the 4 wall bodies that bound the physics world. * @property {object} walls - An object containing the 4 wall bodies that bound the physics world.
*/ */
this.walls = { left: null, right: null, top: null, bottom: null }; this.walls = { left: null, right: null, top: null, bottom: null };
if (GetFastValue(config, 'setBounds', false)) if (GetFastValue(config, 'setBounds', false))
{ {
var boundsConfig = config['setBounds']; var boundsConfig = config['setBounds'];
@ -283,6 +284,39 @@ var World = new Class({
return this; return this;
}, },
/**
* All colliding tiles will be set
*/
convertTilemapLayer: function (tilemapLayer, options)
{
var layerData = tilemapLayer.layer;
var tiles = tilemapLayer.getTilesWithin(0, 0, layerData.width, layerData.height, {
isColliding: true
});
this.convertTiles(tiles, options);
return this;
},
/**
* Array of tiles
*/
convertTiles: function (tiles, options)
{
if (tiles.length === 0)
{
return this;
}
for (var i = 0; i < tiles.length; i++)
{
new MatterTileBody(this, tiles[i], options);
}
return this;
},
nextGroup: function (isNonColliding) nextGroup: function (isNonColliding)
{ {
return MatterBody.nextGroup(isNonColliding); return MatterBody.nextGroup(isNonColliding);

View file

@ -167,6 +167,7 @@ var BaseSoundManager = new Class({
* @method Phaser.Sound.BaseSoundManager#play * @method Phaser.Sound.BaseSoundManager#play
* @param {string} key - Asset key for the sound. * @param {string} key - Asset key for the sound.
* @param {ISoundConfig | ISoundMarker} [extra] - An optional additional object containing settings to be applied to the sound. It could be either config or marker object. * @param {ISoundConfig | ISoundMarker} [extra] - An optional additional object containing settings to be applied to the sound. It could be either config or marker object.
* @returns {boolean} Whether the sound started playing successfully.
*/ */
play: function (key, extra) { play: function (key, extra) {
var sound = this.add(key); var sound = this.add(key);
@ -175,14 +176,14 @@ var BaseSoundManager = new Class({
if (extra) { if (extra) {
if (extra.name) { if (extra.name) {
sound.addMarker(extra); sound.addMarker(extra);
sound.play(extra.name); return sound.play(extra.name);
} }
else { else {
sound.play(extra); return sound.play(extra);
} }
} }
else { else {
sound.play(); return sound.play();
} }
}, },
/** /**
@ -193,11 +194,12 @@ var BaseSoundManager = new Class({
* @param {string} key - Asset key for the sound. * @param {string} key - Asset key for the sound.
* @param {string} spriteName - The name of the sound sprite to play. * @param {string} spriteName - The name of the sound sprite to play.
* @param {ISoundConfig} [config] - An optional config object containing default sound settings. * @param {ISoundConfig} [config] - An optional config object containing default sound settings.
* @returns {boolean} Whether the audio sprite sound started playing successfully.
*/ */
playAudioSprite: function (key, spriteName, config) { playAudioSprite: function (key, spriteName, config) {
var sound = this.addAudioSprite(key); var sound = this.addAudioSprite(key);
sound.once('ended', sound.destroy, sound); sound.once('ended', sound.destroy, sound);
sound.play(spriteName, config); return sound.play(spriteName, config);
}, },
/** /**
* Removes a sound from the sound manager. * Removes a sound from the sound manager.

View file

@ -1,6 +1,6 @@
var BaseSoundManager = require('./BaseSoundManager');
var WebAudioSoundManager = require('./webaudio/WebAudioSoundManager'); var WebAudioSoundManager = require('./webaudio/WebAudioSoundManager');
var HTML5AudioSoundManager = require('./html5/HTML5AudioSoundManager'); var HTML5AudioSoundManager = require('./html5/HTML5AudioSoundManager');
var NoAudioSoundManager = require('./noaudio/NoAudioSoundManager');
var SoundManagerCreator = { var SoundManagerCreator = {
@ -11,8 +11,7 @@ var SoundManagerCreator = {
if ((audioConfig && audioConfig.noAudio) || (!deviceAudio.webAudio && !deviceAudio.audioData)) if ((audioConfig && audioConfig.noAudio) || (!deviceAudio.webAudio && !deviceAudio.audioData))
{ {
// TODO add no audio implementation of BaseSoundManager return new NoAudioSoundManager(game);
return new BaseSoundManager(game);
} }
if(deviceAudio.webAudio && !(audioConfig && audioConfig.disableWebAudio)) if(deviceAudio.webAudio && !(audioConfig && audioConfig.disableWebAudio))

View file

@ -11,6 +11,9 @@ module.exports = {
WebAudioSoundManager: require('./webaudio/WebAudioSoundManager'), WebAudioSoundManager: require('./webaudio/WebAudioSoundManager'),
HTML5AudioSound: require('./html5/HTML5AudioSound'), HTML5AudioSound: require('./html5/HTML5AudioSound'),
HTML5AudioSoundManager: require('./html5/HTML5AudioSoundManager') HTML5AudioSoundManager: require('./html5/HTML5AudioSoundManager'),
NoAudioSound: require('./noaudio/NoAudioSound'),
NoAudioSoundManager: require('./noaudio/NoAudioSoundManager')
}; };

View file

@ -0,0 +1,62 @@
var Class = require('../../utils/Class');
var EventEmitter = require('eventemitter3');
var Extend = require('../../utils/object/Extend');
var BaseSound = require('../BaseSound');
var NoAudioSound = new Class({
Extends: EventEmitter,
initialize: function NoAudioSound(manager, key, config) {
EventEmitter.call(this);
this.manager = manager;
this.key = key;
this.isPlaying = false;
this.isPaused = false;
this.totalRate = 1;
this.duration = 0;
this.totalDuration = 0;
this.config = Extend({
mute: false,
volume: 1,
rate: 1,
detune: 0,
seek: 0,
loop: false,
delay: 0
}, config);
this.currentConfig = this.config;
this.mute = false;
this.volume = 1;
this.rate = 1;
this.detune = 0;
this.seek = 0;
this.loop = false;
this.markers = {};
this.currentMarker = null;
this.pendingRemove = false;
},
addMarker: function (marker) {
return false;
},
updateMarker: function (marker) {
return false;
},
removeMarker: function (markerName) {
return null;
},
play: function (markerName, config) {
return false;
},
pause: function () {
return false;
},
resume: function () {
return false;
},
stop: function () {
return false;
},
destroy: function () {
this.manager.remove(this);
BaseSound.prototype.destroy.call(this);
}
});
module.exports = NoAudioSound;

View file

@ -0,0 +1,52 @@
var Class = require('../../utils/Class');
var EventEmitter = require('eventemitter3');
var NoAudioSound = require('./NoAudioSound');
var BaseSoundManager = require('../BaseSoundManager');
var NOOP = require('../../utils/NOOP');
var NoAudioSoundManager = new Class({
Extends: EventEmitter,
initialize: function NoAudioSoundManager(game) {
EventEmitter.call(this);
this.game = game;
this.sounds = [];
this.mute = false;
this.volume = 1;
this.rate = 1;
this.detune = 0;
this.pauseOnBlur = true;
this.locked = false;
},
add: function (key, config) {
var sound = new NoAudioSound(this, key, config);
this.sounds.push(sound);
return sound;
},
addAudioSprite: function (key, config) {
var sound = this.add(key, config);
sound.spritemap = {};
return sound;
},
play: function (key, extra) {
return false;
},
playAudioSprite: function (key, spriteName, config) {
return false;
},
remove: function (sound) {
return BaseSoundManager.prototype.remove.call(this, sound);
},
removeByKey: function (key) {
return BaseSoundManager.prototype.removeByKey.call(this, key);
},
pauseAll: NOOP,
resumeAll: NOOP,
stopAll: NOOP,
update: NOOP,
destroy: function () {
BaseSoundManager.prototype.destroy.call(this);
},
forEachActiveSound: function (callbackfn, thisArg) {
BaseSoundManager.prototype.forEachActiveSound.call(this, callbackfn, thisArg);
}
});
module.exports = NoAudioSoundManager;