Merge remote-tracking branch 'origin/master'

This commit is contained in:
Pavle Goloskokovic 2018-01-11 16:51:11 +01:00
commit 5aec2e45e4
23 changed files with 458 additions and 37 deletions

View file

@ -1,9 +1,10 @@
var AlignIn = require('../display/align/in/QuickSet');
var CONST = require('../display/align/const');
var GetValue = require('../utils/object/GetValue');
var NOOP = require('../utils/NOOP');
var Zone = require('../gameobjects/zone/Zone');
var tempZone = new Zone({ sys: { sortChildrenFlag: false }}, 0, 0, 1, 1);
var tempZone = new Zone({ sys: { queueDepthSort: NOOP }}, 0, 0, 1, 1);
/**
* [description]

View file

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

View file

@ -1,6 +1,6 @@
var Class = require('../../utils/Class');
var Event = require('../../events/Event');
var EventDispatcher = require('../../events/EventDispatcher');
var Class = require('../utils/Class');
var Event = require('../events/Event');
var EventDispatcher = require('../events/EventDispatcher');
/**
* 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 DataStore = new Class({

View file

@ -121,7 +121,7 @@ var GameObject = new Class({
this.body = null;
// Tell the Scene to re-sort the children
this.scene.sys.sortChildrenFlag = true;
this.scene.sys.queueDepthSort();
},
/**
@ -294,7 +294,7 @@ var GameObject = new Class({
}
// Tell the Scene to re-sort the children
this.scene.sys.sortChildrenFlag = true;
this.scene.sys.queueDepthSort();
this.active = false;
this.visible = false;

View file

@ -14,7 +14,7 @@ var Depth = {
set: function (value)
{
this.scene.sys.sortChildrenFlag = true;
this.scene.sys.queueDepthSort();
this._depth = value;
}

View file

@ -180,7 +180,7 @@ var Transform = {
set: function (value)
{
this.scene.sys.sortChildrenFlag = true;
this.scene.sys.queueDepthSort();
this._depth = value;
}

View file

@ -49,6 +49,13 @@ var DynamicTilemapLayer = new Class({
{
GameObject.call(this, scene, 'DynamicTilemapLayer');
/**
* Used internally by physics system to perform fast type checks.
* @property {boolean} isTilemap
* @readonly
*/
this.isTilemap = true;
/**
* The Tilemap that this layer is a part of.
* @property {Tilemap} map

View file

@ -49,6 +49,13 @@ var StaticTilemapLayer = new Class({
{
GameObject.call(this, scene, 'StaticTilemapLayer');
/**
* Used internally by physics system to perform fast type checks.
* @property {boolean} isTilemap
* @readonly
*/
this.isTilemap = true;
/**
* The Tilemap that this layer is a part of.
* @property {Tilemap} map

View file

@ -131,8 +131,6 @@ var Body = new Class({
this.blocked = { none: true, up: false, down: false, left: false, right: false };
this.tilePadding = new Vector2();
this.dirty = false;
this.syncBounds = false;

View file

@ -48,6 +48,8 @@ var World = new Class({
this.OVERLAP_BIAS = GetValue(config, 'overlapBias', 4);
this.TILE_BIAS = GetValue(config, 'tileBias', 16);
this.forceX = GetValue(config, 'forceX', false);
this.isPaused = GetValue(config, 'isPaused', false);
@ -387,6 +389,8 @@ var World = new Class({
collideHandler: require('./inc/CollideHandler'),
collideSpriteVsSprite: require('./inc/CollideSpriteVsSprite'),
collideSpriteVsGroup: require('./inc/CollideSpriteVsGroup'),
collideGroupVsTilemapLayer: require('./inc/CollideGroupVsTilemapLayer'),
collideSpriteVsTilemapLayer: require('./inc/CollideSpriteVsTilemapLayer'),
// Utils
accelerateTo: require('./utils/AccelerateTo'),

View file

@ -0,0 +1,8 @@
var CollideGroupVsTilemapLayer = function (group, tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly)
{
// TODO
return false;
};
module.exports = CollideGroupVsTilemapLayer;

View file

@ -0,0 +1,50 @@
var SeparateTile = require('./tilemap/SeparateTile');
var TileIntersectsBody = require('./tilemap/TileIntersectsBody');
var ProcessTileCallbacks = require('./tilemap/ProcessTileCallbacks');
var CollideSpriteVsTilemapLayer = function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly)
{
var body = sprite.body;
if (!body.enable)
{
return false;
}
var mapData = tilemapLayer.getTilesWithinWorldXY(
body.position.x, body.position.y,
body.width, body.height
);
if (mapData.length === 0)
{
return false;
}
var tile;
var tileWorldRect = { left: 0, right: 0, top: 0, bottom: 0 };
for (var i = 0; i < mapData.length; i++)
{
tile = mapData[i];
tileWorldRect.left = tilemapLayer.tileToWorldX(tile.x);
tileWorldRect.top = tilemapLayer.tileToWorldY(tile.y);
tileWorldRect.right = tileWorldRect.left + tile.width * tilemapLayer.scaleX;
tileWorldRect.bottom = tileWorldRect.top + tile.height * tilemapLayer.scaleY;
if (TileIntersectsBody(tileWorldRect, body)
&& (!processCallback || processCallback.call(callbackContext, sprite, tile))
&& ProcessTileCallbacks(tile)
&& (overlapOnly || SeparateTile(i, body, tile, tileWorldRect, tilemapLayer, this.TILE_BIAS)))
{
this._total++;
if (collideCallback)
{
collideCallback.call(callbackContext, sprite, tile);
}
}
}
};
module.exports = CollideSpriteVsTilemapLayer;

View file

@ -0,0 +1,20 @@
var ProcessTileCallbacks = function (tile)
{
return true;
// TODO: port v2
// // Tilemap & tile callbacks take priority
// // A local callback always takes priority over a layer level callback
// if (tile.collisionCallback && !tile.collisionCallback.call(tile.collisionCallbackContext, body.sprite, tile))
// {
// // If it returns true then we can carry on, otherwise we should abort.
// return false;
// }
// else if (typeof tile.layer.callbacks !== 'undefined' && tile.layer.callbacks[tile.index] && !tile.layer.callbacks[tile.index].callback.call(tile.layer.callbacks[tile.index].callbackContext, body.sprite, tile))
// {
// // If it returns true then we can carry on, otherwise we should abort.
// return false;
// }
};
module.exports = ProcessTileCallbacks;

View file

@ -0,0 +1,32 @@
/**
* Internal function to process the separation of a physics body from a tile.
*
* @private
* @method Phaser.Physics.Arcade#processTileSeparationX
* @param {Phaser.Physics.Arcade.Body} body - The Body object to separate.
* @param {number} x - The x separation amount.
*/
var ProcessTileSeparationX = function (body, x)
{
if (x < 0)
{
body.blocked.left = true;
}
else if (x > 0)
{
body.blocked.right = true;
}
body.position.x -= x;
if (body.bounce.x === 0)
{
body.velocity.x = 0;
}
else
{
body.velocity.x = -body.velocity.x * body.bounce.x;
}
};
module.exports = ProcessTileSeparationX;

