diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 086a6c716..4309c9657 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,10 +1,10 @@ -#How to contribute +# How to contribute It's important to us that you feel you can contribute towards the evolution of Phaser. This can take many forms: from helping to fix bugs or improve the docs, to adding in new features to the source. This guide should help you in making that process as smooth as possible. Before contributing, please read the [code of conduct](https://github.com/photonstorm/phaser/blob/master/v2/CODE_OF_CONDUCT.md). -##Reporting issues +## Reporting issues [GitHub Issues][0] is the place to report bugs you may have found. When submitting a bug please do the following: @@ -19,12 +19,12 @@ Before contributing, please read the [code of conduct](https://github.com/photon **5. Share as much information as possible.** Include browser version affected, your OS, version of the library, steps to reproduce, etc. "X isn't working!!!1!" will probably just be closed. -##Pixi and Phaser +## Pixi and Phaser It's important to understand that internally Phaser 2 uses a heavily customized version of [Pixi.js v2](https://github.com/GoodBoyDigital/pixi.js/) for all rendering. It's possible you may find a bug that is generated on the Pixi level rather than Phaser. You're welcome to still report the issue of course, but if you get a reply saying we think it might be a Pixi issue, this is what we're talking about :) -##Support Forum +## Support Forum We have a very active [Phaser Support Forum][4]. If you need general support, or are struggling to understand how to do something or need your code checked over, then we would urge you to post it to our forum. There are a lot of friendly devs in there who can help, as well as the core Phaser and Pixi teams, so it's a great place to get support from. You're welcome to report bugs directly on GitHub, but for general support we'd always recommend using the forum first. @@ -47,17 +47,17 @@ make your changes and submit a Pull Request: - **Only commit relevant changes.** Don't include changes that are not directly relevant to the fix you are making. The more focused a PR is, the faster it will get attention and be merged. Extra files changing only whitespace or trash files will likely get your PR closed. -##Coding style preferences are not contributions +## Coding style preferences are not contributions If your PR is doing little more than changing the Phaser source code into a format / coding style that you prefer then we will automatically close it. All PRs must adhere to the coding style already set-out across the thousands of lines of code in Phaser. Your personal preferences for how things should "look" or be structured do not apply here, sorry. PRs should fix bugs, fix documentation or add features. No changes for the sake of change. -##I don't really like git / node.js, but I can fix this bug +## I don't really like git / node.js, but I can fix this bug That is fine too. While Pull Requests are the best thing in the world for us, they are not the only way to help. You're welcome to post fixes to our forum or even just email them to us. All we ask is that you still adhere to the guidelines presented here re: JSHint, etc. -##Code Style Guide +## Code Style Guide - Use 4 spaces for tabs, never tab characters. diff --git a/src/actions/GridAlign.js b/src/actions/GridAlign.js index 7412027e9..041c62897 100644 --- a/src/actions/GridAlign.js +++ b/src/actions/GridAlign.js @@ -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] diff --git a/src/camera/3d/Camera3D.js b/src/camera/3d/Camera3D.js index b085b77ff..2e08ec376 100644 --- a/src/camera/3d/Camera3D.js +++ b/src/camera/3d/Camera3D.js @@ -298,7 +298,7 @@ var Camera3D = new Class({ dir.set(x, y, z); } - dir.sub(this.position).normalize(); + dir.subtract(this.position).normalize(); // Calculate right vector tmpVec3.copy(dir).cross(up).normalize(); @@ -319,7 +319,7 @@ var Camera3D = new Class({ rotateAround: function (point, radians, axis) { - tmpVec3.copy(point).sub(this.position); + tmpVec3.copy(point).subtract(this.position); this.translate(tmpVec3); this.rotate(radians, axis); @@ -391,7 +391,7 @@ var Camera3D = new Class({ direction.unproject(viewport, mtx); - direction.sub(origin).normalize(); + direction.subtract(origin).normalize(); return this.ray; }, @@ -419,7 +419,7 @@ var Camera3D = new Class({ var dir = dirvec.set(this.direction).negate(); // Better view-aligned billboards might use this: - // var dir = tmp.set(camera.position).sub(p).normalize(); + // var dir = tmp.set(camera.position).subtract(p).normalize(); var right = rightvec.set(this.up).cross(dir).normalize(); var up = tmpVec3.set(dir).cross(right).normalize(); diff --git a/src/curves/curve/inc/GetTangent.js b/src/curves/curve/inc/GetTangent.js index 474c11c25..e4b46b741 100644 --- a/src/curves/curve/inc/GetTangent.js +++ b/src/curves/curve/inc/GetTangent.js @@ -39,7 +39,7 @@ var GetTangent = function (t, out) this.getPoint(t1, this._tmpVec2A); this.getPoint(t2, out); - return out.sub(this._tmpVec2A).normalize(); + return out.subtract(this._tmpVec2A).normalize(); }; module.exports = GetTangent; diff --git a/src/curves/line/LineCurve.js b/src/curves/line/LineCurve.js index 124f6a5a9..d162846b2 100644 --- a/src/curves/line/LineCurve.js +++ b/src/curves/line/LineCurve.js @@ -59,7 +59,7 @@ var LineCurve = new Class({ return out.copy(this.p1); } - out.copy(this.p1).sub(this.p0).scale(t).add(this.p0); + out.copy(this.p1).subtract(this.p0).scale(t).add(this.p0); return out; }, @@ -72,7 +72,7 @@ var LineCurve = new Class({ getTangent: function () { - var tangent = tmpVec2.copy(this.p1).sub(this.p0); + var tangent = tmpVec2.copy(this.p1).subtract(this.p0); return tangent.normalize(); }, diff --git a/src/curves/path/inc/EllipseTo.js b/src/curves/path/inc/EllipseTo.js index ab5017c0f..4b13e9327 100644 --- a/src/curves/path/inc/EllipseTo.js +++ b/src/curves/path/inc/EllipseTo.js @@ -26,7 +26,7 @@ var EllipseTo = function (xRadius, yRadius, startAngle, endAngle, clockwise, rot // Calculate where to center the ellipse var start = ellipse.getStartPoint(this._tmpVec2B); - end.sub(start); + end.subtract(start); ellipse.x = end.x; ellipse.y = end.y; diff --git a/src/gameobjects/GameObject.js b/src/gameobjects/GameObject.js index faeddef62..53ce79e76 100644 --- a/src/gameobjects/GameObject.js +++ b/src/gameobjects/GameObject.js @@ -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; diff --git a/src/gameobjects/components/Depth.js b/src/gameobjects/components/Depth.js index 358332ba4..ec96ba5af 100644 --- a/src/gameobjects/components/Depth.js +++ b/src/gameobjects/components/Depth.js @@ -14,7 +14,7 @@ var Depth = { set: function (value) { - this.scene.sys.sortChildrenFlag = true; + this.scene.sys.queueDepthSort(); this._depth = value; } diff --git a/src/gameobjects/components/Transform.js b/src/gameobjects/components/Transform.js index 8013e68a5..9b8216a6a 100644 --- a/src/gameobjects/components/Transform.js +++ b/src/gameobjects/components/Transform.js @@ -180,7 +180,7 @@ var Transform = { set: function (value) { - this.scene.sys.sortChildrenFlag = true; + this.scene.sys.queueDepthSort(); this._depth = value; } diff --git a/src/gameobjects/tilemap/dynamiclayer/DynamicTilemapLayer.js b/src/gameobjects/tilemap/dynamiclayer/DynamicTilemapLayer.js index 4cdcec323..c3e2dea47 100644 --- a/src/gameobjects/tilemap/dynamiclayer/DynamicTilemapLayer.js +++ b/src/gameobjects/tilemap/dynamiclayer/DynamicTilemapLayer.js @@ -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 diff --git a/src/gameobjects/tilemap/staticlayer/StaticTilemapLayer.js b/src/gameobjects/tilemap/staticlayer/StaticTilemapLayer.js index 2b18bddfc..ceb40a989 100644 --- a/src/gameobjects/tilemap/staticlayer/StaticTilemapLayer.js +++ b/src/gameobjects/tilemap/staticlayer/StaticTilemapLayer.js @@ -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 diff --git a/src/input/keyboard/combo/KeyComboMatchEvent.js b/src/input/keyboard/combo/KeyComboMatchEvent.js index 7928b3c11..a8661dce9 100644 --- a/src/input/keyboard/combo/KeyComboMatchEvent.js +++ b/src/input/keyboard/combo/KeyComboMatchEvent.js @@ -11,9 +11,7 @@ var KeyComboMatchEvent = new Class({ { Event.call(this, 'KEY_COMBO_MATCH_EVENT'); - this.target = keyCombo; - - this.data = keyboardEvent; + this.data = keyCombo; } }); diff --git a/src/math/Quaternion.js b/src/math/Quaternion.js index e8f3040bb..dd819e658 100644 --- a/src/math/Quaternion.js +++ b/src/math/Quaternion.js @@ -168,7 +168,7 @@ var Quaternion = new Class({ if (dot < -0.999999) { - if (tmpvec.copy(xUnitVec3).cross(a).len() < EPSILON) + if (tmpvec.copy(xUnitVec3).cross(a).length() < EPSILON) { tmpvec.copy(yUnitVec3).cross(a); } diff --git a/src/physics/arcade/Body.js b/src/physics/arcade/Body.js index aa7c1ce59..abec94ca1 100644 --- a/src/physics/arcade/Body.js +++ b/src/physics/arcade/Body.js @@ -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; diff --git a/src/physics/arcade/World.js b/src/physics/arcade/World.js index f619ef2d2..e6259718f 100644 --- a/src/physics/arcade/World.js +++ b/src/physics/arcade/World.js @@ -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'), diff --git a/src/physics/arcade/inc/CollideGroupVsTilemapLayer.js b/src/physics/arcade/inc/CollideGroupVsTilemapLayer.js new file mode 100644 index 000000000..ac2812ee2 --- /dev/null +++ b/src/physics/arcade/inc/CollideGroupVsTilemapLayer.js @@ -0,0 +1,25 @@ +var CollideGroupVsTilemapLayer = function (group, tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly) +{ + var children = group.getChildren(); + + if (children.length === 0) + { + return false; + } + + var didCollide = false; + + for (var i = 0; i < children.length; i++) + { + if (children[i].body) + { + if (this.collideSpriteVsTilemapLayer(children[i], tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly)) { + didCollide = true; + } + } + } + + return didCollide; +}; + +module.exports = CollideGroupVsTilemapLayer; diff --git a/src/physics/arcade/inc/CollideHandler.js b/src/physics/arcade/inc/CollideHandler.js index 084177c2a..83eea732e 100644 --- a/src/physics/arcade/inc/CollideHandler.js +++ b/src/physics/arcade/inc/CollideHandler.js @@ -9,7 +9,7 @@ var CollideHandler = function (object1, object2, collideCallback, processCallbac // If neither of the objects are set then bail out if (!object1 || !object2) { - return; + return false; } // A Body @@ -17,15 +17,15 @@ var CollideHandler = function (object1, object2, collideCallback, processCallbac { if (object2.body) { - this.collideSpriteVsSprite(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + return this.collideSpriteVsSprite(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); } else if (object2.isParent) { - this.collideSpriteVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + return this.collideSpriteVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); } else if (object2.isTilemap) { - this.collideSpriteVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + return this.collideSpriteVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); } } // GROUPS @@ -33,15 +33,15 @@ var CollideHandler = function (object1, object2, collideCallback, processCallbac { if (object2.body) { - this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); + return this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); } else if (object2.isParent) { - this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + return this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); } else if (object2.isTilemap) { - this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + return this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); } } // TILEMAP LAYERS @@ -49,11 +49,11 @@ var CollideHandler = function (object1, object2, collideCallback, processCallbac { if (object2.body) { - this.collideSpriteVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); + return this.collideSpriteVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); } else if (object2.isParent) { - this.collideGroupVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); + return this.collideGroupVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); } } }; diff --git a/src/physics/arcade/inc/CollideSpriteVsTilemapLayer.js b/src/physics/arcade/inc/CollideSpriteVsTilemapLayer.js new file mode 100644 index 000000000..3d379c422 --- /dev/null +++ b/src/physics/arcade/inc/CollideSpriteVsTilemapLayer.js @@ -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; diff --git a/src/physics/arcade/inc/tilemap/ProcessTileCallbacks.js b/src/physics/arcade/inc/tilemap/ProcessTileCallbacks.js new file mode 100644 index 000000000..7bd983bfa --- /dev/null +++ b/src/physics/arcade/inc/tilemap/ProcessTileCallbacks.js @@ -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; diff --git a/src/physics/arcade/inc/tilemap/ProcessTileSeparationX.js b/src/physics/arcade/inc/tilemap/ProcessTileSeparationX.js new file mode 100644 index 000000000..b7fc4a6c9 --- /dev/null +++ b/src/physics/arcade/inc/tilemap/ProcessTileSeparationX.js @@ -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; diff --git a/src/physics/arcade/inc/tilemap/ProcessTileSeparationY.js b/src/physics/arcade/inc/tilemap/ProcessTileSeparationY.js new file mode 100644 index 000000000..05777c2b0 --- /dev/null +++ b/src/physics/arcade/inc/tilemap/ProcessTileSeparationY.js @@ -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; diff --git a/src/physics/arcade/inc/tilemap/SeparateTile.js b/src/physics/arcade/inc/tilemap/SeparateTile.js new file mode 100644 index 000000000..2ea374933 --- /dev/null +++ b/src/physics/arcade/inc/tilemap/SeparateTile.js @@ -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; diff --git a/src/physics/arcade/inc/tilemap/TileCheckX.js b/src/physics/arcade/inc/tilemap/TileCheckX.js new file mode 100644 index 000000000..92258db5e --- /dev/null +++ b/src/physics/arcade/inc/tilemap/TileCheckX.js @@ -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; diff --git a/src/physics/arcade/inc/tilemap/TileCheckY.js b/src/physics/arcade/inc/tilemap/TileCheckY.js new file mode 100644 index 000000000..282a20aca --- /dev/null +++ b/src/physics/arcade/inc/tilemap/TileCheckY.js @@ -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; diff --git a/src/physics/arcade/inc/tilemap/TileIntersectsBody.js b/src/physics/arcade/inc/tilemap/TileIntersectsBody.js new file mode 100644 index 000000000..9c3cdda7c --- /dev/null +++ b/src/physics/arcade/inc/tilemap/TileIntersectsBody.js @@ -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; diff --git a/src/scene/local/InjectionMap.js b/src/scene/local/InjectionMap.js index fb5bbece2..4cee37874 100644 --- a/src/scene/local/InjectionMap.js +++ b/src/scene/local/InjectionMap.js @@ -9,6 +9,7 @@ var InjectionMap = { anims: 'anims', cache: 'cache', registry: 'registry', + sound: 'sound', textures: 'textures', add: 'add', diff --git a/src/scene/local/Systems.js b/src/scene/local/Systems.js index d40596bf7..a7e687217 100644 --- a/src/scene/local/Systems.js +++ b/src/scene/local/Systems.js @@ -29,8 +29,6 @@ var Systems = new Class({ this.config = config; this.settings = Settings.create(config); - 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) @@ -74,6 +73,7 @@ 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); @@ -157,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 diff --git a/src/scene/plugins/DisplayList.js b/src/scene/plugins/DisplayList.js index aa387cc23..b06264d13 100644 --- a/src/scene/plugins/DisplayList.js +++ b/src/scene/plugins/DisplayList.js @@ -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?