View file

@ -0,0 +1,32 @@
/**
* Internal function to process the separation of a physics body from a tile.
*
* @private
* @method Phaser.Physics.Arcade#processTileSeparationY
* @param {Phaser.Physics.Arcade.Body} body - The Body object to separate.
* @param {number} y - The y separation amount.
*/
var ProcessTileSeparationY = function (body, y)
{
if (y < 0)
{
body.blocked.up = true;
}
else if (y > 0)
{
body.blocked.down = true;
}
body.position.y -= y;
if (body.bounce.y === 0)
{
body.velocity.y = 0;
}
else
{
body.velocity.y = -body.velocity.y * body.bounce.y;
}
};
module.exports = ProcessTileSeparationY;

View file

@ -0,0 +1,94 @@
var TileCheckX = require('./TileCheckX');
var TileCheckY = require('./TileCheckY');
var TileIntersectsBody = require('./TileIntersectsBody');
/**
* The core separation function to separate a physics body and a tile.
*
* @param {Phaser.Physics.Arcade.Body} body - The Body object to separate.
* @param {Phaser.Tile} tile - The tile to collide against.
* @param {Phaser.TilemapLayer} tilemapLayer - The tilemapLayer to collide against.
* @return {boolean} Returns true if the body was separated, otherwise false.
*/
var SeparateTile = function (i, body, tile, tileWorldRect, tilemapLayer, tileBias)
{
var tileLeft = tileWorldRect.left;
var tileTop = tileWorldRect.top;
var tileRight = tileWorldRect.right;
var tileBottom = tileWorldRect.bottom;
var faceHorizontal = tile.faceLeft || tile.faceRight;
var faceVertical = tile.faceTop || tile.faceBottom;
// We don't need to go any further if this tile doesn't actually have any colliding faces. This
// could happen if the tile was meant to be collided with re: a callback, but otherwise isn't
// needed for separation.
if (!faceHorizontal && !faceVertical)
{
return false;
}
var ox = 0;
var oy = 0;
var minX = 0;
var minY = 1;
if (body.deltaAbsX() > body.deltaAbsY())
{
// Moving faster horizontally, check X axis first
minX = -1;
}
else if (body.deltaAbsX() < body.deltaAbsY())
{
// Moving faster vertically, check Y axis first
minY = -1;
}
if (body.deltaX() !== 0 && body.deltaY() !== 0 && faceHorizontal && faceVertical)
{
// We only need do this if both axes have colliding faces AND we're moving in both
// directions
minX = Math.min(Math.abs(body.position.x - tileRight), Math.abs(body.right - tileLeft));
minY = Math.min(Math.abs(body.position.y - tileBottom), Math.abs(body.bottom - tileTop));
}
if (minX < minY)
{
if (faceHorizontal)
{
ox = TileCheckX(body, tile, tilemapLayer, tileBias);
// That's horizontal done, check if we still intersects? If not then we can return now
if (ox !== 0 && !TileIntersectsBody(tileWorldRect, body))
{
return true;
}
}
if (faceVertical)
{
oy = TileCheckY(body, tile, tilemapLayer, tileBias);
}
}
else
{
if (faceVertical)
{
oy = TileCheckY(body, tile, tilemapLayer, tileBias);
// That's vertical done, check if we still intersects? If not then we can return now
if (oy !== 0 && !TileIntersectsBody(tileWorldRect, body))
{
return true;
}
}
if (faceHorizontal)
{
ox = TileCheckX(body, tile, tilemapLayer, tileBias);
}
}
return (ox !== 0 || oy !== 0);
};
module.exports = SeparateTile;

View file

@ -0,0 +1,62 @@
var ProcessTileSeparationX = require('./ProcessTileSeparationX');
/**
* Check the body against the given tile on the X axis.
*
* @private
* @method Phaser.Physics.Arcade#tileCheckX
* @param {Phaser.Physics.Arcade.Body} body - The Body object to separate.
* @param {Phaser.Tile} tile - The tile to check.
* @param {Phaser.TilemapLayer} tilemapLayer - The tilemapLayer to collide against.
* @return {number} The amount of separation that occurred.
*/
var TileCheckX = function (body, tile, tilemapLayer, tileBias)
{
var ox = 0;
var tileLeft = tilemapLayer.tileToWorldX(tile.x);
var tileWidth = tile.width * tilemapLayer.scaleX;
var tileRight = tileLeft + tileWidth;
if (body.deltaX() < 0 && !body.blocked.left && tile.collideRight && body.checkCollision.left)
{
// Body is moving LEFT
if (tile.faceRight && body.x < tileRight)
{
ox = body.x - tileRight;
if (ox < -tileBias)
{
ox = 0;
}
}
}
else if (body.deltaX() > 0 && !body.blocked.right && tile.collideLeft && body.checkCollision.right)
{
// Body is moving RIGHT
if (tile.faceLeft && body.right > tileLeft)
{
ox = body.right - tileLeft;
if (ox > tileBias)
{
ox = 0;
}
}
}
if (ox !== 0)
{
if (body.customSeparateX)
{
body.overlapX = ox;
}
else
{
ProcessTileSeparationX(body, ox);
}
}
return ox;
};
module.exports = TileCheckX;

View file

@ -0,0 +1,62 @@
var ProcessTileSeparationY = require('./ProcessTileSeparationY');
/**
* Check the body against the given tile on the Y axis.
*
* @private
* @method Phaser.Physics.Arcade#tileCheckY
* @param {Phaser.Physics.Arcade.Body} body - The Body object to separate.
* @param {Phaser.Tile} tile - The tile to check.
* @param {Phaser.TilemapLayer} tilemapLayer - The tilemapLayer to collide against.
* @return {number} The amount of separation that occurred.
*/
var TileCheckY = function (body, tile, tilemapLayer, tileBias)
{
var oy = 0;
var tileTop = tilemapLayer.tileToWorldX(tile.y);
var tileHeight = tile.height * tilemapLayer.scaleY;
var tileBottom = tileTop + tileHeight;
if (body.deltaY() < 0 && !body.blocked.up && tile.collideDown && body.checkCollision.up)
{
// Body is moving UP
if (tile.faceBottom && body.y < tileBottom)
{
oy = body.y - tileBottom;
if (oy < -tileBias)
{
oy = 0;
}
}
}
else if (body.deltaY() > 0 && !body.blocked.down && tile.collideUp && body.checkCollision.down)
{
// Body is moving DOWN
if (tile.faceTop && body.bottom > tileTop)
{
oy = body.bottom - tileTop;
if (oy > tileBias)
{
oy = 0;
}
}
}
if (oy !== 0)
{
if (body.customSeparateY)
{
body.overlapY = oy;
}
else
{
ProcessTileSeparationY(body, oy);
}
}
return oy;
};
module.exports = TileCheckY;

View file

@ -0,0 +1,18 @@
var TileIntersectsBody = function (tileWorldRect, body)
{
if (body.isCircle)
{
return false;
}
else
{
return !(
body.right <= tileWorldRect.left ||
body.bottom <= tileWorldRect.top ||
body.position.x >= tileWorldRect.right ||
body.position.y >= tileWorldRect.bottom
);
}
};
module.exports = TileIntersectsBody;

View file

@ -9,6 +9,7 @@ var InjectionMap = {
anims: 'anims',
cache: 'cache',
registry: 'registry',
sound: 'sound',
textures: 'textures',
add: 'add',

View file

@ -1,8 +1,8 @@
var CameraManager = require('../../camera/local/CameraManager');
var Class = require('../../utils/Class');
var Clock = require('../../time/Clock');
var Data = require('../plugins/Data');
var DataStore = require('../plugins/DataStore');
var Data = require('../../data/Data');
var DataStore = require('../../data/DataStore');
var DisplayList = require('../plugins/DisplayList');
var EventDispatcher = require('../../events/EventDispatcher');
var GameObjectCreator = require('../plugins/GameObjectCreator');
@ -16,6 +16,8 @@ var StableSort = require('../../utils/array/StableSort');
var TweenManager = require('../../tweens/manager/TweenManager');
var UpdateList = require('../plugins/UpdateList');
var PluginManager = require('../../plugins/PluginManager');
var Systems = new Class({
initialize:
@ -27,10 +29,6 @@ var Systems = new Class({
this.config = config;
this.settings = Settings.create(config);
this.renderList = [];
this.sortChildrenFlag = false;
// Set by the GlobalSceneManager
this.canvas;
this.context;
@ -42,6 +40,7 @@ var Systems = new Class({
this.anims;
this.cache;
this.registry;
this.sound;
this.textures;
// Reference to Scene specific managers (Factory, Tweens, Loader, Physics, etc)
@ -59,6 +58,8 @@ var Systems = new Class({
this.time;
this.tweens;
this.updateList;
this.plugins;
},
init: function (game)
@ -72,8 +73,11 @@ var Systems = new Class({
this.anims = game.anims;
this.cache = game.cache;
this.registry = game.registry;
this.sound = game.sound;
this.textures = game.textures;
this.plugins = new PluginManager(scene);
// Scene specific managers (Factory, Tweens, Loader, Physics, etc)
this.add = new GameObjectFactory(scene);
@ -153,37 +157,23 @@ var Systems = new Class({
return;
}
// inlined to avoid branching
if (this.sortChildrenFlag)
{
StableSort.inplace(this.displayList.list, this.sortZ);
var displayList = this.displayList;
this.sortChildrenFlag = false;
}
displayList.process();
this.cameras.render(renderer, this.displayList, interpolation);
this.cameras.render(renderer, displayList, interpolation);
},
// Force a sort of the display list on the next render
queueDepthSort: function ()
{
this.sortChildrenFlag = true;
this.displayList.queueDepthSort();
},
// Immediately sorts the display list if the flag is set
depthSort: function ()
{
if (this.sortChildrenFlag)
{
StableSort.inplace(this.displayList.list, this.sortZ);
this.sortChildrenFlag = false;
}
},
sortZ: function (childA, childB)
{
return childA._depth - childB._depth;
this.displayList.depthSort();
},
// A paused Scene still renders, it just doesn't run ANY of its update handlers or systems

View file

@ -1,4 +1,5 @@
var Class = require('../../utils/Class');
var StableSort = require('../../utils/array/StableSort');
var DisplayList = new Class({
@ -13,9 +14,43 @@ var DisplayList = new Class({
// The equivalent of the old `Sprite.children` array.
this.list = [];
this.sortChildrenFlag = false;
this.position = 0;
},
process: function ()
{
if (this.sortChildrenFlag)
{
StableSort.inplace(this.list, this.sortZ);
this.sortChildrenFlag = false;
}
},
sortZ: function (childA, childB)
{
return childA._depth - childB._depth;
},
// Force a sort of the display list on the next call to process
queueDepthSort: function ()
{
this.sortChildrenFlag = true;
},
// Immediately sorts the display list if the flag is set
depthSort: function ()
{
if (this.sortChildrenFlag)
{
StableSort.inplace(this.list, this.sortZ);
this.sortChildrenFlag = false;
}
},
add: function (child)
{
// Is child already in this display list?