diff --git a/.gitignore b/.gitignore index bec8828..5bd981c 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,4 @@ ehthumbs.db Thumbs.db -node_modules/ -package.json -Gruntfile.js \ No newline at end of file +node_modules/ \ No newline at end of file diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..e905c35 --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,104 @@ +module.exports = function(grunt) { + + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + clean: ['doc'], + concat: { + options: { + separator: ';' + }, + dist: { + src: ['src/Isometric.js', 'src/**/*.js'], + dest: 'dist/<%= pkg.name %>.js' + } + }, + jshint: { + src: ['src/**/*.js'], + options: { + "globals" : { "Phaser": false, "PIXI": false, "p2": false }, + // Ignore Environment Globals + "browser" : true, // Standard browser globals e.g. `window`, `document`. + + // Development + "devel" : true, // Allow developments statements e.g. `console.log();`. + + // ECMAScript Support + "es3" : true, // Support legacy browser and javascript environments. + "esnext" : false, // This option tells JSHint that your code uses ECMAScript 6 specific syntax. + "strict" : false, // Require `use strict` pragma in every file. + "globalstrict": false, // Allow global "use strict" (also enables 'strict'). + + // Functionality + "bitwise" : false, // Prohibit bitwise operators (&, |, ^, etc.). + "boss" : true, // Tolerate assignments inside if, for & while. Usually conditions & loops are for comparison, not assignments. + "camelcase" : true, // Force all variable names to use either camelCase style or UPPER_CASE with underscores. + "curly" : true, // Require {} for every new block or scope. + "eqeqeq" : false, // Require triple equals i.e. `===`. + "eqnull" : true, // Tolerate use of `== null`. + "evil" : false, // Tolerate use of `eval`. + "expr" : false, // Tolerate `ExpressionStatement` as Programs. + "forin" : false, // Tolerate `for in` loops without `hasOwnPrototype`. + "freeze" : true, // Prohibits overwriting prototypes of native objects such as Array and Date. + "funcscope" : true, // This option suppresses warnings about declaring variables inside of control structures while accessing them later from the outside. + "immed" : true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );` + "latedef" : true, // Prohibit variable use before definition. + "laxbreak" : false, // Tolerate unsafe line breaks e.g. `return [\n] x` without semicolons. + "laxcomma" : false, // This option suppresses warnings about comma-first coding style. + "loopfunc" : true, // Allow functions to be defined within loops. + "noarg" : true, // Prohibit use of `arguments.caller` and `arguments.callee`. + "notypeof" : false, // This option suppresses warnings about invalid typeof operator values. + "shadow" : true, // Allows re-define variables later in code e.g. `var x=1; x=2;`. + "smarttabs" : false, // This option suppresses warnings about mixed tabs and spaces when the latter are used for alignmnent only. + "supernew" : false, // Tolerate `new function () { ... };` and `new Object;`. + "undef" : true, // Require all non-global variables be declared before they are used. + "unused" : true, // This option warns when you define and never use your variables. + + // Styling + "indent" : 4, // Specify indentation spacing + "newcap" : true, // Require capitalization of all constructor functions e.g. `new F()`. + "noempty" : true, // Prohibit use of empty blocks. + "nonew" : true, // Prohibit use of constructors for side-effects. + "plusplus" : false, // Prohibit use of `++` & `--`. + "quotmark" : false, // This option enforces the consistency of quotation marks used throughout your code. + "sub" : true, // Tolerate all forms of subscript notation besides dot notation e.g. `dict['key']` instead of `dict.key`. + "trailing" : true // Prohibit trailing whitespaces. + } + }, + uglify: { + options: { + banner: '/* Phaser Isometric <%= pkg.version %> - <%= grunt.template.today("dd-mm-yyyy") %> by Lewis Lane */\n' + }, + dist: { + files: { + 'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>'] + } + } + }, + watch: { + scripts: { + files: ['src/**/*.js'], + tasks: ['default'] + } + }, + jsdoc : { + docstrap : { + src: ['src/**/*.js'], + options: { + destination: 'doc', + template : "node_modules/ink-docstrap/template", + configure : "node_modules/ink-docstrap/template/jsdoc.conf.json", + private: false + } + } + } + }); + + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-contrib-concat'); + grunt.loadNpmTasks('grunt-contrib-clean'); + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-jsdoc'); + + grunt.registerTask('default', ['concat', 'jshint', 'uglify', 'jsdoc:docstrap']); +}; \ No newline at end of file diff --git a/dist/phaser-plugin-isometric.js b/dist/phaser-plugin-isometric.js index 793af49..3fca08c 100644 --- a/dist/phaser-plugin-isometric.js +++ b/dist/phaser-plugin-isometric.js @@ -32,13 +32,14 @@ */ /** + * @class Phaser.Plugin.Isometric + * + * @classdesc * Isometric is a comprehensive axonometric plugin for Phaser which provides an API for handling axonometric projection of assets in 3D space to the screen. * The goal has been to mimic as closely as possible the existing APIs provided by Phaser for standard orthogonal 2D projection, but add a third dimension. * Also included is an Arcade-based 3D AABB physics engine, which again is closely equivalent in functionality and its API. - * - * @class Phaser.Plugin.Isometric + * * @constructor - * * @param {Phaser.Game} game The current game instance. */ Phaser.Plugin.Isometric = function (game, parent) { @@ -52,7 +53,7 @@ Phaser.Plugin.Isometric = function (game, parent) { Phaser.Plugin.Isometric.prototype = Object.create(Phaser.Plugin.prototype); Phaser.Plugin.Isometric.prototype.constructor = Phaser.Plugin.Isometric; -Phaser.Plugin.Isometric.VERSION = '0.7.2'; +Phaser.Plugin.Isometric.VERSION = '0.7.3'; // Directional consts Phaser.Plugin.Isometric.UP = 0; @@ -70,9 +71,11 @@ Phaser.Plugin.Isometric.ISOARCADE = 'isoarcade'; Phaser.Plugin.Isometric.CLASSIC = 0.5; Phaser.Plugin.Isometric.TRUE = 0.6154797093263624; ;/** - * Creates a new Cube object with the bottom-back corner specified by the x, y and z parameters, with the specified breadth (widthX), depth (widthY) and height parameters. If you call this function without parameters, a Cube with x, y, z, breadth, depth and height properties set to 0 is created. - * * @class Phaser.Plugin.Isometric.Cube + * + * @classdesc + * Creates a new Cube object with the bottom-back corner specified by the x, y and z parameters, with the specified breadth (widthX), depth (widthY) and height parameters. If you call this function without parameters, a Cube with x, y, z, breadth, depth and height properties set to 0 is created. + * * @constructor * @param {number} x - The x coordinate of the bottom-back corner of the Cube. * @param {number} y - The y coordinate of the bottom-back corner of the Cube. @@ -658,13 +661,26 @@ Phaser.Plugin.Isometric.Cube.intersects = function (a, b) { return !(a.frontX < b.x || a.frontY < b.y || a.x > b.frontX || a.y > b.frontY || a.z > b.top || a.top < b.z); }; ;/** - * Phaser IsoSprite constructor - * @class Phaser.Plugin.Isometric.IsoSprite - * @constructor +* @class Phaser.Plugin.Isometric.IsoSprite +* +* @classdesc +* Create a new `IsoSprite` object. IsoSprites are extended versions of standard Sprites that are suitable for axonometric positioning. +* +* IsoSprites are simply Sprites that have three new position properties (isoX, isoY and isoZ) and ask the instance of Phaser.Plugin.Isometric.Projector what their position should be in a 2D scene whenever these properties are changed. +* The IsoSprites retain their 2D position property to prevent any problems and allow you to interact with them as you would a normal Sprite. The upside of this simplicity is that things should behave predictably for those already used to Phaser. +* +* @constructor +* @extends Phaser.Sprite +* @param {Phaser.Game} game - A reference to the currently running game. +* @param {number} x - The x coordinate (in 3D space) to position the IsoSprite at. +* @param {number} y - The y coordinate (in 3D space) to position the IsoSprite at. +* @param {number} z - The z coordinate (in 3D space) to position the IsoSprite at. +* @param {string|Phaser.RenderTexture|Phaser.BitmapData|PIXI.Texture} key - This is the image or texture used by the IsoSprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture. +* @param {string|number} frame - If this IsoSprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index. */ -Phaser.Plugin.Isometric.IsoSprite = function (game, x, y, z, key, frame, parent) { +Phaser.Plugin.Isometric.IsoSprite = function (game, x, y, z, key, frame) { - Phaser.Sprite.call(this, game, x, y, key, frame, parent); + Phaser.Sprite.call(this, game, x, y, key, frame); /** * @property {number} type - The const type of this object. @@ -679,7 +695,7 @@ Phaser.Plugin.Isometric.IsoSprite = function (game, x, y, z, key, frame, parent) this._isoPosition = new Phaser.Plugin.Isometric.Point3(x, y, z); /** - * @property {number} snap - Snap this IsoSprite's position to this value; handy for keeping pixel art snapped to whole pixels. + * @property {number} snap - Snap this IsoSprite's position to the specified value; handy for keeping pixel art snapped to whole pixels. * @default */ this.snap = 0; @@ -687,18 +703,21 @@ Phaser.Plugin.Isometric.IsoSprite = function (game, x, y, z, key, frame, parent) /** * @property {number} _depth - Internal cached depth value. * @readonly + * @private */ this._depth = 0; /** * @property {boolean} _depthChanged - Internal invalidation control for depth management. * @readonly + * @private */ this._depthChanged = true; /** * @property {boolean} _isoPositionChanged - Internal invalidation control for positioning. * @readonly + * @private */ this._isoPositionChanged = true; @@ -742,7 +761,7 @@ Phaser.Plugin.Isometric.IsoSprite.prototype._project = function () { /** * The axonometric position of the IsoSprite on the x axis. Increasing the x coordinate will move the object down and to the right on the screen. * - * @name Phaser.Sprite#isoX + * @name Phaser.Plugin.Isometric.IsoSprite#isoX * @property {number} isoX - The axonometric position of the IsoSprite on the x axis. */ Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoX", { @@ -758,7 +777,7 @@ Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoX", { /** * The axonometric position of the IsoSprite on the y axis. Increasing the y coordinate will move the object down and to the left on the screen. * - * @name Phaser.Sprite#isoY + * @name Phaser.Plugin.Isometric.IsoSprite#isoY * @property {number} isoY - The axonometric position of the IsoSprite on the y axis. */ Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoY", { @@ -774,7 +793,7 @@ Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoY", { /** * The axonometric position of the IsoSprite on the z axis. Increasing the z coordinate will move the object directly upwards on the screen. * - * @name Phaser.Sprite#isoZ + * @name Phaser.Plugin.Isometric.IsoSprite#isoZ * @property {number} isoZ - The axonometric position of the IsoSprite on the z axis. */ Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoZ", { @@ -790,7 +809,7 @@ Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoZ", { /** * A Point3 object representing the axonometric position of the IsoSprite. * - * @name Phaser.Sprite#isoPosition + * @name Phaser.Plugin.Isometric.IsoSprite#isoPosition * @property {Point3} isoPosition - The axonometric position of the IsoSprite on the z axis. * @readonly */ @@ -803,14 +822,14 @@ Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoPosition" /** * The non-unit distance of the IsoSprite from the 'front' of the scene. Used to correctly depth sort a group of IsoSprites. * - * @name Phaser.Sprite#depth + * @name Phaser.Plugin.Isometric.IsoSprite#depth * @property {number} depth - A calculated value used for depth sorting. * @readonly */ Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "depth", { get: function () { if (this._depthChanged === true) { - this._depth = (this._isoPosition.x + this._isoPosition.y) + (this._isoPosition.z * 0.95); + this._depth = (this._isoPosition.x + this._isoPosition.y); this._depthChanged = false; } return this._depth; @@ -856,17 +875,404 @@ Phaser.GameObjectFactory.prototype.isoSprite = function (x, y, z, key, frame, gr return group.add(new Phaser.Plugin.Isometric.IsoSprite(this.game, x, y, z, key, frame)); +}; +;/** + * Octree Constructor + * + * @class Phaser.Plugin.Isometric.Octree + * @classdesc A Octree implementation based on Phaser.QuadTree. + * Original version at https://github.com/timohausmann/quadtree-js/ + * + * @constructor + * @param {number} x - The bottom-back coordinate of the octree. + * @param {number} y - The bottom-back coordinate of the octree. + * @param {number} z - The bottom-back coordinate of the octree. + * @param {number} widthX - The width X (breadth) of the octree. + * @param {number} widthY - The width Y (depth) of the octree. + * @param {number} height - The height (Z) of the octree. + * @param {number} [maxObjects=10] - The maximum number of objects per node. + * @param {number} [maxLevels=4] - The maximum number of levels to iterate to. + * @param {number} [level=0] - Which level is this? + */ +Phaser.Plugin.Isometric.Octree = function (x, y, z, widthX, widthY, height, maxObjects, maxLevels, level) { + + /** + * @property {number} maxObjects - The maximum number of objects per node. + * @default + */ + this.maxObjects = 10; + + /** + * @property {number} maxLevels - The maximum number of levels to break down to. + * @default + */ + this.maxLevels = 4; + + /** + * @property {number} level - The current level. + */ + this.level = 0; + + /** + * @property {object} bounds - Object that contains the octree bounds. + */ + this.bounds = {}; + + /** + * @property {array} objects - Array of octree children. + */ + this.objects = []; + + /** + * @property {array} nodes - Array of associated child nodes. + */ + this.nodes = []; + + /** + * @property {array} _empty - Internal empty array. + * @private + */ + this._empty = []; + + this.reset(x, y, z, widthX, widthY, height, maxObjects, maxLevels, level); + +}; + +Phaser.Plugin.Isometric.Octree.prototype = { + + /** + * Resets the QuadTree. + * + * @method Phaser.Plugin.Isometric.Octree#reset + * @param {number} x - The bottom-back coordinate of the octree. + * @param {number} y - The bottom-back coordinate of the octree. + * @param {number} z - The bottom-back coordinate of the octree. + * @param {number} widthX - The width X (breadth) of the octree. + * @param {number} widthY - The width Y (depth) of the octree. + * @param {number} height - The height (Z) of the octree. + * @param {number} [maxObjects=10] - The maximum number of objects per node. + * @param {number} [maxLevels=4] - The maximum number of levels to iterate to. + * @param {number} [level=0] - Which level is this? + */ + reset: function (x, y, z, widthX, widthY, height, maxObjects, maxLevels, level) { + + this.maxObjects = maxObjects || 10; + this.maxLevels = maxLevels || 4; + this.level = level || 0; + + this.bounds = { + x: Math.round(x), + y: Math.round(y), + z: Math.round(z), + widthX: widthX, + widthY: widthY, + height: height, + subWidthX: Math.floor(widthX * 0.5), + subWidthY: Math.floor(widthY * 0.5), + subHeight: Math.floor(height * 0.5), + frontX: Math.round(x) + Math.floor(widthX * 0.5), + frontY: Math.round(y) + Math.floor(widthY * 0.5), + top: Math.round(z) + Math.floor(height * 0.5) + }; + + this.objects.length = 0; + this.nodes.length = 0; + + }, + + /** + * Populates this octree with the children of the given Group. In order to be added the child must exist and have a body property. + * + * @method Phaser.Plugin.Isometric.Octree#populate + * @param {Phaser.Group} group - The Group to add to the octree. + */ + populate: function (group) { + + group.forEach(this.populateHandler, this, true); + + }, + + /** + * Handler for the populate method. + * + * @method Phaser.Plugin.Isometric.Octree#populateHandler + * @param {Phaser.Plugin.Isometric.IsoSprite|object} sprite - The Sprite to check. + */ + populateHandler: function (sprite) { + + if (sprite.body && sprite.exists) { + this.insert(sprite.body); + } + + }, + + /** + * Split the node into 8 subnodes + * + * @method Phaser.Plugin.Isometric.Octree#split + */ + split: function () { + + // bottom four octants + // -x-y-z + this.nodes[0] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.y, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); + // +x-y-z + this.nodes[1] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.y, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); + // -x+y-z + this.nodes[2] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.frontY, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); + // +x+y-z + this.nodes[3] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.frontY, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); + + // top four octants + // -x-y+z + this.nodes[4] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.y, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); + // +x-y+z + this.nodes[5] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.y, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); + // -x+y+z + this.nodes[6] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.frontY, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); + // +x+y+z + this.nodes[7] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.frontY, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); + }, + + /** + * Insert the object into the node. If the node exceeds the capacity, it will split and add all objects to their corresponding subnodes. + * + * @method Phaser.Plugin.Isometric.Octree#insert + * @param {Phaser.Plugin.Isometric.Body|Phaser.Plugin.Isometric.Cube|object} body - The Body object to insert into the octree. Can be any object so long as it exposes x, y, z, frontX, frontY and top properties. + */ + insert: function (body) { + + var i = 0; + var index; + + // if we have subnodes ... + if (this.nodes[0] !== null) { + index = this.getIndex(body); + + if (index !== -1) { + this.nodes[index].insert(body); + return; + } + } + + this.objects.push(body); + + if (this.objects.length > this.maxObjects && this.level < this.maxLevels) { + // Split if we don't already have subnodes + if (this.nodes[0] === null) { + this.split(); + } + + // Add objects to subnodes + while (i < this.objects.length) { + index = this.getIndex(this.objects[i]); + + if (index !== -1) { + // this is expensive - see what we can do about it + this.nodes[index].insert(this.objects.splice(i, 1)[0]); + } else { + i++; + } + } + } + + }, + + /** + * Determine which node the object belongs to. + * + * @method Phaser.Plugin.Isometric.Octree#getIndex + * @param {Phaser.Plugin.Isometric.Cube|object} cube - The bounds in which to check. + * @return {number} index - Index of the subnode (0-7), or -1 if cube cannot completely fit within a subnode and is part of the parent node. + */ + getIndex: function (cube) { + + // default is that cube doesn't fit, i.e. it straddles the internal octants + var index = -1; + + if (cube.x < this.bounds.frontX && cube.frontX < this.bounds.frontX) { + if (cube.y < this.bounds.frontY && cube.frontY < this.bounds.frontY) { + if (cube.z < this.bounds.top && cube.top < this.bounds.top) { + // cube fits into -x-y-z octant + index = 0; + } else if (cube.z > this.bounds.top) { + // cube fits into -x-y+z octant + index = 4; + } + } else if (cube.y > this.bounds.frontY) { + if (cube.z < this.bounds.top && cube.top < this.bounds.top) { + // cube fits into -x+y-z octant + index = 2; + } else if (cube.z > this.bounds.top) { + // cube fits into -x+y+z octant + index = 6; + } + } + } else if (cube.x > this.bounds.frontX) { + if (cube.y < this.bounds.frontY && cube.frontY < this.bounds.frontY) { + if (cube.z < this.bounds.top && cube.top < this.bounds.top) { + // cube fits into +x-y-z octant + index = 1; + } else if (cube.z > this.bounds.top) { + // cube fits into +x-y+z octant + index = 5; + } + } else if (cube.y > this.bounds.frontY) { + if (cube.z < this.bounds.top && cube.top < this.bounds.top) { + // cube fits into +x+y-z octant + index = 3; + } else if (cube.z > this.bounds.top) { + // cube fits into +x+y+z octant + index = 7; + } + } + } + + + return index; + + }, + + /** + * Return all objects that could collide with the given IsoSprite or Cube. + * + * @method Phaser.Plugin.Isometric.Octree#retrieve + * @param {Phaser.Plugin.Isometric.IsoSprite|Phaser.Plugin.Isometric.Cube} source - The source object to check the Octree against. Either a IsoSprite or Cube. + * @return {array} - Array with all detected objects. + */ + retrieve: function (source) { + + var returnObjects, index; + + if (source instanceof Phaser.Plugin.Isometric.Cube) { + returnObjects = this.objects; + + index = this.getIndex(source); + } else { + if (!source.body) { + return this._empty; + } + + returnObjects = this.objects; + + index = this.getIndex(source.body); + } + + if (this.nodes[0]) { + // If cube fits into a subnode .. + if (index !== -1) { + returnObjects = returnObjects.concat(this.nodes[index].retrieve(source)); + } else { + // If cube does not fit into a subnode, check it against all subnodes (unrolled for speed) + returnObjects = returnObjects.concat(this.nodes[0].retrieve(source)); + returnObjects = returnObjects.concat(this.nodes[1].retrieve(source)); + returnObjects = returnObjects.concat(this.nodes[2].retrieve(source)); + returnObjects = returnObjects.concat(this.nodes[3].retrieve(source)); + returnObjects = returnObjects.concat(this.nodes[4].retrieve(source)); + returnObjects = returnObjects.concat(this.nodes[5].retrieve(source)); + returnObjects = returnObjects.concat(this.nodes[6].retrieve(source)); + returnObjects = returnObjects.concat(this.nodes[7].retrieve(source)); + } + } + + return returnObjects; + + }, + + /** + * Clear the octree. + * @method Phaser.Plugin.Isometric.Octree#clear + */ + clear: function () { + + this.objects.length = 0; + + var i = this.nodes.length; + + while (i--) { + this.nodes[i].clear(); + this.nodes.splice(i, 1); + } + + this.nodes.length = 0; + } + +}; + +Phaser.Plugin.Isometric.Octree.prototype.constructor = Phaser.Plugin.Isometric.Octree; + +/** + * Visually renders an Octree to the display. + * + * @method Phaser.Utils.Debug#octree + * @param {Phaser.Plugin.Isometric.Octree} octree - The octree to render. + * @param {string} color - The color of the lines in the quadtree. + */ +Phaser.Utils.Debug.prototype.octree = function (octree, color) { + + color = color || 'rgba(255,0,0,0.3)'; + + this.start(); + + var bounds = octree.bounds, + i, points; + + if (octree.nodes.length === 0) { + + this.context.strokeStyle = color; + + var cube = new Phaser.Plugin.Isometric.Cube(bounds.x, bounds.y, bounds.z, bounds.widthX, bounds.widthY, bounds.height); + var corners = cube.getCorners(); + + points = corners.slice(0, corners.length); + points = points.map(function (p) { + return this.game.iso.project(p); + }); + + this.context.moveTo(points[0].x, points[0].y); + this.context.beginPath(); + this.context.strokeStyle = color; + + this.context.lineTo(points[1].x, points[1].y); + this.context.lineTo(points[3].x, points[3].y); + this.context.lineTo(points[2].x, points[2].y); + this.context.lineTo(points[6].x, points[6].y); + this.context.lineTo(points[4].x, points[4].y); + this.context.lineTo(points[5].x, points[5].y); + this.context.lineTo(points[1].x, points[1].y); + this.context.lineTo(points[0].x, points[0].y); + this.context.lineTo(points[4].x, points[4].y); + this.context.moveTo(points[0].x, points[0].y); + this.context.lineTo(points[2].x, points[2].y); + this.context.moveTo(points[3].x, points[3].y); + this.context.lineTo(points[7].x, points[7].y); + this.context.lineTo(points[6].x, points[6].y); + this.context.moveTo(points[7].x, points[7].y); + this.context.lineTo(points[5].x, points[5].y); + this.context.stroke(); + this.context.closePath(); + + for (i = 0; i < octree.objects.length; i++) { + this.body(octree.objects[i].sprite, 'rgb(0,255,0)', false); + } + } else { + for (i = 0; i < octree.nodes.length; i++) { + this.octree(octree.nodes[i]); + } + } + + this.stop(); + }; ;/** * @class Phaser.Plugin.Isometric.Point3 + * * @classdesc * The Point3 object represents a location in a three-dimensional coordinate system, * where x and y represent the horizontal axes and z represents the vertical axis. * The following code creates a point at (0,0,0): * `var myPoint = new Phaser.Plugin.Isometric.Point3();` - */ - -/** + * * Creates a new Point3 object. If you pass no parameters a Point3 is created set to (0, 0, 0). * * @constructor @@ -1158,9 +1564,11 @@ Phaser.Plugin.Isometric.Point3.equals = function (a, b) { }; ;/** - * Creates a new Isometric Projector object, which has helpers for projecting x, y and z coordinates into axonometric x and y equivalents. - * * @class Phaser.Plugin.Isometric.Projector + * + * @classdesc + * Creates a new Isometric Projector object, which has helpers for projecting x, y and z coordinates into axonometric x and y equivalents. + * * @constructor * @param {Phaser.Game} game - The current game object. * @param {number} projectionRatio - The ratio of the axonometric projection. @@ -1234,11 +1642,12 @@ Phaser.Plugin.Isometric.Projector.prototype = { }; ;/** + * @class Phaser.Plugin.Isometric.Body + * + * @classdesc * The Physics Body is linked to a single IsoSprite. All physics operations should be performed against the body rather than * the IsoSprite itself. For example you can set the velocity, acceleration, bounce values etc all on the Body. - * - * @class Phaser.Plugin.Isometric.Body - * @classdesc IsoArcade Physics Body Constructor + * * @constructor * @param {Phaser.Plugin.Isometric.IsoSprite} sprite - The IsoSprite object this physics body belongs to. */ @@ -1947,7 +2356,7 @@ Phaser.Plugin.Isometric.Body.prototype = { this.position.x = x + ((this.widthX * -this.sprite.anchor.x) + this.widthX * 0.5) + this.offset.x; this.position.y = y + ((this.widthY * this.sprite.anchor.x) - this.widthY * 0.5) + this.offset.y; - this.position.z = z - ((this.height * -this.sprite.anchor.y * 2) + this.height) + this.offset.z; + this.position.z = z - (Math.abs(this.sprite.height) * (1 - this.sprite.anchor.y)) + (Math.abs(this.sprite.width * 0.5)) + this.offset.z; this.prev.x = this.position.x; this.prev.y = this.position.y; @@ -1961,6 +2370,8 @@ Phaser.Plugin.Isometric.Body.prototype = { this.center.setTo(this.position.x + this.halfWidthX, this.position.y + this.halfWidthY, this.position.z + this.halfHeight); + this.sprite._isoPositionChanged = true; + }, /** @@ -2325,395 +2736,6 @@ Phaser.Plugin.Isometric.Body.renderBodyInfo = function (debug, body) { Phaser.Plugin.Isometric.Body.prototype.constructor = Phaser.Plugin.Isometric.Body; -/** - * Octree Constructor - * - * @class Phaser.Plugin.Isometric.Octree - * @classdesc A Octree implementation. The original code was a conversion of the Java code posted to GameDevTuts. - * However I've tweaked it massively to add node indexing, removed lots of temp. var creation and significantly increased performance as a result. - * Original version at https://github.com/timohausmann/quadtree-js/ - * @constructor - * @param {number} x - The bottom-back coordinate of the octree. - * @param {number} y - The bottom-back coordinate of the octree. - * @param {number} z - The bottom-back coordinate of the octree. - * @param {number} widthX - The width X (breadth) of the octree. - * @param {number} widthY - The width Y (depth) of the octree. - * @param {number} height - The height (Z) of the octree. - * @param {number} [maxObjects=10] - The maximum number of objects per node. - * @param {number} [maxLevels=4] - The maximum number of levels to iterate to. - * @param {number} [level=0] - Which level is this? - */ -Phaser.Plugin.Isometric.Octree = function (x, y, z, widthX, widthY, height, maxObjects, maxLevels, level) { - - /** - * @property {number} maxObjects - The maximum number of objects per node. - * @default - */ - this.maxObjects = 10; - - /** - * @property {number} maxLevels - The maximum number of levels to break down to. - * @default - */ - this.maxLevels = 4; - - /** - * @property {number} level - The current level. - */ - this.level = 0; - - /** - * @property {object} bounds - Object that contains the octree bounds. - */ - this.bounds = {}; - - /** - * @property {array} objects - Array of octree children. - */ - this.objects = []; - - /** - * @property {array} nodes - Array of associated child nodes. - */ - this.nodes = []; - - /** - * @property {array} _empty - Internal empty array. - * @private - */ - this._empty = []; - - this.reset(x, y, z, widthX, widthY, height, maxObjects, maxLevels, level); - -}; - -Phaser.Plugin.Isometric.Octree.prototype = { - - /** - * Resets the QuadTree. - * - * @method Phaser.Plugin.Isometric.Octree#reset - * @param {number} x - The bottom-back coordinate of the octree. - * @param {number} y - The bottom-back coordinate of the octree. - * @param {number} z - The bottom-back coordinate of the octree. - * @param {number} widthX - The width X (breadth) of the octree. - * @param {number} widthY - The width Y (depth) of the octree. - * @param {number} height - The height (Z) of the octree. - * @param {number} [maxObjects=10] - The maximum number of objects per node. - * @param {number} [maxLevels=4] - The maximum number of levels to iterate to. - * @param {number} [level=0] - Which level is this? - */ - reset: function (x, y, z, widthX, widthY, height, maxObjects, maxLevels, level) { - - this.maxObjects = maxObjects || 10; - this.maxLevels = maxLevels || 4; - this.level = level || 0; - - this.bounds = { - x: Math.round(x), - y: Math.round(y), - z: Math.round(z), - widthX: widthX, - widthY: widthY, - height: height, - subWidthX: Math.floor(widthX * 0.5), - subWidthY: Math.floor(widthY * 0.5), - subHeight: Math.floor(height * 0.5), - frontX: Math.round(x) + Math.floor(widthX * 0.5), - frontY: Math.round(y) + Math.floor(widthY * 0.5), - top: Math.round(z) + Math.floor(height * 0.5) - }; - - this.objects.length = 0; - this.nodes.length = 0; - - }, - - /** - * Populates this octree with the children of the given Group. In order to be added the child must exist and have a body property. - * - * @method Phaser.Plugin.Isometric.Octree#populate - * @param {Phaser.Group} group - The Group to add to the octree. - */ - populate: function (group) { - - group.forEach(this.populateHandler, this, true); - - }, - - /** - * Handler for the populate method. - * - * @method Phaser.Plugin.Isometric.Octree#populateHandler - * @param {Phaser.Plugin.Isometric.IsoSprite|object} sprite - The Sprite to check. - */ - populateHandler: function (sprite) { - - if (sprite.body && sprite.exists) { - this.insert(sprite.body); - } - - }, - - /** - * Split the node into 8 subnodes - * - * @method Phaser.Plugin.Isometric.Octree#split - */ - split: function () { - - // bottom four octants - // -x-y-z - this.nodes[0] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.y, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); - // +x-y-z - this.nodes[1] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.y, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); - // -x+y-z - this.nodes[2] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.frontY, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); - // +x+y-z - this.nodes[3] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.frontY, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); - - // top four octants - // -x-y+z - this.nodes[4] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.y, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); - // +x-y+z - this.nodes[5] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.y, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); - // -x+y+z - this.nodes[6] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.frontY, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); - // +x+y+z - this.nodes[7] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.frontY, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); - }, - - /** - * Insert the object into the node. If the node exceeds the capacity, it will split and add all objects to their corresponding subnodes. - * - * @method Phaser.Plugin.Isometric.Octree#insert - * @param {Phaser.Plugin.Isometric.Body|Phaser.Plugin.Isometric.Cube|object} body - The Body object to insert into the octree. Can be any object so long as it exposes x, y, z, frontX, frontY and top properties. - */ - insert: function (body) { - - var i = 0; - var index; - - // if we have subnodes ... - if (this.nodes[0] !== null) { - index = this.getIndex(body); - - if (index !== -1) { - this.nodes[index].insert(body); - return; - } - } - - this.objects.push(body); - - if (this.objects.length > this.maxObjects && this.level < this.maxLevels) { - // Split if we don't already have subnodes - if (this.nodes[0] === null) { - this.split(); - } - - // Add objects to subnodes - while (i < this.objects.length) { - index = this.getIndex(this.objects[i]); - - if (index !== -1) { - // this is expensive - see what we can do about it - this.nodes[index].insert(this.objects.splice(i, 1)[0]); - } else { - i++; - } - } - } - - }, - - /** - * Determine which node the object belongs to. - * - * @method Phaser.Plugin.Isometric.Octree#getIndex - * @param {Phaser.Plugin.Isometric.Cube|object} cube - The bounds in which to check. - * @return {number} index - Index of the subnode (0-7), or -1 if cube cannot completely fit within a subnode and is part of the parent node. - */ - getIndex: function (cube) { - - // default is that cube doesn't fit, i.e. it straddles the internal octants - var index = -1; - - if (cube.x < this.bounds.frontX && cube.frontX < this.bounds.frontX) { - if (cube.y < this.bounds.frontY && cube.frontY < this.bounds.frontY) { - if (cube.z < this.bounds.top && cube.top < this.bounds.top) { - // cube fits into -x-y-z octant - index = 0; - } else if (cube.z > this.bounds.top) { - // cube fits into -x-y+z octant - index = 4; - } - } else if (cube.y > this.bounds.frontY) { - if (cube.z < this.bounds.top && cube.top < this.bounds.top) { - // cube fits into -x+y-z octant - index = 2; - } else if (cube.z > this.bounds.top) { - // cube fits into -x+y+z octant - index = 6; - } - } - } else if (cube.x > this.bounds.frontX) { - if (cube.y < this.bounds.frontY && cube.frontY < this.bounds.frontY) { - if (cube.z < this.bounds.top && cube.top < this.bounds.top) { - // cube fits into +x-y-z octant - index = 1; - } else if (cube.z > this.bounds.top) { - // cube fits into +x-y+z octant - index = 5; - } - } else if (cube.y > this.bounds.frontY) { - if (cube.z < this.bounds.top && cube.top < this.bounds.top) { - // cube fits into +x+y-z octant - index = 3; - } else if (cube.z > this.bounds.top) { - // cube fits into +x+y+z octant - index = 7; - } - } - } - - - return index; - - }, - - /** - * Return all objects that could collide with the given IsoSprite or Cube. - * - * @method Phaser.Plugin.Isometric.Octree#retrieve - * @param {Phaser.Plugin.Isometric.IsoSprite|Phaser.Plugin.Isometric.Cube} source - The source object to check the Octree against. Either a IsoSprite or Cube. - * @return {array} - Array with all detected objects. - */ - retrieve: function (source) { - - var returnObjects, index; - - if (source instanceof Phaser.Plugin.Isometric.Cube) { - returnObjects = this.objects; - - index = this.getIndex(source); - } else { - if (!source.body) { - return this._empty; - } - - returnObjects = this.objects; - - index = this.getIndex(source.body); - } - - if (this.nodes[0]) { - // If cube fits into a subnode .. - if (index !== -1) { - returnObjects = returnObjects.concat(this.nodes[index].retrieve(source)); - } else { - // If cube does not fit into a subnode, check it against all subnodes (unrolled for speed) - returnObjects = returnObjects.concat(this.nodes[0].retrieve(source)); - returnObjects = returnObjects.concat(this.nodes[1].retrieve(source)); - returnObjects = returnObjects.concat(this.nodes[2].retrieve(source)); - returnObjects = returnObjects.concat(this.nodes[3].retrieve(source)); - returnObjects = returnObjects.concat(this.nodes[4].retrieve(source)); - returnObjects = returnObjects.concat(this.nodes[5].retrieve(source)); - returnObjects = returnObjects.concat(this.nodes[6].retrieve(source)); - returnObjects = returnObjects.concat(this.nodes[7].retrieve(source)); - } - } - - return returnObjects; - - }, - - /** - * Clear the octree. - * @method Phaser.Plugin.Isometric.Octree#clear - */ - clear: function () { - - this.objects.length = 0; - - var i = this.nodes.length; - - while (i--) { - this.nodes[i].clear(); - this.nodes.splice(i, 1); - } - - this.nodes.length = 0; - } - -}; - -Phaser.Plugin.Isometric.Octree.prototype.constructor = Phaser.Plugin.Isometric.Octree; - -/** - * Visually renders an Octree to the display. - * - * @method Phaser.Utils.Debug#octree - * @param {Phaser.Plugin.Isometric.Octree} octree - The octree to render. - * @param {string} color - The color of the lines in the quadtree. - */ -Phaser.Utils.Debug.prototype.octree = function (octree, color) { - - color = color || 'rgba(255,0,0,0.3)'; - - this.start(); - - var bounds = octree.bounds, - i, points; - - if (octree.nodes.length === 0) { - - this.context.strokeStyle = color; - - var cube = new Phaser.Plugin.Isometric.Cube(bounds.x, bounds.y, bounds.z, bounds.widthX, bounds.widthY, bounds.height); - var corners = cube.getCorners(); - - points = corners.slice(0, corners.length); - points = points.map(function (p) { - return this.game.iso.project(p); - }); - - this.context.moveTo(points[0].x, points[0].y); - this.context.beginPath(); - this.context.strokeStyle = color; - - this.context.lineTo(points[1].x, points[1].y); - this.context.lineTo(points[3].x, points[3].y); - this.context.lineTo(points[2].x, points[2].y); - this.context.lineTo(points[6].x, points[6].y); - this.context.lineTo(points[4].x, points[4].y); - this.context.lineTo(points[5].x, points[5].y); - this.context.lineTo(points[1].x, points[1].y); - this.context.lineTo(points[0].x, points[0].y); - this.context.lineTo(points[4].x, points[4].y); - this.context.moveTo(points[0].x, points[0].y); - this.context.lineTo(points[2].x, points[2].y); - this.context.moveTo(points[3].x, points[3].y); - this.context.lineTo(points[7].x, points[7].y); - this.context.lineTo(points[6].x, points[6].y); - this.context.moveTo(points[7].x, points[7].y); - this.context.lineTo(points[5].x, points[5].y); - this.context.stroke(); - this.context.closePath(); - - for (i = 0; i < octree.objects.length; i++) { - this.body(octree.objects[i].sprite, 'rgb(0,255,0)', false); - } - } else { - for (i = 0; i < octree.nodes.length; i++) { - this.octree(octree.nodes[i]); - } - } - - this.stop(); - -}; - Phaser.Utils.Debug.prototype.body = (function (_super) { return function (sprite, color, filled) { diff --git a/dist/phaser-plugin-isometric.min.js b/dist/phaser-plugin-isometric.min.js index 8f596c3..982939c 100644 --- a/dist/phaser-plugin-isometric.min.js +++ b/dist/phaser-plugin-isometric.min.js @@ -1,3 +1,3 @@ -/* Phaser Isometric 0.7.2 - 06-08-2014 by Lewis Lane */ -Phaser.Plugin.Isometric=function(a,b){Phaser.Plugin.call(this,a,b),this.game.iso=this.game.iso||new Phaser.Plugin.Isometric.Projector(this.game,Phaser.Plugin.Isometric.CLASSIC)},Phaser.Plugin.Isometric.prototype=Object.create(Phaser.Plugin.prototype),Phaser.Plugin.Isometric.prototype.constructor=Phaser.Plugin.Isometric,Phaser.Plugin.Isometric.VERSION="0.7.2",Phaser.Plugin.Isometric.UP=0,Phaser.Plugin.Isometric.DOWN=1,Phaser.Plugin.Isometric.FORWARDX=2,Phaser.Plugin.Isometric.FORWARDY=3,Phaser.Plugin.Isometric.BACKWARDX=4,Phaser.Plugin.Isometric.BACKWARDY=5,Phaser.Plugin.Isometric.ISOSPRITE="isosprite",Phaser.Plugin.Isometric.ISOARCADE="isoarcade",Phaser.Plugin.Isometric.CLASSIC=.5,Phaser.Plugin.Isometric.TRUE=.6154797093263624,Phaser.Plugin.Isometric.Cube=function(a,b,c,d,e,f){a=a||0,b=b||0,c=c||0,d=d||0,e=e||0,f=f||0,this.x=a,this.y=b,this.z=c,this.widthX=d,this.widthY=e,this.height=f,this._corners=[new Phaser.Plugin.Isometric.Point3(this.x,this.y,this.z),new Phaser.Plugin.Isometric.Point3(this.x,this.y,this.z+this.height),new Phaser.Plugin.Isometric.Point3(this.x,this.y+this.widthY,this.z),new Phaser.Plugin.Isometric.Point3(this.x,this.y+this.widthY,this.z+this.height),new Phaser.Plugin.Isometric.Point3(this.x+this.widthX,this.y,this.z),new Phaser.Plugin.Isometric.Point3(this.x+this.widthX,this.y,this.z+this.height),new Phaser.Plugin.Isometric.Point3(this.x+this.widthX,this.y+this.widthY,this.z),new Phaser.Plugin.Isometric.Point3(this.x+this.widthX,this.y+this.widthY,this.z+this.height)]},Phaser.Plugin.Isometric.Cube.prototype.constructor=Phaser.Plugin.Isometric.Cube,Phaser.Plugin.Isometric.Cube.prototype={setTo:function(a,b,c,d,e,f){return this.x=a,this.y=b,this.z=c,this.widthX=d,this.widthY=e,this.height=f,this},copyFrom:function(a){this.setTo(a.x,a.y,a.z,a.widthX,a.widthY,a.height)},copyTo:function(a){return a.x=this.x,a.y=this.y,a.z=this.z,a.widthX=this.widthX,a.widthY=this.widthY,a.height=this.height,a},size:function(a){return Phaser.Plugin.Isometric.Cube.size(this,a)},clone:function(a){return Phaser.Plugin.Isometric.Cube.clone(this,a)},intersects:function(a){return Phaser.Plugin.Isometric.Cube.intersects(this,a)},getCorners:function(){return this._corners[0].setTo(this.x,this.y,this.z),this._corners[1].setTo(this.x,this.y,this.z+this.height),this._corners[2].setTo(this.x,this.y+this.widthY,this.z),this._corners[3].setTo(this.x,this.y+this.widthY,this.z+this.height),this._corners[4].setTo(this.x+this.widthX,this.y,this.z),this._corners[5].setTo(this.x+this.widthX,this.y,this.z+this.height),this._corners[6].setTo(this.x+this.widthX,this.y+this.widthY,this.z),this._corners[7].setTo(this.x+this.widthX,this.y+this.widthY,this.z+this.height),this._corners},toString:function(){return"[{Cube (x="+this.x+" y="+this.y+" z="+this.z+" widthX="+this.widthX+" widthY="+this.widthY+" height="+this.height+" empty="+this.empty+")}]"}},Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"halfWidthX",{get:function(){return Math.round(.5*this.widthX)}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"halfWidthY",{get:function(){return Math.round(.5*this.widthY)}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"halfHeight",{get:function(){return Math.round(.5*this.height)}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"bottom",{get:function(){return this.z},set:function(a){this.height=a>=this.top?0:this.top-a,this.z=a}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"top",{get:function(){return this.z+this.height},set:function(a){this.height=a<=this.z?0:a-this.z}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"backX",{get:function(){return this.x},set:function(a){this.widthX=a>=this.frontX?0:this.frontX-a,this.x=a}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"backY",{get:function(){return this.y},set:function(a){this.widthY=a>=this.frontY?0:this.frontY-a,this.y=a}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"frontX",{get:function(){return this.x+this.widthX},set:function(a){this.widthX=a<=this.x?0:a-this.x}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"frontY",{get:function(){return this.y+this.widthY},set:function(a){this.widthY=a<=this.y?0:a-this.y}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"volume",{get:function(){return this.widthX*this.widthY*this.height}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"centerX",{get:function(){return this.x+this.halfWidthX},set:function(a){this.x=a-this.halfWidthX}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"centerY",{get:function(){return this.y+this.halfWidthY},set:function(a){this.y=a-this.halfWidthY}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"centerZ",{get:function(){return this.z+this.halfHeight},set:function(a){this.z=a-this.halfHeight}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"randomX",{get:function(){return this.x+Math.random()*this.widthX}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"randomY",{get:function(){return this.y+Math.random()*this.widthY}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"randomZ",{get:function(){return this.z+Math.random()*this.height}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"empty",{get:function(){return!this.widthX||!this.widthY||!this.height},set:function(a){a===!0&&this.setTo(0,0,0,0,0,0)}}),Phaser.Plugin.Isometric.Cube.size=function(a,b){return"undefined"==typeof b||null===b?b=new Phaser.Plugin.Isometric.Point3(a.widthX,a.widthY,a.height):b.setTo(a.widthX,a.widthY,a.height),b},Phaser.Plugin.Isometric.Cube.clone=function(a,b){return"undefined"==typeof b||null===b?b=new Phaser.Plugin.Isometric.Cube(a.x,a.y,a.z,a.widthX,a.widthY,a.height):b.setTo(a.x,a.y,a.z,a.widthX,a.widthY,a.height),b},Phaser.Plugin.Isometric.Cube.contains=function(a,b,c,d){return a.widthX<=0||a.widthY<=0||a.height<=0?!1:b>=a.x&&b<=a.right&&c>=a.y&&c<=a.back&&d>=a.z&&d<=a.top},Phaser.Plugin.Isometric.Cube.containsPoint3=function(a,b){return Phaser.Plugin.Isometric.Cube.contains(a,b.x,b.y,b.z)},Phaser.Plugin.Isometric.Cube.containsCube=function(a,b){return a.volume>b.volume?!1:a.x>=b.x&&a.y>=b.y&&a.z>=b.z&&a.frontX<=b.frontX&&a.frontY<=b.frontY&&a.top<=b.top},Phaser.Plugin.Isometric.Cube.intersects=function(a,b){return a.widthX<=0||a.widthY<=0||a.height<=0||b.widthX<=0||b.widthY<=0||b.height<=0?!1:!(a.frontXb.frontX||a.y>b.frontY||a.z>b.top||a.top0&&(this.position.x=Phaser.Math.snapTo(this.position.x,this.snap),this.position.y=Phaser.Math.snapTo(this.position.y,this.snap)),this._isoPositionChanged=!1)},Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype,"isoX",{get:function(){return this._isoPosition.x},set:function(a){this._isoPosition.x=a,this._depthChanged=this._isoPositionChanged=!0}}),Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype,"isoY",{get:function(){return this._isoPosition.y},set:function(a){this._isoPosition.y=a,this._depthChanged=this._isoPositionChanged=!0}}),Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype,"isoZ",{get:function(){return this._isoPosition.z},set:function(a){this._isoPosition.z=a,this._depthChanged=this._isoPositionChanged=!0}}),Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype,"isoPosition",{get:function(){return this._isoPosition}}),Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype,"depth",{get:function(){return this._depthChanged===!0&&(this._depth=this._isoPosition.x+this._isoPosition.y+.95*this._isoPosition.z,this._depthChanged=!1),this._depth}}),Phaser.GameObjectCreator.prototype.isoSprite=function(a,b,c,d,e){return new Phaser.Plugin.Isometric.IsoSprite(this.game,a,b,c,d,e)},Phaser.GameObjectFactory.prototype.isoSprite=function(a,b,c,d,e,f){return"undefined"==typeof f&&(f=this.world),f.add(new Phaser.Plugin.Isometric.IsoSprite(this.game,a,b,c,d,e))},Phaser.Plugin.Isometric.Point3=function(a,b,c){a=a||0,b=b||0,c=c||0,this.x=a,this.y=b,this.z=c},Phaser.Plugin.Isometric.Point3.prototype={copyFrom:function(a){return this.setTo(a.x,a.y,a.z)},copyTo:function(a){return a.x=this.x,a.y=this.y,a.z=this.z,a},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z},set:function(a,b,c){return this.x=a||0,this.y=b||(0!==b?this.x:0),this.z=c||("undefined"==typeof b?this.x:0),this},setTo:function(a,b,c){return this.set(a,b,c)},add:function(a,b){return this.x+=a||0,this.y+=b||0,this},subtract:function(a,b,c){return this.x-=a||0,this.y-=b||0,this.z-=c||0,this},multiply:function(a,b,c){return this.x*=a||1,this.y*=b||1,this.z*=c||1,this},divide:function(a,b,c){return this.x/=a||1,this.y/=b||1,this.z/=c||1,this}},Phaser.Plugin.Isometric.Point3.prototype.constructor=Phaser.Plugin.Isometric.Point3,Phaser.Plugin.Isometric.Point3.add=function(a,b,c){return"undefined"==typeof c&&(c=new Phaser.Plugin.Isometric.Point3),c.x=a.x+b.x,c.y=a.y+b.y,c.z=a.z+b.z,c},Phaser.Plugin.Isometric.Point3.subtract=function(a,b,c){return"undefined"==typeof c&&(c=new Phaser.Plugin.Isometric.Point3),c.x=a.x-b.x,c.y=a.y-b.y,c.z=a.z-b.z,c},Phaser.Plugin.Isometric.Point3.multiply=function(a,b,c){return"undefined"==typeof c&&(c=new Phaser.Plugin.Isometric.Point3),c.x=a.x*b.x,c.y=a.y*b.y,c.z=a.z*b.z,c},Phaser.Plugin.Isometric.Point3.divide=function(a,b,c){return"undefined"==typeof c&&(c=new Phaser.Plugin.Isometric.Point3),c.x=a.x/b.x,c.y=a.y/b.y,c.z=a.z/b.z,c},Phaser.Plugin.Isometric.Point3.equals=function(a,b){return a.x===b.x&&a.y===b.y&&a.z===b.z},Phaser.Plugin.Isometric.Projector=function(a,b){this.game=a,this.projectionRatio=b||Phaser.Plugin.Isometric.CLASSIC,this.anchor=new Phaser.Point(.5,0)},Phaser.Plugin.Isometric.Projector.prototype={project:function(a,b){return"undefined"==typeof b&&(b=new Phaser.Point),b.x=a.x-a.y,b.y=(a.x+a.y)*this.projectionRatio-a.z,b.x+=this.game.world.width*this.anchor.x,b.y+=this.game.world.height*this.anchor.y,b},projectXY:function(a,b){return"undefined"==typeof b&&(b=new Phaser.Point),b.x=a.x-a.y,b.y=(a.x+a.y)*this.projectionRatio,b.x+=this.game.world.width*this.anchor.x,b.y+=this.game.world.height*this.anchor.y,b}},Phaser.Plugin.Isometric.Body=function(a){this.sprite=a,this.game=a.game,this.type=Phaser.Plugin.Isometric.ISOARCADE,this.enable=!0,this.offset=new Phaser.Plugin.Isometric.Point3,this.position=new Phaser.Plugin.Isometric.Point3(a.isoX,a.isoY,a.isoZ),this.prev=new Phaser.Plugin.Isometric.Point3(this.position.x,this.position.y,this.position.z),this.allowRotation=!0,this.rotation=a.rotation,this.preRotation=a.rotation,this.sourceWidthX=a.texture.frame.width,this.sourceWidthY=a.texture.frame.width,this.sourceHeight=a.texture.frame.height,this.widthX=.5*a.width,this.widthY=.5*a.width,this.height=a.height-.5*a.width,this.halfWidthX=Math.abs(.5*this.widthX),this.halfWidthY=Math.abs(.5*this.widthY),this.halfHeight=Math.abs(.5*this.height),this.center=new Phaser.Plugin.Isometric.Point3(a.isoX+this.halfWidthX,a.isoY+this.halfWidthY,a.isoZ+this.halfHeight),this.velocity=new Phaser.Plugin.Isometric.Point3,this.newVelocity=new Phaser.Plugin.Isometric.Point3,this.deltaMax=new Phaser.Plugin.Isometric.Point3,this.acceleration=new Phaser.Plugin.Isometric.Point3,this.drag=new Phaser.Plugin.Isometric.Point3,this.allowGravity=!0,this.gravity=new Phaser.Plugin.Isometric.Point3,this.bounce=new Phaser.Plugin.Isometric.Point3,this.maxVelocity=new Phaser.Plugin.Isometric.Point3(1e4,1e4,1e4),this.angularVelocity=0,this.angularAcceleration=0,this.angularDrag=0,this.maxAngular=1e3,this.mass=1,this.angle=0,this.speed=0,this.facing=Phaser.NONE,this.immovable=!1,this.moves=!0,this.customSeparateX=!1,this.customSeparateY=!1,this.customSeparateZ=!1,this.overlapX=0,this.overlapY=0,this.overlapZ=0,this.embedded=!1,this.collideWorldBounds=!1,this.checkCollision={none:!1,any:!0,up:!0,down:!0,frontX:!0,frontY:!0,backX:!0,backY:!0},this.touching={none:!0,up:!1,down:!1,frontX:!1,frontY:!1,backX:!1,backY:!1},this.wasTouching={none:!0,up:!1,down:!1,frontX:!1,frontY:!1,backX:!1,backY:!1},this.blocked={up:!1,down:!1,frontX:!1,frontY:!1,backX:!1,backY:!1},this.phase=0,this.skipTree=!1,this._reset=!0,this._sx=a.scale.x,this._sy=a.scale.y,this._dx=0,this._dy=0,this._dz=0,this._corners=[new Phaser.Plugin.Isometric.Point3(this.x,this.y,this.z),new Phaser.Plugin.Isometric.Point3(this.x,this.y,this.z+this.height),new Phaser.Plugin.Isometric.Point3(this.x,this.y+this.widthY,this.z),new Phaser.Plugin.Isometric.Point3(this.x,this.y+this.widthY,this.z+this.height),new Phaser.Plugin.Isometric.Point3(this.x+this.widthX,this.y,this.z),new Phaser.Plugin.Isometric.Point3(this.x+this.widthX,this.y,this.z+this.height),new Phaser.Plugin.Isometric.Point3(this.x+this.widthX,this.y+this.widthY,this.z),new Phaser.Plugin.Isometric.Point3(this.x+this.widthX,this.y+this.widthY,this.z+this.height)]},Phaser.Plugin.Isometric.Body.prototype={updateBounds:function(){var a=Math.abs(this.sprite.scale.x),b=Math.abs(this.sprite.scale.y);(a!==this._sx||b!==this._sy)&&(this.widthX=.5*this.sprite.width*a,this.widthY=.5*this.sprite.width*a,this.height=(this.sprite.height-.5*this.sprite.width)*b,this.halfWidthX=Math.floor(2*this.widthX),this.halfWidthY=Math.floor(2*this.widthY),this.halfHeight=Math.floor(2*this.height),this._sx=a,this._sy=b,this.center.setTo(this.position.x+this.halfWidthX,this.position.y+this.halfWidthY,this.position.z+this.halfHeight),this._reset=!0)},preUpdate:function(){this.enable&&(this.phase=1,this.wasTouching.none=this.touching.none,this.wasTouching.up=this.touching.up,this.wasTouching.down=this.touching.down,this.wasTouching.backX=this.touching.backX,this.wasTouching.backY=this.touching.backY,this.wasTouching.frontX=this.touching.frontX,this.wasTouching.frontY=this.touching.frontY,this.touching.none=!0,this.touching.up=!1,this.touching.down=!1,this.touching.backX=!1,this.touching.backY=!1,this.touching.frontX=!1,this.touching.frontY=!1,this.blocked.up=!1,this.blocked.down=!1,this.blocked.backX=!1,this.blocked.frontX=!1,this.blocked.backY=!1,this.blocked.backX=!1,this.embedded=!1,this.updateBounds(),this.position.x=this.sprite.isoX+(this.widthX*-this.sprite.anchor.x+.5*this.widthX)+this.offset.x,this.position.y=this.sprite.isoY+(this.widthY*this.sprite.anchor.x-.5*this.widthY)+this.offset.y,this.position.z=this.sprite.isoZ-Math.abs(this.sprite.height)*(1-this.sprite.anchor.y)+Math.abs(.5*this.sprite.width)+this.offset.z,this.rotation=this.sprite.angle,this.preRotation=this.rotation,(this._reset||1===this.sprite._cache[4])&&(this.prev.x=this.position.x,this.prev.y=this.position.y,this.prev.z=this.position.z),this.moves&&(this.game.physics.isoArcade.updateMotion(this),this.newVelocity.set(this.velocity.x*this.game.time.physicsElapsed,this.velocity.y*this.game.time.physicsElapsed,this.velocity.z*this.game.time.physicsElapsed),this.position.x+=this.newVelocity.x,this.position.y+=this.newVelocity.y,this.position.z+=this.newVelocity.z,(this.position.x!==this.prev.x||this.position.y!==this.prev.y||this.position.z!==this.prev.z)&&(this.speed=Math.sqrt(this.velocity.x*this.velocity.x+this.velocity.y*this.velocity.y+this.velocity.z*this.velocity.z),this.angle=Math.atan2(this.velocity.y,this.velocity.x)),this.collideWorldBounds&&this.checkWorldBounds()),this._dx=this.deltaX(),this._dy=this.deltaY(),this._dz=this.deltaZ(),this._reset=!1)},postUpdate:function(){this.enable&&2!==this.phase&&(this.phase=2,this.deltaX()<0?this.facing=Phaser.Plugin.Isometric.BACKWARDX:this.deltaX()>0&&(this.facing=Phaser.Plugin.Isometric.FORWARDX),this.deltaY()<0?this.facing=Phaser.Plugin.Isometric.BACKWARDY:this.deltaY()>0&&(this.facing=Phaser.Plugin.Isometric.FORWARDY),this.deltaZ()<0?this.facing=Phaser.Plugin.Isometric.DOWN:this.deltaZ()>0&&(this.facing=Phaser.Plugin.Isometric.UP),this.moves&&(this._dx=this.deltaX(),this._dy=this.deltaY(),this._dz=this.deltaZ(),0!==this.deltaMax.x&&0!==this._dx&&(this._dx<0&&this._dx<-this.deltaMax.x?this._dx=-this.deltaMax.x:this._dx>0&&this._dx>this.deltaMax.x&&(this._dx=this.deltaMax.x)),0!==this.deltaMax.y&&0!==this._dy&&(this._dy<0&&this._dy<-this.deltaMax.y?this._dy=-this.deltaMax.y:this._dy>0&&this._dy>this.deltaMax.y&&(this._dy=this.deltaMax.y)),0!==this.deltaMax.z&&0!==this._dz&&(this._dz<0&&this._dz<-this.deltaMax.z?this._dz=-this.deltaMax.z:this._dz>0&&this._dz>this.deltaMax.z&&(this._dz=this.deltaMax.z)),this.sprite.isoX+=this._dx,this.sprite.isoY+=this._dy,this.sprite.isoZ+=this._dz),this.center.setTo(this.position.x+this.halfWidthX,this.position.y+this.halfWidthY,this.position.z+this.halfHeight),this.allowRotation&&(this.sprite.angle+=this.deltaR()),this.prev.x=this.position.x,this.prev.y=this.position.y,this.prev.z=this.position.z)},destroy:function(){this.sprite=null},checkWorldBounds:function(){this.position.xthis.game.physics.isoArcade.bounds.frontX&&this.game.physics.isoArcade.checkCollision.frontX&&(this.position.x=this.game.physics.isoArcade.bounds.frontX-this.widthX,this.velocity.x*=-this.bounce.x,this.blocked.frontX=!0),this.position.ythis.game.physics.isoArcade.bounds.frontY&&this.game.physics.isoArcade.checkCollision.frontY&&(this.position.y=this.game.physics.isoArcade.bounds.frontY-this.widthY,this.velocity.y*=-this.bounce.y,this.blocked.frontY=!0),this.position.zthis.game.physics.isoArcade.bounds.top&&this.game.physics.isoArcade.checkCollision.up&&(this.position.z=this.game.physics.isoArcade.bounds.top-this.height,this.velocity.z*=-this.bounce.z,this.blocked.up=!0)},setSize:function(a,b,c,d,e,f){"undefined"==typeof d&&(d=this.offset.x),"undefined"==typeof e&&(e=this.offset.y),"undefined"==typeof f&&(f=this.offset.z),this.sourceWidthX=a,this.sourceWidthY=b,this.sourceHeight=c,this.widthX=this.sourceWidthX*this._sx,this.widthY=this.sourceWidthY*this._sx,this.height=this.sourceHeight*this._sy,this.halfWidthX=Math.floor(.5*this.widthX),this.halfWidthY=Math.floor(.5*this.widthY),this.halfHeight=Math.floor(.5*this.height),this.offset.setTo(d,e,f),this.center.setTo(this.position.x+this.halfWidthX,this.position.y+this.halfWidthY,this.position.z+this.halfHeight)},reset:function(a,b,c){this.velocity.set(0),this.acceleration.set(0),this.angularVelocity=0,this.angularAcceleration=0,this.position.x=a+(this.widthX*-this.sprite.anchor.x+.5*this.widthX)+this.offset.x,this.position.y=b+(this.widthY*this.sprite.anchor.x-.5*this.widthY)+this.offset.y,this.position.z=c-(this.height*-this.sprite.anchor.y*2+this.height)+this.offset.z,this.prev.x=this.position.x,this.prev.y=this.position.y,this.prev.z=this.position.z,this.rotation=this.sprite.angle,this.preRotation=this.rotation,this._sx=this.sprite.scale.x,this._sy=this.sprite.scale.y,this.center.setTo(this.position.x+this.halfWidthX,this.position.y+this.halfWidthY,this.position.z+this.halfHeight)},hitTest:function(a,b,c){return Phaser.Plugin.Isometric.Cube.contains(this,a,b,c)},onFloor:function(){return this.blocked.down},onWall:function(){return this.blocked.frontX||this.blocked.frontY||this.blocked.backX||this.blocked.backY},deltaAbsX:function(){return this.deltaX()>0?this.deltaX():-this.deltaX()},deltaAbsY:function(){return this.deltaY()>0?this.deltaY():-this.deltaY()},deltaAbsZ:function(){return this.deltaZ()>0?this.deltaZ():-this.deltaZ()},deltaX:function(){return this.position.x-this.prev.x},deltaY:function(){return this.position.y-this.prev.y},deltaZ:function(){return this.position.z-this.prev.z},deltaR:function(){return this.rotation-this.preRotation},getCorners:function(){return this._corners[0].setTo(this.x,this.y,this.z),this._corners[1].setTo(this.x,this.y,this.z+this.height),this._corners[2].setTo(this.x,this.y+this.widthY,this.z),this._corners[3].setTo(this.x,this.y+this.widthY,this.z+this.height),this._corners[4].setTo(this.x+this.widthX,this.y,this.z),this._corners[5].setTo(this.x+this.widthX,this.y,this.z+this.height),this._corners[6].setTo(this.x+this.widthX,this.y+this.widthY,this.z),this._corners[7].setTo(this.x+this.widthX,this.y+this.widthY,this.z+this.height),this._corners}},Object.defineProperty(Phaser.Plugin.Isometric.Body.prototype,"top",{get:function(){return this.position.z+this.height}}),Object.defineProperty(Phaser.Plugin.Isometric.Body.prototype,"frontX",{get:function(){return this.position.x+this.widthX}}),Object.defineProperty(Phaser.Plugin.Isometric.Body.prototype,"right",{get:function(){return this.position.x+this.widthX}}),Object.defineProperty(Phaser.Plugin.Isometric.Body.prototype,"frontY",{get:function(){return this.position.y+this.widthY}}),Object.defineProperty(Phaser.Plugin.Isometric.Body.prototype,"bottom",{get:function(){return this.position.y+this.widthY}}),Object.defineProperty(Phaser.Plugin.Isometric.Body.prototype,"x",{get:function(){return this.position.x},set:function(a){this.position.x=a}}),Object.defineProperty(Phaser.Plugin.Isometric.Body.prototype,"y",{get:function(){return this.position.y},set:function(a){this.position.y=a}}),Object.defineProperty(Phaser.Plugin.Isometric.Body.prototype,"z",{get:function(){return this.position.z},set:function(a){this.position.z=a}}),Phaser.Plugin.Isometric.Body.render=function(a,b,c,d){"undefined"==typeof d&&(d=!0),c=c||"rgba(0,255,0,0.4)";var e=[],f=b.getCorners(),g=-b.sprite.game.camera.x,h=-b.sprite.game.camera.y;if(d){e=[f[1],f[3],f[2],f[6],f[4],f[5],f[1]],e=e.map(function(a){var b=this.game.iso.project(a);return b.x+=g,b.y+=h,b}),a.beginPath(),a.fillStyle=c,a.moveTo(e[0].x,e[0].y);for(var i=1;ithis.maxObjects&&this.levelthis.bounds.top&&(b=4):a.y>this.bounds.frontY&&(a.zthis.bounds.top&&(b=6)):a.x>this.bounds.frontX&&(a.ythis.bounds.top&&(b=5):a.y>this.bounds.frontY&&(a.zthis.bounds.top&&(b=7))),b},retrieve:function(a){var b,c;if(a instanceof Phaser.Plugin.Isometric.Cube)b=this.objects,c=this.getIndex(a);else{if(!a.body)return this._empty;b=this.objects,c=this.getIndex(a.body)}return this.nodes[0]&&(-1!==c?b=b.concat(this.nodes[c].retrieve(a)):(b=b.concat(this.nodes[0].retrieve(a)),b=b.concat(this.nodes[1].retrieve(a)),b=b.concat(this.nodes[2].retrieve(a)),b=b.concat(this.nodes[3].retrieve(a)),b=b.concat(this.nodes[4].retrieve(a)),b=b.concat(this.nodes[5].retrieve(a)),b=b.concat(this.nodes[6].retrieve(a)),b=b.concat(this.nodes[7].retrieve(a)))),b},clear:function(){this.objects.length=0;for(var a=this.nodes.length;a--;)this.nodes[a].clear(),this.nodes.splice(a,1);this.nodes.length=0}},Phaser.Plugin.Isometric.Octree.prototype.constructor=Phaser.Plugin.Isometric.Octree,Phaser.Utils.Debug.prototype.octree=function(a,b){b=b||"rgba(255,0,0,0.3)",this.start();var c,d,e=a.bounds;if(0===a.nodes.length){this.context.strokeStyle=b;var f=new Phaser.Plugin.Isometric.Cube(e.x,e.y,e.z,e.widthX,e.widthY,e.height),g=f.getCorners();for(d=g.slice(0,g.length),d=d.map(function(a){return this.game.iso.project(a)}),this.context.moveTo(d[0].x,d[0].y),this.context.beginPath(),this.context.strokeStyle=b,this.context.lineTo(d[1].x,d[1].y),this.context.lineTo(d[3].x,d[3].y),this.context.lineTo(d[2].x,d[2].y),this.context.lineTo(d[6].x,d[6].y),this.context.lineTo(d[4].x,d[4].y),this.context.lineTo(d[5].x,d[5].y),this.context.lineTo(d[1].x,d[1].y),this.context.lineTo(d[0].x,d[0].y),this.context.lineTo(d[4].x,d[4].y),this.context.moveTo(d[0].x,d[0].y),this.context.lineTo(d[2].x,d[2].y),this.context.moveTo(d[3].x,d[3].y),this.context.lineTo(d[7].x,d[7].y),this.context.lineTo(d[6].x,d[6].y),this.context.moveTo(d[7].x,d[7].y),this.context.lineTo(d[5].x,d[5].y),this.context.stroke(),this.context.closePath(),c=0;c0&&this.enable(a[c],!0));else a instanceof Phaser.Group?this.enable(a.children,b):(this.enableBody(a),b&&a.hasOwnProperty("children")&&a.children.length>0&&this.enable(a.children,!0)) +/* Phaser Isometric 0.7.3 - 07-08-2014 by Lewis Lane */ +Phaser.Plugin.Isometric=function(a,b){Phaser.Plugin.call(this,a,b),this.game.iso=this.game.iso||new Phaser.Plugin.Isometric.Projector(this.game,Phaser.Plugin.Isometric.CLASSIC)},Phaser.Plugin.Isometric.prototype=Object.create(Phaser.Plugin.prototype),Phaser.Plugin.Isometric.prototype.constructor=Phaser.Plugin.Isometric,Phaser.Plugin.Isometric.VERSION="0.7.3",Phaser.Plugin.Isometric.UP=0,Phaser.Plugin.Isometric.DOWN=1,Phaser.Plugin.Isometric.FORWARDX=2,Phaser.Plugin.Isometric.FORWARDY=3,Phaser.Plugin.Isometric.BACKWARDX=4,Phaser.Plugin.Isometric.BACKWARDY=5,Phaser.Plugin.Isometric.ISOSPRITE="isosprite",Phaser.Plugin.Isometric.ISOARCADE="isoarcade",Phaser.Plugin.Isometric.CLASSIC=.5,Phaser.Plugin.Isometric.TRUE=.6154797093263624,Phaser.Plugin.Isometric.Cube=function(a,b,c,d,e,f){a=a||0,b=b||0,c=c||0,d=d||0,e=e||0,f=f||0,this.x=a,this.y=b,this.z=c,this.widthX=d,this.widthY=e,this.height=f,this._corners=[new Phaser.Plugin.Isometric.Point3(this.x,this.y,this.z),new Phaser.Plugin.Isometric.Point3(this.x,this.y,this.z+this.height),new Phaser.Plugin.Isometric.Point3(this.x,this.y+this.widthY,this.z),new Phaser.Plugin.Isometric.Point3(this.x,this.y+this.widthY,this.z+this.height),new Phaser.Plugin.Isometric.Point3(this.x+this.widthX,this.y,this.z),new Phaser.Plugin.Isometric.Point3(this.x+this.widthX,this.y,this.z+this.height),new Phaser.Plugin.Isometric.Point3(this.x+this.widthX,this.y+this.widthY,this.z),new Phaser.Plugin.Isometric.Point3(this.x+this.widthX,this.y+this.widthY,this.z+this.height)]},Phaser.Plugin.Isometric.Cube.prototype.constructor=Phaser.Plugin.Isometric.Cube,Phaser.Plugin.Isometric.Cube.prototype={setTo:function(a,b,c,d,e,f){return this.x=a,this.y=b,this.z=c,this.widthX=d,this.widthY=e,this.height=f,this},copyFrom:function(a){this.setTo(a.x,a.y,a.z,a.widthX,a.widthY,a.height)},copyTo:function(a){return a.x=this.x,a.y=this.y,a.z=this.z,a.widthX=this.widthX,a.widthY=this.widthY,a.height=this.height,a},size:function(a){return Phaser.Plugin.Isometric.Cube.size(this,a)},clone:function(a){return Phaser.Plugin.Isometric.Cube.clone(this,a)},intersects:function(a){return Phaser.Plugin.Isometric.Cube.intersects(this,a)},getCorners:function(){return this._corners[0].setTo(this.x,this.y,this.z),this._corners[1].setTo(this.x,this.y,this.z+this.height),this._corners[2].setTo(this.x,this.y+this.widthY,this.z),this._corners[3].setTo(this.x,this.y+this.widthY,this.z+this.height),this._corners[4].setTo(this.x+this.widthX,this.y,this.z),this._corners[5].setTo(this.x+this.widthX,this.y,this.z+this.height),this._corners[6].setTo(this.x+this.widthX,this.y+this.widthY,this.z),this._corners[7].setTo(this.x+this.widthX,this.y+this.widthY,this.z+this.height),this._corners},toString:function(){return"[{Cube (x="+this.x+" y="+this.y+" z="+this.z+" widthX="+this.widthX+" widthY="+this.widthY+" height="+this.height+" empty="+this.empty+")}]"}},Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"halfWidthX",{get:function(){return Math.round(.5*this.widthX)}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"halfWidthY",{get:function(){return Math.round(.5*this.widthY)}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"halfHeight",{get:function(){return Math.round(.5*this.height)}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"bottom",{get:function(){return this.z},set:function(a){this.height=a>=this.top?0:this.top-a,this.z=a}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"top",{get:function(){return this.z+this.height},set:function(a){this.height=a<=this.z?0:a-this.z}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"backX",{get:function(){return this.x},set:function(a){this.widthX=a>=this.frontX?0:this.frontX-a,this.x=a}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"backY",{get:function(){return this.y},set:function(a){this.widthY=a>=this.frontY?0:this.frontY-a,this.y=a}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"frontX",{get:function(){return this.x+this.widthX},set:function(a){this.widthX=a<=this.x?0:a-this.x}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"frontY",{get:function(){return this.y+this.widthY},set:function(a){this.widthY=a<=this.y?0:a-this.y}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"volume",{get:function(){return this.widthX*this.widthY*this.height}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"centerX",{get:function(){return this.x+this.halfWidthX},set:function(a){this.x=a-this.halfWidthX}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"centerY",{get:function(){return this.y+this.halfWidthY},set:function(a){this.y=a-this.halfWidthY}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"centerZ",{get:function(){return this.z+this.halfHeight},set:function(a){this.z=a-this.halfHeight}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"randomX",{get:function(){return this.x+Math.random()*this.widthX}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"randomY",{get:function(){return this.y+Math.random()*this.widthY}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"randomZ",{get:function(){return this.z+Math.random()*this.height}}),Object.defineProperty(Phaser.Plugin.Isometric.Cube.prototype,"empty",{get:function(){return!this.widthX||!this.widthY||!this.height},set:function(a){a===!0&&this.setTo(0,0,0,0,0,0)}}),Phaser.Plugin.Isometric.Cube.size=function(a,b){return"undefined"==typeof b||null===b?b=new Phaser.Plugin.Isometric.Point3(a.widthX,a.widthY,a.height):b.setTo(a.widthX,a.widthY,a.height),b},Phaser.Plugin.Isometric.Cube.clone=function(a,b){return"undefined"==typeof b||null===b?b=new Phaser.Plugin.Isometric.Cube(a.x,a.y,a.z,a.widthX,a.widthY,a.height):b.setTo(a.x,a.y,a.z,a.widthX,a.widthY,a.height),b},Phaser.Plugin.Isometric.Cube.contains=function(a,b,c,d){return a.widthX<=0||a.widthY<=0||a.height<=0?!1:b>=a.x&&b<=a.right&&c>=a.y&&c<=a.back&&d>=a.z&&d<=a.top},Phaser.Plugin.Isometric.Cube.containsPoint3=function(a,b){return Phaser.Plugin.Isometric.Cube.contains(a,b.x,b.y,b.z)},Phaser.Plugin.Isometric.Cube.containsCube=function(a,b){return a.volume>b.volume?!1:a.x>=b.x&&a.y>=b.y&&a.z>=b.z&&a.frontX<=b.frontX&&a.frontY<=b.frontY&&a.top<=b.top},Phaser.Plugin.Isometric.Cube.intersects=function(a,b){return a.widthX<=0||a.widthY<=0||a.height<=0||b.widthX<=0||b.widthY<=0||b.height<=0?!1:!(a.frontXb.frontX||a.y>b.frontY||a.z>b.top||a.top0&&(this.position.x=Phaser.Math.snapTo(this.position.x,this.snap),this.position.y=Phaser.Math.snapTo(this.position.y,this.snap)),this._isoPositionChanged=!1)},Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype,"isoX",{get:function(){return this._isoPosition.x},set:function(a){this._isoPosition.x=a,this._depthChanged=this._isoPositionChanged=!0}}),Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype,"isoY",{get:function(){return this._isoPosition.y},set:function(a){this._isoPosition.y=a,this._depthChanged=this._isoPositionChanged=!0}}),Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype,"isoZ",{get:function(){return this._isoPosition.z},set:function(a){this._isoPosition.z=a,this._depthChanged=this._isoPositionChanged=!0}}),Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype,"isoPosition",{get:function(){return this._isoPosition}}),Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype,"depth",{get:function(){return this._depthChanged===!0&&(this._depth=this._isoPosition.x+this._isoPosition.y,this._depthChanged=!1),this._depth}}),Phaser.GameObjectCreator.prototype.isoSprite=function(a,b,c,d,e){return new Phaser.Plugin.Isometric.IsoSprite(this.game,a,b,c,d,e)},Phaser.GameObjectFactory.prototype.isoSprite=function(a,b,c,d,e,f){return"undefined"==typeof f&&(f=this.world),f.add(new Phaser.Plugin.Isometric.IsoSprite(this.game,a,b,c,d,e))},Phaser.Plugin.Isometric.Octree=function(a,b,c,d,e,f,g,h,i){this.maxObjects=10,this.maxLevels=4,this.level=0,this.bounds={},this.objects=[],this.nodes=[],this._empty=[],this.reset(a,b,c,d,e,f,g,h,i)},Phaser.Plugin.Isometric.Octree.prototype={reset:function(a,b,c,d,e,f,g,h,i){this.maxObjects=g||10,this.maxLevels=h||4,this.level=i||0,this.bounds={x:Math.round(a),y:Math.round(b),z:Math.round(c),widthX:d,widthY:e,height:f,subWidthX:Math.floor(.5*d),subWidthY:Math.floor(.5*e),subHeight:Math.floor(.5*f),frontX:Math.round(a)+Math.floor(.5*d),frontY:Math.round(b)+Math.floor(.5*e),top:Math.round(c)+Math.floor(.5*f)},this.objects.length=0,this.nodes.length=0},populate:function(a){a.forEach(this.populateHandler,this,!0)},populateHandler:function(a){a.body&&a.exists&&this.insert(a.body)},split:function(){this.nodes[0]=new Phaser.Plugin.Isometric.Octree(this.bounds.x,this.bounds.y,this.bounds.z,this.bounds.subWidthX,this.bounds.subWidthY,this.bounds.subHeight,this.maxLevels,this.level+1),this.nodes[1]=new Phaser.Plugin.Isometric.Octree(this.bounds.frontX,this.bounds.y,this.bounds.z,this.bounds.subWidthX,this.bounds.subWidthY,this.bounds.subHeight,this.maxLevels,this.level+1),this.nodes[2]=new Phaser.Plugin.Isometric.Octree(this.bounds.x,this.bounds.frontY,this.bounds.z,this.bounds.subWidthX,this.bounds.subWidthY,this.bounds.subHeight,this.maxLevels,this.level+1),this.nodes[3]=new Phaser.Plugin.Isometric.Octree(this.bounds.frontX,this.bounds.frontY,this.bounds.z,this.bounds.subWidthX,this.bounds.subWidthY,this.bounds.subHeight,this.maxLevels,this.level+1),this.nodes[4]=new Phaser.Plugin.Isometric.Octree(this.bounds.x,this.bounds.y,this.bounds.top,this.bounds.subWidthX,this.bounds.subWidthY,this.bounds.subHeight,this.maxLevels,this.level+1),this.nodes[5]=new Phaser.Plugin.Isometric.Octree(this.bounds.frontX,this.bounds.y,this.bounds.top,this.bounds.subWidthX,this.bounds.subWidthY,this.bounds.subHeight,this.maxLevels,this.level+1),this.nodes[6]=new Phaser.Plugin.Isometric.Octree(this.bounds.x,this.bounds.frontY,this.bounds.top,this.bounds.subWidthX,this.bounds.subWidthY,this.bounds.subHeight,this.maxLevels,this.level+1),this.nodes[7]=new Phaser.Plugin.Isometric.Octree(this.bounds.frontX,this.bounds.frontY,this.bounds.top,this.bounds.subWidthX,this.bounds.subWidthY,this.bounds.subHeight,this.maxLevels,this.level+1)},insert:function(a){var b,c=0;if(null!==this.nodes[0]&&(b=this.getIndex(a),-1!==b))return void this.nodes[b].insert(a);if(this.objects.push(a),this.objects.length>this.maxObjects&&this.levelthis.bounds.top&&(b=4):a.y>this.bounds.frontY&&(a.zthis.bounds.top&&(b=6)):a.x>this.bounds.frontX&&(a.ythis.bounds.top&&(b=5):a.y>this.bounds.frontY&&(a.zthis.bounds.top&&(b=7))),b},retrieve:function(a){var b,c;if(a instanceof Phaser.Plugin.Isometric.Cube)b=this.objects,c=this.getIndex(a);else{if(!a.body)return this._empty;b=this.objects,c=this.getIndex(a.body)}return this.nodes[0]&&(-1!==c?b=b.concat(this.nodes[c].retrieve(a)):(b=b.concat(this.nodes[0].retrieve(a)),b=b.concat(this.nodes[1].retrieve(a)),b=b.concat(this.nodes[2].retrieve(a)),b=b.concat(this.nodes[3].retrieve(a)),b=b.concat(this.nodes[4].retrieve(a)),b=b.concat(this.nodes[5].retrieve(a)),b=b.concat(this.nodes[6].retrieve(a)),b=b.concat(this.nodes[7].retrieve(a)))),b},clear:function(){this.objects.length=0;for(var a=this.nodes.length;a--;)this.nodes[a].clear(),this.nodes.splice(a,1);this.nodes.length=0}},Phaser.Plugin.Isometric.Octree.prototype.constructor=Phaser.Plugin.Isometric.Octree,Phaser.Utils.Debug.prototype.octree=function(a,b){b=b||"rgba(255,0,0,0.3)",this.start();var c,d,e=a.bounds;if(0===a.nodes.length){this.context.strokeStyle=b;var f=new Phaser.Plugin.Isometric.Cube(e.x,e.y,e.z,e.widthX,e.widthY,e.height),g=f.getCorners();for(d=g.slice(0,g.length),d=d.map(function(a){return this.game.iso.project(a)}),this.context.moveTo(d[0].x,d[0].y),this.context.beginPath(),this.context.strokeStyle=b,this.context.lineTo(d[1].x,d[1].y),this.context.lineTo(d[3].x,d[3].y),this.context.lineTo(d[2].x,d[2].y),this.context.lineTo(d[6].x,d[6].y),this.context.lineTo(d[4].x,d[4].y),this.context.lineTo(d[5].x,d[5].y),this.context.lineTo(d[1].x,d[1].y),this.context.lineTo(d[0].x,d[0].y),this.context.lineTo(d[4].x,d[4].y),this.context.moveTo(d[0].x,d[0].y),this.context.lineTo(d[2].x,d[2].y),this.context.moveTo(d[3].x,d[3].y),this.context.lineTo(d[7].x,d[7].y),this.context.lineTo(d[6].x,d[6].y),this.context.moveTo(d[7].x,d[7].y),this.context.lineTo(d[5].x,d[5].y),this.context.stroke(),this.context.closePath(),c=0;c0&&(this.facing=Phaser.Plugin.Isometric.FORWARDX),this.deltaY()<0?this.facing=Phaser.Plugin.Isometric.BACKWARDY:this.deltaY()>0&&(this.facing=Phaser.Plugin.Isometric.FORWARDY),this.deltaZ()<0?this.facing=Phaser.Plugin.Isometric.DOWN:this.deltaZ()>0&&(this.facing=Phaser.Plugin.Isometric.UP),this.moves&&(this._dx=this.deltaX(),this._dy=this.deltaY(),this._dz=this.deltaZ(),0!==this.deltaMax.x&&0!==this._dx&&(this._dx<0&&this._dx<-this.deltaMax.x?this._dx=-this.deltaMax.x:this._dx>0&&this._dx>this.deltaMax.x&&(this._dx=this.deltaMax.x)),0!==this.deltaMax.y&&0!==this._dy&&(this._dy<0&&this._dy<-this.deltaMax.y?this._dy=-this.deltaMax.y:this._dy>0&&this._dy>this.deltaMax.y&&(this._dy=this.deltaMax.y)),0!==this.deltaMax.z&&0!==this._dz&&(this._dz<0&&this._dz<-this.deltaMax.z?this._dz=-this.deltaMax.z:this._dz>0&&this._dz>this.deltaMax.z&&(this._dz=this.deltaMax.z)),this.sprite.isoX+=this._dx,this.sprite.isoY+=this._dy,this.sprite.isoZ+=this._dz),this.center.setTo(this.position.x+this.halfWidthX,this.position.y+this.halfWidthY,this.position.z+this.halfHeight),this.allowRotation&&(this.sprite.angle+=this.deltaR()),this.prev.x=this.position.x,this.prev.y=this.position.y,this.prev.z=this.position.z)},destroy:function(){this.sprite=null},checkWorldBounds:function(){this.position.xthis.game.physics.isoArcade.bounds.frontX&&this.game.physics.isoArcade.checkCollision.frontX&&(this.position.x=this.game.physics.isoArcade.bounds.frontX-this.widthX,this.velocity.x*=-this.bounce.x,this.blocked.frontX=!0),this.position.ythis.game.physics.isoArcade.bounds.frontY&&this.game.physics.isoArcade.checkCollision.frontY&&(this.position.y=this.game.physics.isoArcade.bounds.frontY-this.widthY,this.velocity.y*=-this.bounce.y,this.blocked.frontY=!0),this.position.zthis.game.physics.isoArcade.bounds.top&&this.game.physics.isoArcade.checkCollision.up&&(this.position.z=this.game.physics.isoArcade.bounds.top-this.height,this.velocity.z*=-this.bounce.z,this.blocked.up=!0)},setSize:function(a,b,c,d,e,f){"undefined"==typeof d&&(d=this.offset.x),"undefined"==typeof e&&(e=this.offset.y),"undefined"==typeof f&&(f=this.offset.z),this.sourceWidthX=a,this.sourceWidthY=b,this.sourceHeight=c,this.widthX=this.sourceWidthX*this._sx,this.widthY=this.sourceWidthY*this._sx,this.height=this.sourceHeight*this._sy,this.halfWidthX=Math.floor(.5*this.widthX),this.halfWidthY=Math.floor(.5*this.widthY),this.halfHeight=Math.floor(.5*this.height),this.offset.setTo(d,e,f),this.center.setTo(this.position.x+this.halfWidthX,this.position.y+this.halfWidthY,this.position.z+this.halfHeight)},reset:function(a,b,c){this.velocity.set(0),this.acceleration.set(0),this.angularVelocity=0,this.angularAcceleration=0,this.position.x=a+(this.widthX*-this.sprite.anchor.x+.5*this.widthX)+this.offset.x,this.position.y=b+(this.widthY*this.sprite.anchor.x-.5*this.widthY)+this.offset.y,this.position.z=c-Math.abs(this.sprite.height)*(1-this.sprite.anchor.y)+Math.abs(.5*this.sprite.width)+this.offset.z,this.prev.x=this.position.x,this.prev.y=this.position.y,this.prev.z=this.position.z,this.rotation=this.sprite.angle,this.preRotation=this.rotation,this._sx=this.sprite.scale.x,this._sy=this.sprite.scale.y,this.center.setTo(this.position.x+this.halfWidthX,this.position.y+this.halfWidthY,this.position.z+this.halfHeight),this.sprite._isoPositionChanged=!0},hitTest:function(a,b,c){return Phaser.Plugin.Isometric.Cube.contains(this,a,b,c)},onFloor:function(){return this.blocked.down},onWall:function(){return this.blocked.frontX||this.blocked.frontY||this.blocked.backX||this.blocked.backY},deltaAbsX:function(){return this.deltaX()>0?this.deltaX():-this.deltaX()},deltaAbsY:function(){return this.deltaY()>0?this.deltaY():-this.deltaY()},deltaAbsZ:function(){return this.deltaZ()>0?this.deltaZ():-this.deltaZ()},deltaX:function(){return this.position.x-this.prev.x},deltaY:function(){return this.position.y-this.prev.y},deltaZ:function(){return this.position.z-this.prev.z},deltaR:function(){return this.rotation-this.preRotation},getCorners:function(){return this._corners[0].setTo(this.x,this.y,this.z),this._corners[1].setTo(this.x,this.y,this.z+this.height),this._corners[2].setTo(this.x,this.y+this.widthY,this.z),this._corners[3].setTo(this.x,this.y+this.widthY,this.z+this.height),this._corners[4].setTo(this.x+this.widthX,this.y,this.z),this._corners[5].setTo(this.x+this.widthX,this.y,this.z+this.height),this._corners[6].setTo(this.x+this.widthX,this.y+this.widthY,this.z),this._corners[7].setTo(this.x+this.widthX,this.y+this.widthY,this.z+this.height),this._corners}},Object.defineProperty(Phaser.Plugin.Isometric.Body.prototype,"top",{get:function(){return this.position.z+this.height}}),Object.defineProperty(Phaser.Plugin.Isometric.Body.prototype,"frontX",{get:function(){return this.position.x+this.widthX}}),Object.defineProperty(Phaser.Plugin.Isometric.Body.prototype,"right",{get:function(){return this.position.x+this.widthX}}),Object.defineProperty(Phaser.Plugin.Isometric.Body.prototype,"frontY",{get:function(){return this.position.y+this.widthY}}),Object.defineProperty(Phaser.Plugin.Isometric.Body.prototype,"bottom",{get:function(){return this.position.y+this.widthY}}),Object.defineProperty(Phaser.Plugin.Isometric.Body.prototype,"x",{get:function(){return this.position.x},set:function(a){this.position.x=a}}),Object.defineProperty(Phaser.Plugin.Isometric.Body.prototype,"y",{get:function(){return this.position.y},set:function(a){this.position.y=a}}),Object.defineProperty(Phaser.Plugin.Isometric.Body.prototype,"z",{get:function(){return this.position.z},set:function(a){this.position.z=a}}),Phaser.Plugin.Isometric.Body.render=function(a,b,c,d){"undefined"==typeof d&&(d=!0),c=c||"rgba(0,255,0,0.4)";var e=[],f=b.getCorners(),g=-b.sprite.game.camera.x,h=-b.sprite.game.camera.y;if(d){e=[f[1],f[3],f[2],f[6],f[4],f[5],f[1]],e=e.map(function(a){var b=this.game.iso.project(a);return b.x+=g,b.y+=h,b}),a.beginPath(),a.fillStyle=c,a.moveTo(e[0].x,e[0].y);for(var i=1;i0&&this.enable(a[c],!0));else a instanceof Phaser.Group?this.enable(a.children,b):(this.enableBody(a),b&&a.hasOwnProperty("children")&&a.children.length>0&&this.enable(a.children,!0)) },enableBody:function(a){a.hasOwnProperty("body")&&null===a.body&&(a.body=new Phaser.Plugin.Isometric.Body(a))},updateMotion:function(a){this._velocityDelta=this.computeVelocity(0,a,a.angularVelocity,a.angularAcceleration,a.angularDrag,a.maxAngular)-a.angularVelocity,a.angularVelocity+=this._velocityDelta,a.rotation+=a.angularVelocity*this.game.time.physicsElapsed,a.velocity.x=this.computeVelocity(1,a,a.velocity.x,a.acceleration.x,a.drag.x,a.maxVelocity.x),a.velocity.y=this.computeVelocity(2,a,a.velocity.y,a.acceleration.y,a.drag.y,a.maxVelocity.y),a.velocity.z=this.computeVelocity(3,a,a.velocity.z,a.acceleration.z,a.drag.z,a.maxVelocity.z)},computeVelocity:function(a,b,c,d,e,f){return f=f||1e4,1===a&&b.allowGravity?c+=(this.gravity.x+b.gravity.x)*this.game.time.physicsElapsed:2===a&&b.allowGravity?c+=(this.gravity.y+b.gravity.y)*this.game.time.physicsElapsed:3===a&&b.allowGravity&&(c+=(this.gravity.z+b.gravity.z)*this.game.time.physicsElapsed),d?c+=d*this.game.time.physicsElapsed:e&&(this._drag=e*this.game.time.physicsElapsed,c-this._drag>0?c-=this._drag:c+this._drag<0?c+=this._drag:c=0),c>f?c=f:-f>c&&(c=-f),c},overlap:function(a,b,c,d,e){if(c=c||null,d=d||null,e=e||c,this._result=!1,this._total=0,Array.isArray(b))for(var f=0,g=b.length;g>f;f++)this.collideHandler(a,b[f],c,d,e,!0);else this.collideHandler(a,b,c,d,e,!0);return this._total>0},collide:function(a,b,c,d,e){return c=c||null,d=d||null,e=e||c,this._result=!1,this._total=0,this.collideHandler(a,b,c,d,e,!1),this._total>0},collideHandler:function(a,b,c,d,e,f){return b||a.type!==Phaser.GROUP&&!Array.isArray(a)?void(a&&b&&(a.exists||a.length)&&(b.exists||b.length)&&(a.type===Phaser.Plugin.Isometric.ISOSPRITE?b.type===Phaser.Plugin.Isometric.ISOSPRITE?this.collideSpriteVsSprite(a,b,c,d,e,f):(b.type===Phaser.GROUP||Array.isArray(b))&&this.collideSpriteVsGroup(a,b,c,d,e,f):(a.type===Phaser.GROUP||Array.isArray(a))&&(b.type===Phaser.Plugin.Isometric.ISOSPRITE?this.collideSpriteVsGroup(b,a,c,d,e,f):(b.type===Phaser.GROUP||Array.isArray(b))&&this.collideGroupVsGroup(a,b,c,d,e,f)))):void this.collideGroupVsSelf(a,c,d,e,f)},collideSpriteVsSprite:function(a,b,c,d,e,f){return a.body&&b.body?(this.separate(a.body,b.body,d,e,f)&&(c&&c.call(e,a,b),this._total++),!0):!1},collideSpriteVsGroup:function(a,b,c,d,e,f){var g,h;if(0!==b.length&&a.body)if(a.body.skipTree||this.skipTree)for(g=0,h=b.children.length;h>g;g++)b.children[g]&&b.children[g].exists&&this.collideSpriteVsSprite(a,b.children[g],c,d,e,f);else for(this.useQuadTree?(this.quadTree.clear(),this.quadTree.reset(this.bounds.x,this.bounds.y,this.bounds.widthX,this.bounds.widthY,this.maxObjects,this.maxLevels),this.quadTree.populate(b),this._potentials=this.quadTree.retrieve(a)):(this.octree.clear(),this.octree.reset(this.bounds.x,this.bounds.y,this.bounds.z,this.bounds.widthX,this.bounds.widthY,this.bounds.height,this.maxObjects,this.maxLevels),this.octree.populate(b),this._potentials=this.octree.retrieve(a)),g=0,h=this._potentials.length;h>g;g++)this.separate(a.body,this._potentials[g],d,e,f)&&(c&&c.call(e,a,this._potentials[g].sprite),this._total++)},collideGroupVsSelf:function(a,b,c,d,e){if(0!==a.length)for(var f=a.children.length,g=0;f>g;g++)for(var h=g+1;f>=h;h++)a.children[g]&&a.children[h]&&a.children[g].exists&&a.children[h].exists&&this.collideSpriteVsSprite(a.children[g],a.children[h],b,c,d,e)},collideGroupVsGroup:function(a,b,c,d,e,f){if(0!==a.length&&0!==b.length)for(var g=0,h=a.children.length;h>g;g++)a.children[g].exists&&this.collideSpriteVsGroup(a.children[g],b,c,d,e,f)},separate:function(a,b,c,d,e){return a.enable&&b.enable&&this.intersects(a,b)?c&&c.call(d,a.sprite,b.sprite)===!1?!1:e?!0:(this._result=this.forceXY||Math.abs(this.gravity.z+a.gravity.z)=b.frontX?!1:a.y>=b.frontY?!1:a.top<=b.z?!1:a.z>=b.top?!1:!0},separateX:function(a,b,c){return a.immovable&&b.immovable?!1:(this._overlap=0,this.intersects(a,b)&&(this._maxOverlap=a.deltaAbsX()+b.deltaAbsX()+this.OVERLAP_BIAS,0===a.deltaX()&&0===b.deltaX()?(a.embedded=!0,b.embedded=!0):a.deltaX()>b.deltaX()?(this._overlap=a.frontX-b.x,this._overlap>this._maxOverlap||a.checkCollision.frontX===!1||b.checkCollision.backX===!1?this._overlap=0:(a.touching.none=!1,a.touching.frontX=!0,b.touching.none=!1,b.touching.backX=!0)):a.deltaX()this._maxOverlap||a.checkCollision.backX===!1||b.checkCollision.frontX===!1?this._overlap=0:(a.touching.none=!1,a.touching.backX=!0,b.touching.none=!1,b.touching.frontX=!0)),0!==this._overlap)?(a.overlapX=this._overlap,b.overlapX=this._overlap,c||a.customSeparateX||b.customSeparateX?!0:(this._velocity1=a.velocity.x,this._velocity2=b.velocity.x,a.immovable||b.immovable?a.immovable?b.immovable||(b.x+=this._overlap,b.velocity.x=this._velocity1-this._velocity2*b.bounce.x):(a.x=a.x-this._overlap,a.velocity.x=this._velocity2-this._velocity1*a.bounce.x):(this._overlap*=.5,a.x=a.x-this._overlap,b.x+=this._overlap,this._newVelocity1=Math.sqrt(this._velocity2*this._velocity2*b.mass/a.mass)*(this._velocity2>0?1:-1),this._newVelocity2=Math.sqrt(this._velocity1*this._velocity1*a.mass/b.mass)*(this._velocity1>0?1:-1),this._average=.5*(this._newVelocity1+this._newVelocity2),this._newVelocity1-=this._average,this._newVelocity2-=this._average,a.velocity.x=this._average+this._newVelocity1*a.bounce.x,b.velocity.x=this._average+this._newVelocity2*b.bounce.x),!0)):!1)},separateY:function(a,b,c){return a.immovable&&b.immovable?!1:(this._overlap=0,this.intersects(a,b)&&(this._maxOverlap=a.deltaAbsY()+b.deltaAbsY()+this.OVERLAP_BIAS,0===a.deltaY()&&0===b.deltaY()?(a.embedded=!0,b.embedded=!0):a.deltaY()>b.deltaY()?(this._overlap=a.frontY-b.y,this._overlap>this._maxOverlap||a.checkCollision.frontY===!1||b.checkCollision.backY===!1?this._overlap=0:(a.touching.none=!1,a.touching.frontY=!0,b.touching.none=!1,b.touching.backY=!0)):a.deltaY()this._maxOverlap||a.checkCollision.backY===!1||b.checkCollision.frontY===!1?this._overlap=0:(a.touching.none=!1,a.touching.backY=!0,b.touching.none=!1,b.touching.frontY=!0)),0!==this._overlap)?(a.overlapY=this._overlap,b.overlapY=this._overlap,c||a.customSeparateY||b.customSeparateY?!0:(this._velocity1=a.velocity.y,this._velocity2=b.velocity.y,a.immovable||b.immovable?a.immovable?b.immovable||(b.y+=this._overlap,b.velocity.y=this._velocity1-this._velocity2*b.bounce.y):(a.y=a.y-this._overlap,a.velocity.y=this._velocity2-this._velocity1*a.bounce.y):(this._overlap*=.5,a.y=a.y-this._overlap,b.y+=this._overlap,this._newVelocity1=Math.sqrt(this._velocity2*this._velocity2*b.mass/a.mass)*(this._velocity2>0?1:-1),this._newVelocity2=Math.sqrt(this._velocity1*this._velocity1*a.mass/b.mass)*(this._velocity1>0?1:-1),this._average=.5*(this._newVelocity1+this._newVelocity2),this._newVelocity1-=this._average,this._newVelocity2-=this._average,a.velocity.y=this._average+this._newVelocity1*a.bounce.y,b.velocity.y=this._average+this._newVelocity2*b.bounce.y),!0)):!1)},separateZ:function(a,b,c){return a.immovable&&b.immovable?!1:(this._overlap=0,this.intersects(a,b)&&(this._maxOverlap=a.deltaAbsZ()+b.deltaAbsZ()+this.OVERLAP_BIAS,0===a.deltaZ()&&0===b.deltaZ()?(a.embedded=!0,b.embedded=!0):a.deltaZ()>b.deltaZ()?(this._overlap=a.top-b.z,this._overlap>this._maxOverlap||a.checkCollision.down===!1||b.checkCollision.up===!1?this._overlap=0:(a.touching.none=!1,a.touching.down=!0,b.touching.none=!1,b.touching.up=!0)):a.deltaZ()this._maxOverlap||a.checkCollision.up===!1||b.checkCollision.down===!1?this._overlap=0:(a.touching.none=!1,a.touching.up=!0,b.touching.none=!1,b.touching.down=!0)),0!==this._overlap)?(a.overlapZ=this._overlap,b.overlapZ=this._overlap,c||a.customSeparateY||b.customSeparateZ?!0:(this._velocity1=a.velocity.z,this._velocity2=b.velocity.z,a.immovable||b.immovable?a.immovable?b.immovable||(b.z+=this._overlap,b.velocity.z=this._velocity1-this._velocity2*b.bounce.z,a.moves&&(b.x+=a.x-a.prev.x,a.y+=b.y-b.prev.y)):(a.z=a.z-this._overlap,a.velocity.z=this._velocity2-this._velocity1*a.bounce.z,b.moves&&(a.x+=b.x-b.prev.x,a.y+=b.y-b.prev.y)):(this._overlap*=.5,a.z=a.z-this._overlap,b.z+=this._overlap,this._newVelocity1=Math.sqrt(this._velocity2*this._velocity2*b.mass/a.mass)*(this._velocity2>0?1:-1),this._newVelocity2=Math.sqrt(this._velocity1*this._velocity1*a.mass/b.mass)*(this._velocity1>0?1:-1),this._average=.5*(this._newVelocity1+this._newVelocity2),this._newVelocity1-=this._average,this._newVelocity2-=this._average,a.velocity.z=this._average+this._newVelocity1*a.bounce.z,b.velocity.z=this._average+this._newVelocity2*b.bounce.z),!0)):!1)},distanceBetween:function(a,b){return this._dx=a.x-b.x,this._dy=a.y-b.y,this._dz=a.z-b.z,Math.sqrt(this._dx*this._dx+this._dy*this._dy+this._dz*this._dz)},distanceToXY:function(a,b,c){return this._dx=a.x-b,this._dy=a.y-c,Math.sqrt(this._dx*this._dx+this._dy*this._dy)},distanceToXYZ:function(a,b,c,d){return this._dx=a.x-b,this._dy=a.y-c,this._dz=a.y-d,Math.sqrt(this._dx*this._dx+this._dy*this._dy+this._dz*this._dz)}},Phaser.Physics.prototype.isoArcade=null,Phaser.Physics.prototype.parseConfig=function(a){return function(){return this.config.hasOwnProperty("isoArcade")&&this.config.isoArcade===!0&&Phaser.Plugin.Isometric.hasOwnProperty("IsoArcade")&&(this.isoArcade=new Phaser.Plugin.Isometric(this.game,this.config)),a.call(this)}}(Phaser.Physics.prototype.parseConfig),Phaser.Physics.prototype.startSystem=function(a){return function(b){return b===Phaser.Plugin.Isometric.ISOARCADE&&null===this.isoArcade&&(this.isoArcade=new Phaser.Plugin.Isometric.Arcade(this.game),this.setBoundsToWorld()),a.call(this,b)}}(Phaser.Physics.prototype.startSystem),Phaser.Physics.prototype.enable=function(a){return function(b,c){return c===Phaser.Plugin.Isometric.ISOARCADE&&this.isoArcade&&this.isoArcade.enable(b),a.call(this,b,c)}}(Phaser.Physics.prototype.enable),Phaser.Physics.prototype.setBoundsToWorld=function(a){return function(){return this.isoArcade&&this.isoArcade.setBoundsToWorld(),a.call(this)}}(Phaser.Physics.prototype.setBoundsToWorld),Phaser.Physics.prototype.destroy=function(a){return function(){return this.isoArcade=null,a.call(this)}}(Phaser.Physics.prototype.destroy); \ No newline at end of file diff --git a/doc/Body.js.html b/doc/Body.js.html index 0083748..81648f6 100644 --- a/doc/Body.js.html +++ b/doc/Body.js.html @@ -82,11 +82,12 @@
/**
+ * @class Phaser.Plugin.Isometric.Body
+ * 
+ * @classdesc
  * The Physics Body is linked to a single IsoSprite. All physics operations should be performed against the body rather than
  * the IsoSprite itself. For example you can set the velocity, acceleration, bounce values etc all on the Body.
- *
- * @class Phaser.Plugin.Isometric.Body
- * @classdesc IsoArcade Physics Body Constructor
+ * 
  * @constructor
  * @param {Phaser.Plugin.Isometric.IsoSprite} sprite - The IsoSprite object this physics body belongs to.
  */
@@ -795,7 +796,7 @@ Phaser.Plugin.Isometric.Body.prototype = {
 
         this.position.x = x + ((this.widthX * -this.sprite.anchor.x) + this.widthX * 0.5) + this.offset.x;
         this.position.y = y + ((this.widthY * this.sprite.anchor.x) - this.widthY * 0.5) + this.offset.y;
-        this.position.z = z - ((this.height * -this.sprite.anchor.y * 2) + this.height) + this.offset.z;
+        this.position.z = z - (Math.abs(this.sprite.height) * (1 - this.sprite.anchor.y)) + (Math.abs(this.sprite.width * 0.5)) + this.offset.z;
 
         this.prev.x = this.position.x;
         this.prev.y = this.position.y;
@@ -809,6 +810,8 @@ Phaser.Plugin.Isometric.Body.prototype = {
 
         this.center.setTo(this.position.x + this.halfWidthX, this.position.y + this.halfWidthY, this.position.z + this.halfHeight);
 
+        this.sprite._isoPositionChanged = true;
+
     },
 
     /**
@@ -1173,395 +1176,6 @@ Phaser.Plugin.Isometric.Body.renderBodyInfo = function (debug, body) {
 
 Phaser.Plugin.Isometric.Body.prototype.constructor = Phaser.Plugin.Isometric.Body;
 
-/**
- * Octree Constructor
- *
- * @class Phaser.Plugin.Isometric.Octree
- * @classdesc A Octree implementation. The original code was a conversion of the Java code posted to GameDevTuts.
- * However I've tweaked it massively to add node indexing, removed lots of temp. var creation and significantly increased performance as a result.
- * Original version at https://github.com/timohausmann/quadtree-js/
- * @constructor
- * @param {number} x - The bottom-back coordinate of the octree.
- * @param {number} y - The bottom-back coordinate of the octree.
- * @param {number} z - The bottom-back coordinate of the octree.
- * @param {number} widthX - The width X (breadth) of the octree.
- * @param {number} widthY - The width Y (depth) of the octree.
- * @param {number} height - The height (Z) of the octree.
- * @param {number} [maxObjects=10] - The maximum number of objects per node.
- * @param {number} [maxLevels=4] - The maximum number of levels to iterate to.
- * @param {number} [level=0] - Which level is this?
- */
-Phaser.Plugin.Isometric.Octree = function (x, y, z, widthX, widthY, height, maxObjects, maxLevels, level) {
-
-    /**
-     * @property {number} maxObjects - The maximum number of objects per node.
-     * @default
-     */
-    this.maxObjects = 10;
-
-    /**
-     * @property {number} maxLevels - The maximum number of levels to break down to.
-     * @default
-     */
-    this.maxLevels = 4;
-
-    /**
-     * @property {number} level - The current level.
-     */
-    this.level = 0;
-
-    /**
-     * @property {object} bounds - Object that contains the octree bounds.
-     */
-    this.bounds = {};
-
-    /**
-     * @property {array} objects - Array of octree children.
-     */
-    this.objects = [];
-
-    /**
-     * @property {array} nodes - Array of associated child nodes.
-     */
-    this.nodes = [];
-
-    /**
-     * @property {array} _empty - Internal empty array.
-     * @private
-     */
-    this._empty = [];
-
-    this.reset(x, y, z, widthX, widthY, height, maxObjects, maxLevels, level);
-
-};
-
-Phaser.Plugin.Isometric.Octree.prototype = {
-
-    /**
-     * Resets the QuadTree.
-     *
-     * @method Phaser.Plugin.Isometric.Octree#reset
-     * @param {number} x - The bottom-back coordinate of the octree.
-     * @param {number} y - The bottom-back coordinate of the octree.
-     * @param {number} z - The bottom-back coordinate of the octree.
-     * @param {number} widthX - The width X (breadth) of the octree.
-     * @param {number} widthY - The width Y (depth) of the octree.
-     * @param {number} height - The height (Z) of the octree.
-     * @param {number} [maxObjects=10] - The maximum number of objects per node.
-     * @param {number} [maxLevels=4] - The maximum number of levels to iterate to.
-     * @param {number} [level=0] - Which level is this?
-     */
-    reset: function (x, y, z, widthX, widthY, height, maxObjects, maxLevels, level) {
-
-        this.maxObjects = maxObjects || 10;
-        this.maxLevels = maxLevels || 4;
-        this.level = level || 0;
-
-        this.bounds = {
-            x: Math.round(x),
-            y: Math.round(y),
-            z: Math.round(z),
-            widthX: widthX,
-            widthY: widthY,
-            height: height,
-            subWidthX: Math.floor(widthX * 0.5),
-            subWidthY: Math.floor(widthY * 0.5),
-            subHeight: Math.floor(height * 0.5),
-            frontX: Math.round(x) + Math.floor(widthX * 0.5),
-            frontY: Math.round(y) + Math.floor(widthY * 0.5),
-            top: Math.round(z) + Math.floor(height * 0.5)
-        };
-
-        this.objects.length = 0;
-        this.nodes.length = 0;
-
-    },
-
-    /**
-     * Populates this octree with the children of the given Group. In order to be added the child must exist and have a body property.
-     *
-     * @method Phaser.Plugin.Isometric.Octree#populate
-     * @param {Phaser.Group} group - The Group to add to the octree.
-     */
-    populate: function (group) {
-
-        group.forEach(this.populateHandler, this, true);
-
-    },
-
-    /**
-     * Handler for the populate method.
-     *
-     * @method Phaser.Plugin.Isometric.Octree#populateHandler
-     * @param {Phaser.Plugin.Isometric.IsoSprite|object} sprite - The Sprite to check.
-     */
-    populateHandler: function (sprite) {
-
-        if (sprite.body && sprite.exists) {
-            this.insert(sprite.body);
-        }
-
-    },
-
-    /**
-     * Split the node into 8 subnodes
-     *
-     * @method Phaser.Plugin.Isometric.Octree#split
-     */
-    split: function () {
-
-        //  bottom four octants
-        //  -x-y-z
-        this.nodes[0] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.y, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1));
-        //  +x-y-z
-        this.nodes[1] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.y, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1));
-        //  -x+y-z
-        this.nodes[2] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.frontY, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1));
-        //  +x+y-z
-        this.nodes[3] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.frontY, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1));
-
-        //  top four octants
-        //  -x-y+z
-        this.nodes[4] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.y, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1));
-        //  +x-y+z
-        this.nodes[5] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.y, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1));
-        //  -x+y+z
-        this.nodes[6] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.frontY, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1));
-        //  +x+y+z
-        this.nodes[7] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.frontY, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1));
-    },
-
-    /**
-     * Insert the object into the node. If the node exceeds the capacity, it will split and add all objects to their corresponding subnodes.
-     *
-     * @method Phaser.Plugin.Isometric.Octree#insert
-     * @param {Phaser.Plugin.Isometric.Body|Phaser.Plugin.Isometric.Cube|object} body - The Body object to insert into the octree. Can be any object so long as it exposes x, y, z, frontX, frontY and top properties.
-     */
-    insert: function (body) {
-
-        var i = 0;
-        var index;
-
-        //  if we have subnodes ...
-        if (this.nodes[0] !== null) {
-            index = this.getIndex(body);
-
-            if (index !== -1) {
-                this.nodes[index].insert(body);
-                return;
-            }
-        }
-
-        this.objects.push(body);
-
-        if (this.objects.length > this.maxObjects && this.level < this.maxLevels) {
-            //  Split if we don't already have subnodes
-            if (this.nodes[0] === null) {
-                this.split();
-            }
-
-            //  Add objects to subnodes
-            while (i < this.objects.length) {
-                index = this.getIndex(this.objects[i]);
-
-                if (index !== -1) {
-                    //  this is expensive - see what we can do about it
-                    this.nodes[index].insert(this.objects.splice(i, 1)[0]);
-                } else {
-                    i++;
-                }
-            }
-        }
-
-    },
-
-    /**
-     * Determine which node the object belongs to.
-     *
-     * @method Phaser.Plugin.Isometric.Octree#getIndex
-     * @param {Phaser.Plugin.Isometric.Cube|object} cube - The bounds in which to check.
-     * @return {number} index - Index of the subnode (0-7), or -1 if cube cannot completely fit within a subnode and is part of the parent node.
-     */
-    getIndex: function (cube) {
-
-        //  default is that cube doesn't fit, i.e. it straddles the internal octants
-        var index = -1;
-
-        if (cube.x < this.bounds.frontX && cube.frontX < this.bounds.frontX) {
-            if (cube.y < this.bounds.frontY && cube.frontY < this.bounds.frontY) {
-                if (cube.z < this.bounds.top && cube.top < this.bounds.top) {
-                    //  cube fits into -x-y-z octant
-                    index = 0;
-                } else if (cube.z > this.bounds.top) {
-                    //  cube fits into -x-y+z octant
-                    index = 4;
-                }
-            } else if (cube.y > this.bounds.frontY) {
-                if (cube.z < this.bounds.top && cube.top < this.bounds.top) {
-                    //  cube fits into -x+y-z octant
-                    index = 2;
-                } else if (cube.z > this.bounds.top) {
-                    //  cube fits into -x+y+z octant
-                    index = 6;
-                }
-            }
-        } else if (cube.x > this.bounds.frontX) {
-            if (cube.y < this.bounds.frontY && cube.frontY < this.bounds.frontY) {
-                if (cube.z < this.bounds.top && cube.top < this.bounds.top) {
-                    //  cube fits into +x-y-z octant
-                    index = 1;
-                } else if (cube.z > this.bounds.top) {
-                    //  cube fits into +x-y+z octant
-                    index = 5;
-                }
-            } else if (cube.y > this.bounds.frontY) {
-                if (cube.z < this.bounds.top && cube.top < this.bounds.top) {
-                    //  cube fits into +x+y-z octant
-                    index = 3;
-                } else if (cube.z > this.bounds.top) {
-                    //  cube fits into +x+y+z octant
-                    index = 7;
-                }
-            }
-        }
-
-
-        return index;
-
-    },
-
-    /**
-     * Return all objects that could collide with the given IsoSprite or Cube.
-     *
-     * @method Phaser.Plugin.Isometric.Octree#retrieve
-     * @param {Phaser.Plugin.Isometric.IsoSprite|Phaser.Plugin.Isometric.Cube} source - The source object to check the Octree against. Either a IsoSprite or Cube.
-     * @return {array} - Array with all detected objects.
-     */
-    retrieve: function (source) {
-
-        var returnObjects, index;
-
-        if (source instanceof Phaser.Plugin.Isometric.Cube) {
-            returnObjects = this.objects;
-
-            index = this.getIndex(source);
-        } else {
-            if (!source.body) {
-                return this._empty;
-            }
-
-            returnObjects = this.objects;
-
-            index = this.getIndex(source.body);
-        }
-
-        if (this.nodes[0]) {
-            //  If cube fits into a subnode ..
-            if (index !== -1) {
-                returnObjects = returnObjects.concat(this.nodes[index].retrieve(source));
-            } else {
-                //  If cube does not fit into a subnode, check it against all subnodes (unrolled for speed)
-                returnObjects = returnObjects.concat(this.nodes[0].retrieve(source));
-                returnObjects = returnObjects.concat(this.nodes[1].retrieve(source));
-                returnObjects = returnObjects.concat(this.nodes[2].retrieve(source));
-                returnObjects = returnObjects.concat(this.nodes[3].retrieve(source));
-                returnObjects = returnObjects.concat(this.nodes[4].retrieve(source));
-                returnObjects = returnObjects.concat(this.nodes[5].retrieve(source));
-                returnObjects = returnObjects.concat(this.nodes[6].retrieve(source));
-                returnObjects = returnObjects.concat(this.nodes[7].retrieve(source));
-            }
-        }
-
-        return returnObjects;
-
-    },
-
-    /**
-     * Clear the octree.
-     * @method Phaser.Plugin.Isometric.Octree#clear
-     */
-    clear: function () {
-
-        this.objects.length = 0;
-
-        var i = this.nodes.length;
-
-        while (i--) {
-            this.nodes[i].clear();
-            this.nodes.splice(i, 1);
-        }
-
-        this.nodes.length = 0;
-    }
-
-};
-
-Phaser.Plugin.Isometric.Octree.prototype.constructor = Phaser.Plugin.Isometric.Octree;
-
-/**
- * Visually renders an Octree to the display.
- *
- * @method Phaser.Utils.Debug#octree
- * @param {Phaser.Plugin.Isometric.Octree} octree - The octree to render.
- * @param {string} color - The color of the lines in the quadtree.
- */
-Phaser.Utils.Debug.prototype.octree = function (octree, color) {
-
-    color = color || 'rgba(255,0,0,0.3)';
-
-    this.start();
-
-    var bounds = octree.bounds,
-        i, points;
-
-    if (octree.nodes.length === 0) {
-
-        this.context.strokeStyle = color;
-
-        var cube = new Phaser.Plugin.Isometric.Cube(bounds.x, bounds.y, bounds.z, bounds.widthX, bounds.widthY, bounds.height);
-        var corners = cube.getCorners();
-
-        points = corners.slice(0, corners.length);
-        points = points.map(function (p) {
-            return this.game.iso.project(p);
-        });
-
-        this.context.moveTo(points[0].x, points[0].y);
-        this.context.beginPath();
-        this.context.strokeStyle = color;
-
-        this.context.lineTo(points[1].x, points[1].y);
-        this.context.lineTo(points[3].x, points[3].y);
-        this.context.lineTo(points[2].x, points[2].y);
-        this.context.lineTo(points[6].x, points[6].y);
-        this.context.lineTo(points[4].x, points[4].y);
-        this.context.lineTo(points[5].x, points[5].y);
-        this.context.lineTo(points[1].x, points[1].y);
-        this.context.lineTo(points[0].x, points[0].y);
-        this.context.lineTo(points[4].x, points[4].y);
-        this.context.moveTo(points[0].x, points[0].y);
-        this.context.lineTo(points[2].x, points[2].y);
-        this.context.moveTo(points[3].x, points[3].y);
-        this.context.lineTo(points[7].x, points[7].y);
-        this.context.lineTo(points[6].x, points[6].y);
-        this.context.moveTo(points[7].x, points[7].y);
-        this.context.lineTo(points[5].x, points[5].y);
-        this.context.stroke();
-        this.context.closePath();
-
-        for (i = 0; i < octree.objects.length; i++) {
-            this.body(octree.objects[i].sprite, 'rgb(0,255,0)', false);
-        }
-    } else {
-        for (i = 0; i < octree.nodes.length; i++) {
-            this.octree(octree.nodes[i]);
-        }
-    }
-
-    this.stop();
-
-};
-
 Phaser.Utils.Debug.prototype.body = (function (_super) {
 
     return function (sprite, color, filled) {
@@ -1610,7 +1224,7 @@ Phaser.Utils.Debug.prototype.bodyInfo = (function (_super) {
 					
 		
 		Documentation generated by JSDoc 3.2.2
-		on Wed Aug 6th 2014 using the DocStrap template.
 		
 				
diff --git a/doc/Cube.js.html b/doc/Cube.js.html
index 59062a1..1fab372 100644
--- a/doc/Cube.js.html
+++ b/doc/Cube.js.html
@@ -82,9 +82,11 @@
 	
/**
- * Creates a new Cube object with the bottom-back corner specified by the x, y and z parameters, with the specified breadth (widthX), depth (widthY) and height parameters. If you call this function without parameters, a Cube with x, y, z, breadth, depth and height properties set to 0 is created.
- *
  * @class Phaser.Plugin.Isometric.Cube
+ * 
+ * @classdesc
+ * Creates a new Cube object with the bottom-back corner specified by the x, y and z parameters, with the specified breadth (widthX), depth (widthY) and height parameters. If you call this function without parameters, a Cube with x, y, z, breadth, depth and height properties set to 0 is created.
+ * 
  * @constructor
  * @param {number} x - The x coordinate of the bottom-back corner of the Cube.
  * @param {number} y - The y coordinate of the bottom-back corner of the Cube.
@@ -690,7 +692,7 @@ Phaser.Plugin.Isometric.Cube.intersects = function (a, b) {
 					
 		
 		Documentation generated by JSDoc 3.2.2
-		on Wed Aug 6th 2014 using the DocStrap template.
 		
 				
diff --git a/doc/IsoSprite.js.html b/doc/IsoSprite.js.html
index 9083892..0ab7dd1 100644
--- a/doc/IsoSprite.js.html
+++ b/doc/IsoSprite.js.html
@@ -82,13 +82,26 @@
 	
/**
- * Phaser IsoSprite constructor
- * @class Phaser.Plugin.Isometric.IsoSprite
- * @constructor
+* @class Phaser.Plugin.Isometric.IsoSprite
+*
+* @classdesc
+* Create a new `IsoSprite` object. IsoSprites are extended versions of standard Sprites that are suitable for axonometric positioning.
+*
+* IsoSprites are simply Sprites that have three new position properties (isoX, isoY and isoZ) and ask the instance of Phaser.Plugin.Isometric.Projector what their position should be in a 2D scene whenever these properties are changed.
+* The IsoSprites retain their 2D position property to prevent any problems and allow you to interact with them as you would a normal Sprite. The upside of this simplicity is that things should behave predictably for those already used to Phaser.
+* 
+* @constructor
+* @extends Phaser.Sprite
+* @param {Phaser.Game} game - A reference to the currently running game.
+* @param {number} x - The x coordinate (in 3D space) to position the IsoSprite at.
+* @param {number} y - The y coordinate (in 3D space) to position the IsoSprite at.
+* @param {number} z - The z coordinate (in 3D space) to position the IsoSprite at.
+* @param {string|Phaser.RenderTexture|Phaser.BitmapData|PIXI.Texture} key - This is the image or texture used by the IsoSprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture.
+* @param {string|number} frame - If this IsoSprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index.
  */
-Phaser.Plugin.Isometric.IsoSprite = function (game, x, y, z, key, frame, parent) {
+Phaser.Plugin.Isometric.IsoSprite = function (game, x, y, z, key, frame) {
 
-    Phaser.Sprite.call(this, game, x, y, key, frame, parent);
+    Phaser.Sprite.call(this, game, x, y, key, frame);
 
     /**
      * @property {number} type - The const type of this object.
@@ -103,7 +116,7 @@ Phaser.Plugin.Isometric.IsoSprite = function (game, x, y, z, key, frame, parent)
     this._isoPosition = new Phaser.Plugin.Isometric.Point3(x, y, z);
 
     /**
-     * @property {number} snap - Snap this IsoSprite's position to this value; handy for keeping pixel art snapped to whole pixels.
+     * @property {number} snap - Snap this IsoSprite's position to the specified value; handy for keeping pixel art snapped to whole pixels.
      * @default
      */
     this.snap = 0;
@@ -111,18 +124,21 @@ Phaser.Plugin.Isometric.IsoSprite = function (game, x, y, z, key, frame, parent)
     /**
      * @property {number} _depth - Internal cached depth value.
      * @readonly
+     * @private
      */
     this._depth = 0;
 
     /**
      * @property {boolean} _depthChanged - Internal invalidation control for depth management.
      * @readonly
+     * @private
      */
     this._depthChanged = true;
 
     /**
      * @property {boolean} _isoPositionChanged - Internal invalidation control for positioning.
      * @readonly
+     * @private
      */
     this._isoPositionChanged = true;
 
@@ -166,7 +182,7 @@ Phaser.Plugin.Isometric.IsoSprite.prototype._project = function () {
 /**
  * The axonometric position of the IsoSprite on the x axis. Increasing the x coordinate will move the object down and to the right on the screen.
  *
- * @name Phaser.Sprite#isoX
+ * @name Phaser.Plugin.Isometric.IsoSprite#isoX
  * @property {number} isoX - The axonometric position of the IsoSprite on the x axis.
  */
 Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoX", {
@@ -182,7 +198,7 @@ Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoX", {
 /**
  * The axonometric position of the IsoSprite on the y axis. Increasing the y coordinate will move the object down and to the left on the screen.
  *
- * @name Phaser.Sprite#isoY
+ * @name Phaser.Plugin.Isometric.IsoSprite#isoY
  * @property {number} isoY - The axonometric position of the IsoSprite on the y axis.
  */
 Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoY", {
@@ -198,7 +214,7 @@ Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoY", {
 /**
  * The axonometric position of the IsoSprite on the z axis. Increasing the z coordinate will move the object directly upwards on the screen.
  *
- * @name Phaser.Sprite#isoZ
+ * @name Phaser.Plugin.Isometric.IsoSprite#isoZ
  * @property {number} isoZ - The axonometric position of the IsoSprite on the z axis.
  */
 Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoZ", {
@@ -214,7 +230,7 @@ Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoZ", {
 /**
  * A Point3 object representing the axonometric position of the IsoSprite.
  *
- * @name Phaser.Sprite#isoPosition
+ * @name Phaser.Plugin.Isometric.IsoSprite#isoPosition
  * @property {Point3} isoPosition - The axonometric position of the IsoSprite on the z axis.
  * @readonly
  */
@@ -227,14 +243,14 @@ Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoPosition"
 /**
  * The non-unit distance of the IsoSprite from the 'front' of the scene. Used to correctly depth sort a group of IsoSprites.
  *
- * @name Phaser.Sprite#depth
+ * @name Phaser.Plugin.Isometric.IsoSprite#depth
  * @property {number} depth - A calculated value used for depth sorting.
  * @readonly
  */
 Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "depth", {
     get: function () {
         if (this._depthChanged === true) {
-            this._depth = (this._isoPosition.x + this._isoPosition.y) + (this._isoPosition.z * 0.95);
+            this._depth = (this._isoPosition.x + this._isoPosition.y);
             this._depthChanged = false;
         }
         return this._depth;
@@ -302,7 +318,7 @@ Phaser.GameObjectFactory.prototype.isoSprite = function (x, y, z, key, frame, gr
 					
 		
 		Documentation generated by JSDoc 3.2.2
-		on Wed Aug 6th 2014 using the DocStrap template.
 		
 				
diff --git a/doc/Isometric.js.html b/doc/Isometric.js.html
index abee997..9072627 100644
--- a/doc/Isometric.js.html
+++ b/doc/Isometric.js.html
@@ -115,13 +115,14 @@
  */
 
 /**
+ * @class Phaser.Plugin.Isometric
+ * 
+ * @classdesc
  * Isometric is a comprehensive axonometric plugin for Phaser which provides an API for handling axonometric projection of assets in 3D space to the screen.
  * The goal has been to mimic as closely as possible the existing APIs provided by Phaser for standard orthogonal 2D projection, but add a third dimension.
  * Also included is an Arcade-based 3D AABB physics engine, which again is closely equivalent in functionality and its API.
- *
- * @class Phaser.Plugin.Isometric
+ * 
  * @constructor
- *
  * @param {Phaser.Game} game The current game instance.
  */
 Phaser.Plugin.Isometric = function (game, parent) {
@@ -135,7 +136,7 @@ Phaser.Plugin.Isometric = function (game, parent) {
 Phaser.Plugin.Isometric.prototype = Object.create(Phaser.Plugin.prototype);
 Phaser.Plugin.Isometric.prototype.constructor = Phaser.Plugin.Isometric;
 
-Phaser.Plugin.Isometric.VERSION = '0.7.2';
+Phaser.Plugin.Isometric.VERSION = '0.7.3';
 
 //  Directional consts
 Phaser.Plugin.Isometric.UP = 0;
@@ -173,7 +174,7 @@ Phaser.Plugin.Isometric.TRUE = 0.6154797093263624;
 					
 		
 		Documentation generated by JSDoc 3.2.2
-		on Wed Aug 6th 2014 using the DocStrap template.
 		
 				
diff --git a/doc/Octree.js.html b/doc/Octree.js.html
new file mode 100644
index 0000000..fd1656e
--- /dev/null
+++ b/doc/Octree.js.html
@@ -0,0 +1,573 @@
+
+
+
+
+	
+	Phaser Isometric Source: Octree.js
+
+	
+	
+
+	
+
+
+
+
+
+ + +
+ + +
+ +
+ + + +

Source: Octree.js

+ +
+
+
/**
+ * Octree Constructor
+ *
+ * @class Phaser.Plugin.Isometric.Octree
+ * @classdesc A Octree implementation based on Phaser.QuadTree.
+ * Original version at https://github.com/timohausmann/quadtree-js/
+ * 
+ * @constructor
+ * @param {number} x - The bottom-back coordinate of the octree.
+ * @param {number} y - The bottom-back coordinate of the octree.
+ * @param {number} z - The bottom-back coordinate of the octree.
+ * @param {number} widthX - The width X (breadth) of the octree.
+ * @param {number} widthY - The width Y (depth) of the octree.
+ * @param {number} height - The height (Z) of the octree.
+ * @param {number} [maxObjects=10] - The maximum number of objects per node.
+ * @param {number} [maxLevels=4] - The maximum number of levels to iterate to.
+ * @param {number} [level=0] - Which level is this?
+ */
+Phaser.Plugin.Isometric.Octree = function (x, y, z, widthX, widthY, height, maxObjects, maxLevels, level) {
+
+    /**
+     * @property {number} maxObjects - The maximum number of objects per node.
+     * @default
+     */
+    this.maxObjects = 10;
+
+    /**
+     * @property {number} maxLevels - The maximum number of levels to break down to.
+     * @default
+     */
+    this.maxLevels = 4;
+
+    /**
+     * @property {number} level - The current level.
+     */
+    this.level = 0;
+
+    /**
+     * @property {object} bounds - Object that contains the octree bounds.
+     */
+    this.bounds = {};
+
+    /**
+     * @property {array} objects - Array of octree children.
+     */
+    this.objects = [];
+
+    /**
+     * @property {array} nodes - Array of associated child nodes.
+     */
+    this.nodes = [];
+
+    /**
+     * @property {array} _empty - Internal empty array.
+     * @private
+     */
+    this._empty = [];
+
+    this.reset(x, y, z, widthX, widthY, height, maxObjects, maxLevels, level);
+
+};
+
+Phaser.Plugin.Isometric.Octree.prototype = {
+
+    /**
+     * Resets the QuadTree.
+     *
+     * @method Phaser.Plugin.Isometric.Octree#reset
+     * @param {number} x - The bottom-back coordinate of the octree.
+     * @param {number} y - The bottom-back coordinate of the octree.
+     * @param {number} z - The bottom-back coordinate of the octree.
+     * @param {number} widthX - The width X (breadth) of the octree.
+     * @param {number} widthY - The width Y (depth) of the octree.
+     * @param {number} height - The height (Z) of the octree.
+     * @param {number} [maxObjects=10] - The maximum number of objects per node.
+     * @param {number} [maxLevels=4] - The maximum number of levels to iterate to.
+     * @param {number} [level=0] - Which level is this?
+     */
+    reset: function (x, y, z, widthX, widthY, height, maxObjects, maxLevels, level) {
+
+        this.maxObjects = maxObjects || 10;
+        this.maxLevels = maxLevels || 4;
+        this.level = level || 0;
+
+        this.bounds = {
+            x: Math.round(x),
+            y: Math.round(y),
+            z: Math.round(z),
+            widthX: widthX,
+            widthY: widthY,
+            height: height,
+            subWidthX: Math.floor(widthX * 0.5),
+            subWidthY: Math.floor(widthY * 0.5),
+            subHeight: Math.floor(height * 0.5),
+            frontX: Math.round(x) + Math.floor(widthX * 0.5),
+            frontY: Math.round(y) + Math.floor(widthY * 0.5),
+            top: Math.round(z) + Math.floor(height * 0.5)
+        };
+
+        this.objects.length = 0;
+        this.nodes.length = 0;
+
+    },
+
+    /**
+     * Populates this octree with the children of the given Group. In order to be added the child must exist and have a body property.
+     *
+     * @method Phaser.Plugin.Isometric.Octree#populate
+     * @param {Phaser.Group} group - The Group to add to the octree.
+     */
+    populate: function (group) {
+
+        group.forEach(this.populateHandler, this, true);
+
+    },
+
+    /**
+     * Handler for the populate method.
+     *
+     * @method Phaser.Plugin.Isometric.Octree#populateHandler
+     * @param {Phaser.Plugin.Isometric.IsoSprite|object} sprite - The Sprite to check.
+     */
+    populateHandler: function (sprite) {
+
+        if (sprite.body && sprite.exists) {
+            this.insert(sprite.body);
+        }
+
+    },
+
+    /**
+     * Split the node into 8 subnodes
+     *
+     * @method Phaser.Plugin.Isometric.Octree#split
+     */
+    split: function () {
+
+        //  bottom four octants
+        //  -x-y-z
+        this.nodes[0] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.y, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1));
+        //  +x-y-z
+        this.nodes[1] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.y, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1));
+        //  -x+y-z
+        this.nodes[2] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.frontY, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1));
+        //  +x+y-z
+        this.nodes[3] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.frontY, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1));
+
+        //  top four octants
+        //  -x-y+z
+        this.nodes[4] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.y, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1));
+        //  +x-y+z
+        this.nodes[5] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.y, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1));
+        //  -x+y+z
+        this.nodes[6] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.frontY, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1));
+        //  +x+y+z
+        this.nodes[7] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.frontY, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1));
+    },
+
+    /**
+     * Insert the object into the node. If the node exceeds the capacity, it will split and add all objects to their corresponding subnodes.
+     *
+     * @method Phaser.Plugin.Isometric.Octree#insert
+     * @param {Phaser.Plugin.Isometric.Body|Phaser.Plugin.Isometric.Cube|object} body - The Body object to insert into the octree. Can be any object so long as it exposes x, y, z, frontX, frontY and top properties.
+     */
+    insert: function (body) {
+
+        var i = 0;
+        var index;
+
+        //  if we have subnodes ...
+        if (this.nodes[0] !== null) {
+            index = this.getIndex(body);
+
+            if (index !== -1) {
+                this.nodes[index].insert(body);
+                return;
+            }
+        }
+
+        this.objects.push(body);
+
+        if (this.objects.length > this.maxObjects && this.level < this.maxLevels) {
+            //  Split if we don't already have subnodes
+            if (this.nodes[0] === null) {
+                this.split();
+            }
+
+            //  Add objects to subnodes
+            while (i < this.objects.length) {
+                index = this.getIndex(this.objects[i]);
+
+                if (index !== -1) {
+                    //  this is expensive - see what we can do about it
+                    this.nodes[index].insert(this.objects.splice(i, 1)[0]);
+                } else {
+                    i++;
+                }
+            }
+        }
+
+    },
+
+    /**
+     * Determine which node the object belongs to.
+     *
+     * @method Phaser.Plugin.Isometric.Octree#getIndex
+     * @param {Phaser.Plugin.Isometric.Cube|object} cube - The bounds in which to check.
+     * @return {number} index - Index of the subnode (0-7), or -1 if cube cannot completely fit within a subnode and is part of the parent node.
+     */
+    getIndex: function (cube) {
+
+        //  default is that cube doesn't fit, i.e. it straddles the internal octants
+        var index = -1;
+
+        if (cube.x < this.bounds.frontX && cube.frontX < this.bounds.frontX) {
+            if (cube.y < this.bounds.frontY && cube.frontY < this.bounds.frontY) {
+                if (cube.z < this.bounds.top && cube.top < this.bounds.top) {
+                    //  cube fits into -x-y-z octant
+                    index = 0;
+                } else if (cube.z > this.bounds.top) {
+                    //  cube fits into -x-y+z octant
+                    index = 4;
+                }
+            } else if (cube.y > this.bounds.frontY) {
+                if (cube.z < this.bounds.top && cube.top < this.bounds.top) {
+                    //  cube fits into -x+y-z octant
+                    index = 2;
+                } else if (cube.z > this.bounds.top) {
+                    //  cube fits into -x+y+z octant
+                    index = 6;
+                }
+            }
+        } else if (cube.x > this.bounds.frontX) {
+            if (cube.y < this.bounds.frontY && cube.frontY < this.bounds.frontY) {
+                if (cube.z < this.bounds.top && cube.top < this.bounds.top) {
+                    //  cube fits into +x-y-z octant
+                    index = 1;
+                } else if (cube.z > this.bounds.top) {
+                    //  cube fits into +x-y+z octant
+                    index = 5;
+                }
+            } else if (cube.y > this.bounds.frontY) {
+                if (cube.z < this.bounds.top && cube.top < this.bounds.top) {
+                    //  cube fits into +x+y-z octant
+                    index = 3;
+                } else if (cube.z > this.bounds.top) {
+                    //  cube fits into +x+y+z octant
+                    index = 7;
+                }
+            }
+        }
+
+
+        return index;
+
+    },
+
+    /**
+     * Return all objects that could collide with the given IsoSprite or Cube.
+     *
+     * @method Phaser.Plugin.Isometric.Octree#retrieve
+     * @param {Phaser.Plugin.Isometric.IsoSprite|Phaser.Plugin.Isometric.Cube} source - The source object to check the Octree against. Either a IsoSprite or Cube.
+     * @return {array} - Array with all detected objects.
+     */
+    retrieve: function (source) {
+
+        var returnObjects, index;
+
+        if (source instanceof Phaser.Plugin.Isometric.Cube) {
+            returnObjects = this.objects;
+
+            index = this.getIndex(source);
+        } else {
+            if (!source.body) {
+                return this._empty;
+            }
+
+            returnObjects = this.objects;
+
+            index = this.getIndex(source.body);
+        }
+
+        if (this.nodes[0]) {
+            //  If cube fits into a subnode ..
+            if (index !== -1) {
+                returnObjects = returnObjects.concat(this.nodes[index].retrieve(source));
+            } else {
+                //  If cube does not fit into a subnode, check it against all subnodes (unrolled for speed)
+                returnObjects = returnObjects.concat(this.nodes[0].retrieve(source));
+                returnObjects = returnObjects.concat(this.nodes[1].retrieve(source));
+                returnObjects = returnObjects.concat(this.nodes[2].retrieve(source));
+                returnObjects = returnObjects.concat(this.nodes[3].retrieve(source));
+                returnObjects = returnObjects.concat(this.nodes[4].retrieve(source));
+                returnObjects = returnObjects.concat(this.nodes[5].retrieve(source));
+                returnObjects = returnObjects.concat(this.nodes[6].retrieve(source));
+                returnObjects = returnObjects.concat(this.nodes[7].retrieve(source));
+            }
+        }
+
+        return returnObjects;
+
+    },
+
+    /**
+     * Clear the octree.
+     * @method Phaser.Plugin.Isometric.Octree#clear
+     */
+    clear: function () {
+
+        this.objects.length = 0;
+
+        var i = this.nodes.length;
+
+        while (i--) {
+            this.nodes[i].clear();
+            this.nodes.splice(i, 1);
+        }
+
+        this.nodes.length = 0;
+    }
+
+};
+
+Phaser.Plugin.Isometric.Octree.prototype.constructor = Phaser.Plugin.Isometric.Octree;
+
+/**
+ * Visually renders an Octree to the display.
+ *
+ * @method Phaser.Utils.Debug#octree
+ * @param {Phaser.Plugin.Isometric.Octree} octree - The octree to render.
+ * @param {string} color - The color of the lines in the quadtree.
+ */
+Phaser.Utils.Debug.prototype.octree = function (octree, color) {
+
+    color = color || 'rgba(255,0,0,0.3)';
+
+    this.start();
+
+    var bounds = octree.bounds,
+        i, points;
+
+    if (octree.nodes.length === 0) {
+
+        this.context.strokeStyle = color;
+
+        var cube = new Phaser.Plugin.Isometric.Cube(bounds.x, bounds.y, bounds.z, bounds.widthX, bounds.widthY, bounds.height);
+        var corners = cube.getCorners();
+
+        points = corners.slice(0, corners.length);
+        points = points.map(function (p) {
+            return this.game.iso.project(p);
+        });
+
+        this.context.moveTo(points[0].x, points[0].y);
+        this.context.beginPath();
+        this.context.strokeStyle = color;
+
+        this.context.lineTo(points[1].x, points[1].y);
+        this.context.lineTo(points[3].x, points[3].y);
+        this.context.lineTo(points[2].x, points[2].y);
+        this.context.lineTo(points[6].x, points[6].y);
+        this.context.lineTo(points[4].x, points[4].y);
+        this.context.lineTo(points[5].x, points[5].y);
+        this.context.lineTo(points[1].x, points[1].y);
+        this.context.lineTo(points[0].x, points[0].y);
+        this.context.lineTo(points[4].x, points[4].y);
+        this.context.moveTo(points[0].x, points[0].y);
+        this.context.lineTo(points[2].x, points[2].y);
+        this.context.moveTo(points[3].x, points[3].y);
+        this.context.lineTo(points[7].x, points[7].y);
+        this.context.lineTo(points[6].x, points[6].y);
+        this.context.moveTo(points[7].x, points[7].y);
+        this.context.lineTo(points[5].x, points[5].y);
+        this.context.stroke();
+        this.context.closePath();
+
+        for (i = 0; i < octree.objects.length; i++) {
+            this.body(octree.objects[i].sprite, 'rgb(0,255,0)', false);
+        }
+    } else {
+        for (i = 0; i < octree.nodes.length; i++) {
+            this.octree(octree.nodes[i]);
+        }
+    }
+
+    this.stop();
+
+};
+
+
+
+ + + + + +
+ +
+
+ + + + Copyright © 2014 Lewis Lane - Rotates.org + +
+ + + Documentation generated by JSDoc 3.2.2 + on Thu Aug 7th 2014 using the DocStrap template. + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + diff --git a/doc/Phaser.Plugin.Isometric.Arcade.html b/doc/Phaser.Plugin.Isometric.Arcade.html index f6802f4..852fc5b 100644 --- a/doc/Phaser.Plugin.Isometric.Arcade.html +++ b/doc/Phaser.Plugin.Isometric.Arcade.html @@ -4091,7 +4091,7 @@ NOTE: This function is not recursive, and will not test against children of obje Documentation generated by JSDoc 3.2.2 - on Wed Aug 6th 2014 using the DocStrap template. diff --git a/doc/Phaser.Plugin.Isometric.Body.html b/doc/Phaser.Plugin.Isometric.Body.html index 98e840e..f95fc8c 100644 --- a/doc/Phaser.Plugin.Isometric.Body.html +++ b/doc/Phaser.Plugin.Isometric.Body.html @@ -86,7 +86,8 @@ Body -

IsoArcade Physics Body Constructor

+

The Physics Body is linked to a single IsoSprite. All physics operations should be performed against the body rather than +the IsoSprite itself. For example you can set the velocity, acceleration, bounce values etc all on the Body.

@@ -104,11 +105,6 @@
-
-

The Physics Body is linked to a single IsoSprite. All physics operations should be performed against the body rather than -the IsoSprite itself. For example you can set the velocity, acceleration, bounce values etc all on the Body.

-
- @@ -193,7 +189,7 @@ the IsoSprite itself. For example you can set the velocity, acceleration, bounce
@@ -328,7 +324,7 @@ the IsoSprite itself. For example you can set the velocity, acceleration, bounce @@ -444,7 +440,7 @@ the IsoSprite itself. For example you can set the velocity, acceleration, bounce @@ -560,7 +556,7 @@ the IsoSprite itself. For example you can set the velocity, acceleration, bounce @@ -669,7 +665,7 @@ the IsoSprite itself. For example you can set the velocity, acceleration, bounce @@ -785,7 +781,7 @@ the IsoSprite itself. For example you can set the velocity, acceleration, bounce @@ -901,7 +897,7 @@ the IsoSprite itself. For example you can set the velocity, acceleration, bounce @@ -1017,7 +1013,7 @@ the IsoSprite itself. For example you can set the velocity, acceleration, bounce @@ -1131,7 +1127,7 @@ For example if blocked.up is true then the Body cannot move up.

@@ -1240,7 +1236,7 @@ For example if blocked.up is true then the Body cannot move up.

@@ -1349,7 +1345,7 @@ For example if blocked.up is true then the Body cannot move up.

@@ -1458,7 +1454,7 @@ For example if blocked.up is true then the Body cannot move up.

@@ -1572,7 +1568,7 @@ For example checkCollision.up = false means it won't collide when the collision @@ -1685,7 +1681,7 @@ For example checkCollision.up = false means it won't collide when the collision @@ -1806,7 +1802,7 @@ Used in combination with your own collision processHandler you can create whatev @@ -1927,7 +1923,7 @@ Used in combination with your own collision processHandler you can create whatev @@ -2048,7 +2044,7 @@ Used in combination with your own collision processHandler you can create whatev @@ -2157,7 +2153,7 @@ Used in combination with your own collision processHandler you can create whatev @@ -2266,7 +2262,7 @@ Used in combination with your own collision processHandler you can create whatev @@ -2379,7 +2375,7 @@ Used in combination with your own collision processHandler you can create whatev @@ -2495,7 +2491,7 @@ Used in combination with your own collision processHandler you can create whatev @@ -2604,7 +2600,7 @@ Used in combination with your own collision processHandler you can create whatev @@ -2713,7 +2709,7 @@ Used in combination with your own collision processHandler you can create whatev @@ -2822,7 +2818,7 @@ Used in combination with your own collision processHandler you can create whatev @@ -2931,7 +2927,7 @@ Used in combination with your own collision processHandler you can create whatev @@ -3040,7 +3036,7 @@ Used in combination with your own collision processHandler you can create whatev @@ -3149,7 +3145,7 @@ Used in combination with your own collision processHandler you can create whatev @@ -3258,7 +3254,7 @@ Used in combination with your own collision processHandler you can create whatev @@ -3367,7 +3363,7 @@ Used in combination with your own collision processHandler you can create whatev @@ -3476,7 +3472,7 @@ Used in combination with your own collision processHandler you can create whatev @@ -3592,7 +3588,7 @@ Used in combination with your own collision processHandler you can create whatev @@ -3708,7 +3704,7 @@ Used in combination with your own collision processHandler you can create whatev @@ -3824,7 +3820,7 @@ Used in combination with your own collision processHandler you can create whatev @@ -3933,7 +3929,7 @@ Used in combination with your own collision processHandler you can create whatev @@ -4055,7 +4051,7 @@ If you want the physics system to move the body around, then set moves to true.< @@ -4164,7 +4160,7 @@ If you want the physics system to move the body around, then set moves to true.< @@ -4273,7 +4269,7 @@ If you want the physics system to move the body around, then set moves to true.< @@ -4386,7 +4382,7 @@ If you want the physics system to move the body around, then set moves to true.< @@ -4499,7 +4495,7 @@ If you want the physics system to move the body around, then set moves to true.< @@ -4612,7 +4608,7 @@ If you want the physics system to move the body around, then set moves to true.< @@ -4721,7 +4717,7 @@ If you want the physics system to move the body around, then set moves to true.< @@ -4830,7 +4826,7 @@ If you want the physics system to move the body around, then set moves to true.< @@ -4939,7 +4935,7 @@ If you want the physics system to move the body around, then set moves to true.< @@ -5048,7 +5044,7 @@ If you want the physics system to move the body around, then set moves to true.< @@ -5157,7 +5153,7 @@ If you want the physics system to move the body around, then set moves to true.< @@ -5266,7 +5262,7 @@ If you want the physics system to move the body around, then set moves to true.< @@ -5375,7 +5371,7 @@ If you want the physics system to move the body around, then set moves to true.< @@ -5484,7 +5480,7 @@ If you want the physics system to move the body around, then set moves to true.< @@ -5593,7 +5589,7 @@ If you want the physics system to move the body around, then set moves to true.< @@ -5702,7 +5698,7 @@ If you want the physics system to move the body around, then set moves to true.< @@ -5811,7 +5807,7 @@ If you want the physics system to move the body around, then set moves to true.< @@ -5920,7 +5916,7 @@ If you want the physics system to move the body around, then set moves to true.< @@ -6029,7 +6025,7 @@ If you want the physics system to move the body around, then set moves to true.< @@ -6143,7 +6139,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -6252,7 +6248,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -6361,7 +6357,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -6474,7 +6470,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -6583,7 +6579,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -6692,7 +6688,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -6801,7 +6797,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -6910,7 +6906,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -7019,7 +7015,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -7091,7 +7087,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -7167,7 +7163,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -7266,7 +7262,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -7365,7 +7361,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -7464,7 +7460,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -7563,7 +7559,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -7662,7 +7658,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -7761,7 +7757,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -7860,7 +7856,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -7936,7 +7932,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -8130,7 +8126,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -8229,7 +8225,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -8328,7 +8324,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -8427,7 +8423,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -8503,7 +8499,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -8757,7 +8753,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -9007,7 +9003,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -9178,7 +9174,7 @@ touching.up = true means the collision happened to the top of this Body for exam @@ -9476,7 +9472,7 @@ is the position of the Body relative to the center of the Sprite.

@@ -9552,7 +9548,7 @@ is the position of the Body relative to the center of the Sprite.

@@ -9605,7 +9601,7 @@ is the position of the Body relative to the center of the Sprite.

Documentation generated by JSDoc 3.2.2 - on Wed Aug 6th 2014 using the DocStrap template. diff --git a/doc/Phaser.Plugin.Isometric.Cube.html b/doc/Phaser.Plugin.Isometric.Cube.html index da933ef..4bb4c07 100644 --- a/doc/Phaser.Plugin.Isometric.Cube.html +++ b/doc/Phaser.Plugin.Isometric.Cube.html @@ -86,7 +86,7 @@ Cube -

Phaser.Plugin.Isometric.Cube

+

Creates a new Cube object with the bottom-back corner specified by the x, y and z parameters, with the specified breadth (widthX), depth (widthY) and height parameters. If you call this function without parameters, a Cube with x, y, z, breadth, depth and height properties set to 0 is created.

@@ -104,10 +104,6 @@
-
-

Creates a new Cube object with the bottom-back corner specified by the x, y and z parameters, with the specified breadth (widthX), depth (widthY) and height parameters. If you call this function without parameters, a Cube with x, y, z, breadth, depth and height properties set to 0 is created.

-
- @@ -307,7 +303,7 @@
@@ -469,7 +465,7 @@ @@ -582,7 +578,7 @@ @@ -696,7 +692,7 @@ However it does affect the height property, whereas changing the z value does no @@ -809,7 +805,7 @@ However it does affect the height property, whereas changing the z value does no @@ -922,7 +918,7 @@ However it does affect the height property, whereas changing the z value does no @@ -1035,7 +1031,7 @@ However it does affect the height property, whereas changing the z value does no @@ -1149,7 +1145,7 @@ If set to true then all of the Cube properties are set to 0.

@@ -1262,7 +1258,7 @@ If set to true then all of the Cube properties are set to 0.

@@ -1375,7 +1371,7 @@ If set to true then all of the Cube properties are set to 0.

@@ -1484,7 +1480,7 @@ If set to true then all of the Cube properties are set to 0.

@@ -1593,7 +1589,7 @@ If set to true then all of the Cube properties are set to 0.

@@ -1702,7 +1698,7 @@ If set to true then all of the Cube properties are set to 0.

@@ -1811,7 +1807,7 @@ If set to true then all of the Cube properties are set to 0.

@@ -1924,7 +1920,7 @@ If set to true then all of the Cube properties are set to 0.

@@ -2037,7 +2033,7 @@ If set to true then all of the Cube properties are set to 0.

@@ -2150,7 +2146,7 @@ If set to true then all of the Cube properties are set to 0.

@@ -2263,7 +2259,7 @@ If set to true then all of the Cube properties are set to 0.

@@ -2376,7 +2372,7 @@ If set to true then all of the Cube properties are set to 0.

@@ -2485,7 +2481,7 @@ If set to true then all of the Cube properties are set to 0.

@@ -2594,7 +2590,7 @@ If set to true then all of the Cube properties are set to 0.

@@ -2703,7 +2699,7 @@ If set to true then all of the Cube properties are set to 0.

@@ -2812,7 +2808,7 @@ If set to true then all of the Cube properties are set to 0.

@@ -2921,7 +2917,7 @@ If set to true then all of the Cube properties are set to 0.

@@ -3085,7 +3081,7 @@ If set to true then all of the Cube properties are set to 0.

@@ -3298,7 +3294,7 @@ If set to true then all of the Cube properties are set to 0.

@@ -3470,7 +3466,7 @@ A Cube object is said to contain another if the second Cube object falls entirel @@ -3641,7 +3637,7 @@ A Cube object is said to contain another if the second Cube object falls entirel @@ -3813,7 +3809,7 @@ This method checks the x, y, z, widthX, widthY, and height properties of the Cub @@ -4004,7 +4000,7 @@ This method checks the x, y, z, widthX, widthY, and height properties of the Cub @@ -4164,7 +4160,7 @@ This method checks the x, y, z, widthX, widthY, and height properties of the Cub @@ -4308,7 +4304,7 @@ This method checks the x, y, z, widthX, widthY, and height properties of the Cub @@ -4456,7 +4452,7 @@ This method checks the x, y, z, widthX, widthY, and height properties of the Cub @@ -4555,7 +4551,7 @@ This method checks the x, y, z, widthX, widthY, and height properties of the Cub @@ -4704,7 +4700,7 @@ This method checks the x, y, z, widthX, widthY, and height properties of the Cub @@ -4967,7 +4963,7 @@ This method checks the x, y, z, widthX, widthY, and height properties of the Cub @@ -5127,7 +5123,7 @@ This method checks the x, y, z, widthX, widthY, and height properties of the Cub @@ -5226,7 +5222,7 @@ This method checks the x, y, z, widthX, widthY, and height properties of the Cub @@ -5302,7 +5298,7 @@ This method checks the x, y, z, widthX, widthY, and height properties of the Cub Documentation generated by JSDoc 3.2.2 - on Wed Aug 6th 2014 using the DocStrap template. diff --git a/doc/Phaser.Plugin.Isometric.IsoSprite.html b/doc/Phaser.Plugin.Isometric.IsoSprite.html index 2e5b415..7ce3fde 100644 --- a/doc/Phaser.Plugin.Isometric.IsoSprite.html +++ b/doc/Phaser.Plugin.Isometric.IsoSprite.html @@ -86,7 +86,9 @@ IsoSprite -

Phaser.Plugin.Isometric.IsoSprite

+

Create a new IsoSprite object. IsoSprites are extended versions of standard Sprites that are suitable for axonometric positioning.

+

IsoSprites are simply Sprites that have three new position properties (isoX, isoY and isoZ) and ask the instance of Phaser.Plugin.Isometric.Projector what their position should be in a 2D scene whenever these properties are changed. +The IsoSprites retain their 2D position property to prevent any problems and allow you to interact with them as you would a normal Sprite. The upside of this simplicity is that things should behave predictably for those already used to Phaser.

@@ -97,116 +99,23 @@
-

new IsoSprite()

+

new IsoSprite(game, x, y, z, key, frame)

-
-

Phaser IsoSprite constructor

-
- - - -
- +
Parameters:
+ - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - - - -

Members

- -
- -
-

<readonly> _depth

- - -
-
- - - - - -
- - -
Properties:
- -
- - +
@@ -228,7 +137,30 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_depthgame + + +Phaser.Game + + + +

A reference to the currently running game.

x @@ -244,14 +176,121 @@ -

Internal cached depth value.

The x coordinate (in 3D space) to position the IsoSprite at.

y + + +number + + + +

The y coordinate (in 3D space) to position the IsoSprite at.

z + + +number + + + +

The z coordinate (in 3D space) to position the IsoSprite at.

key + + +string +| + +Phaser.RenderTexture +| + +Phaser.BitmapData +| + +PIXI.Texture + + + +

This is the image or texture used by the IsoSprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture.

frame + + +string +| + +number + + + +

If this IsoSprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index.

-
+ + + +
@@ -278,7 +317,7 @@
@@ -291,19 +330,55 @@
+ + + + + + + + + + - + + + + +

Extends

+ +
    +
  • Phaser.Sprite
  • +
+ + + + + + + + + + + +

Members

+ +
-
-

<readonly> _depthChanged

+
+

<readonly> depth

+
+

The non-unit distance of the IsoSprite from the 'front' of the scene. Used to correctly depth sort a group of IsoSprites.

+
+ @@ -337,13 +412,13 @@ - _depthChanged + depth -boolean +number @@ -353,7 +428,7 @@ -

Internal invalidation control for depth management.

+

A calculated value used for depth sorting.

@@ -387,7 +462,7 @@
@@ -406,13 +481,17 @@ -
-

<readonly> _isoPositionChanged

+
+

<readonly> isoPosition

+
+

A Point3 object representing the axonometric position of the IsoSprite.

+
+ @@ -446,13 +525,13 @@ - _isoPositionChanged + isoPosition -boolean +Point3 @@ -462,7 +541,7 @@ -

Internal invalidation control for positioning.

+

The axonometric position of the IsoSprite on the z axis.

@@ -496,7 +575,346 @@ +
+ + + + + + + +
+ + + + + + + +
+

isoX

+ + +
+
+ +
+

The axonometric position of the IsoSprite on the x axis. Increasing the x coordinate will move the object down and to the right on the screen.

+
+ + + + + +
+ + +
Properties:
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
isoX + + +number + + + +

The axonometric position of the IsoSprite on the x axis.

+
+ + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ +
+ + + + + + + +
+ + + +
+ + + +
+

isoY

+ + +
+
+ +
+

The axonometric position of the IsoSprite on the y axis. Increasing the y coordinate will move the object down and to the left on the screen.

+
+ + + + + +
+ + +
Properties:
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
isoY + + +number + + + +

The axonometric position of the IsoSprite on the y axis.

+
+ + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ +
+ + + + + + + +
+ + + +
+ + + +
+

isoZ

+ + +
+
+ +
+

The axonometric position of the IsoSprite on the z axis. Increasing the z coordinate will move the object directly upwards on the screen.

+
+ + + + + +
+ + +
Properties:
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
isoZ + + +number + + + +

The axonometric position of the IsoSprite on the z axis.

+
+ + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+
@@ -571,7 +989,7 @@ -

Snap this IsoSprite's position to this value; handy for keeping pixel art snapped to whole pixels.

+

Snap this IsoSprite's position to the specified value; handy for keeping pixel art snapped to whole pixels.

@@ -612,7 +1030,7 @@
@@ -721,7 +1139,7 @@ @@ -793,7 +1211,7 @@ @@ -846,7 +1264,7 @@ Documentation generated by JSDoc 3.2.2 - on Wed Aug 6th 2014 using the DocStrap template. diff --git a/doc/Phaser.Plugin.Isometric.Octree.html b/doc/Phaser.Plugin.Isometric.Octree.html index 3488dcd..0d80abf 100644 --- a/doc/Phaser.Plugin.Isometric.Octree.html +++ b/doc/Phaser.Plugin.Isometric.Octree.html @@ -86,8 +86,7 @@ Octree -

A Octree implementation. The original code was a conversion of the Java code posted to GameDevTuts. -However I've tweaked it massively to add node indexing, removed lots of temp. var creation and significantly increased performance as a result. +

A Octree implementation based on Phaser.QuadTree. Original version at https://github.com/timohausmann/quadtree-js/

@@ -501,8 +500,8 @@ Original version at https
@@ -636,8 +635,8 @@ Original version at https
@@ -745,8 +744,8 @@ Original version at https
@@ -861,8 +860,8 @@ Original version at https
@@ -977,8 +976,8 @@ Original version at https
@@ -1086,8 +1085,8 @@ Original version at https
@@ -1195,8 +1194,8 @@ Original version at https
@@ -1267,8 +1266,8 @@ Original version at https
@@ -1395,8 +1394,8 @@ Original version at https
@@ -1549,8 +1548,8 @@ Original version at https
@@ -1674,8 +1673,8 @@ Original version at https
@@ -1802,8 +1801,8 @@ Original version at https
@@ -2235,8 +2234,8 @@ Original version at https
@@ -2363,8 +2362,8 @@ Original version at https
@@ -2464,8 +2463,8 @@ Original version at https
@@ -2518,7 +2517,7 @@ Original version at https Documentation generated by JSDoc 3.2.2 - on Wed Aug 6th 2014 using the DocStrap template. diff --git a/doc/Phaser.Plugin.Isometric.Point3.html b/doc/Phaser.Plugin.Isometric.Point3.html index 2c44787..6469d28 100644 --- a/doc/Phaser.Plugin.Isometric.Point3.html +++ b/doc/Phaser.Plugin.Isometric.Point3.html @@ -89,3194 +89,8 @@

The Point3 object represents a location in a three-dimensional coordinate system, where x and y represent the horizontal axes and z represents the vertical axis. The following code creates a point at (0,0,0): -var myPoint = new Phaser.Plugin.Isometric.Point3();

- - - -
-
- - - - -
-

new Point3()

- - -
-
- - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - - - -
- - -
- - - - - - - - - - - - -

Members

- -
- -
-

x

- - -
-
- - - - - -
- - -
Properties:
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
x - - -number - - - -

The x value of the point.

-
- - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - -
- - - -
-

y

- - -
-
- - - - - -
- - -
Properties:
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
y - - -number - - - -

The y value of the point.

-
- - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - -
- - - -
-

z

- - -
-
- - - - - -
- - -
Properties:
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
z - - -number - - - -

The z value of the point.

-
- - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - -
- -
- - - -

Methods

- -
- -
-

add(x, y, z) → {Phaser.Plugin.Isometric.Point3}

- - -
-
- - -
-

Adds the given x, y and z values to this Point3.

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
x - - -number - - - -

The value to add to Point3.x.

y - - -number - - - -

The value to add to Point3.y.

z - - -number - - - -

The value to add to Point3.z.

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

This Point3 object. Useful for chaining method calls.

-
- - - -
-
- Type -
-
- -Phaser.Plugin.Isometric.Point3 - - -
-
- - - - - -
- - - -
-

copyFrom(source) → {Phaser.Plugin.Isometric.Point3}

- - -
-
- - -
-

Copies the x, y and z properties from any given object to this Point3.

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
source - - -any - - - -

The object to copy from.

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

This Point3 object.

-
- - - -
-
- Type -
-
- -Phaser.Plugin.Isometric.Point3 - - -
-
- - - - - -
- - - -
-

copyTo(dest) → {Object}

- - -
-
- - -
-

Copies the x, y and z properties from this Point3 to any given object.

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
dest - - -any - - - -

The object to copy to.

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

The dest object.

-
- - - -
-
- Type -
-
- -Object - - -
-
- - - - - -
- - - -
-

divide(x, y, z) → {Phaser.Plugin.Isometric.Point3}

- - -
-
- - -
-

Divides Point3.x, Point3.y and Point3.z by the given x, y and z values.

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
x - - -number - - - -

The value to divide Point3.x by.

y - - -number - - - -

The value to divide Point3.y by.

z - - -number - - - -

The value to divide Point3.z by.

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

This Point3 object. Useful for chaining method calls.

-
- - - -
-
- Type -
-
- -Phaser.Plugin.Isometric.Point3 - - -
-
- - - - - -
- - - -
-

equals(a) → {boolean}

- - -
-
- - -
-

Determines whether the given object's x/y/z values are equal to this Point3 object.

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
a - - -Phaser.Plugin.Isometric.Point3 -| - -any - - - -

The object to compare with this Point3.

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

A value of true if the x and y points are equal, otherwise false.

-
- - - -
-
- Type -
-
- -boolean - - -
-
- - - - - -
- - - -
-

multiply(x, y, z) → {Phaser.Plugin.Isometric.Point3}

- - -
-
- - -
-

Multiplies Point3.x, Point3.y and Point3.z by the given x and y values. Sometimes known as Scale.

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
x - - -number - - - -

The value to multiply Point3.x by.

y - - -number - - - -

The value to multiply Point3.y by.

z - - -number - - - -

The value to multiply Point3.z by.

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

This Point3 object. Useful for chaining method calls.

-
- - - -
-
- Type -
-
- -Phaser.Plugin.Isometric.Point3 - - -
-
- - - - - -
- - - -
-

set(x, y, z) → {Phaser.Plugin.Isometric.Point3}

- - -
-
- - -
-

Sets the x, y and z values of this Point3 object to the given values. -If you omit the y and z value then the x value will be applied to all three, for example: -Point3.set(2) is the same as Point3.set(2, 2, 2) -If however you set both x and y, but no z, the z value will be set to 0.

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
x - - -number - - - - - - - - - -

The x value of this point.

y - - -number - - - - - - <optional>
- - - - - -

The y value of this point. If not given the x value will be used in its place.

z - - -number - - - - - - <optional>
- - - - - -

The z value of this point. If not given and the y value is also not given, the x value will be used in its place.

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

This Point3 object. Useful for chaining method calls.

-
- - - -
-
- Type -
-
- -Phaser.Plugin.Isometric.Point3 - - -
-
- - - - - -
- - - -
-

setTo(x, y, z) → {Phaser.Plugin.Isometric.Point3}

- - -
-
- - -
-

Sets the x, y and z values of this Point3 object to the given values. -If you omit the y and z value then the x value will be applied to all three, for example: -Point3.setTo(2) is the same as Point3.setTo(2, 2, 2) -If however you set both x and y, but no z, the z value will be set to 0.

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
x - - -number - - - - - - - - - -

The x value of this point.

y - - -number - - - - - - <optional>
- - - - - -

The y value of this point. If not given the x value will be used in its place.

z - - -number - - - - - - <optional>
- - - - - -

The z value of this point. If not given and the y value is also not given, the x value will be used in its place.

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

This Point3 object. Useful for chaining method calls.

-
- - - -
-
- Type -
-
- -Phaser.Plugin.Isometric.Point3 - - -
-
- - - - - -
- - - -
-

subtract(x, y, z) → {Phaser.Plugin.Isometric.Point3}

- - -
-
- - -
-

Subtracts the given x, y and z values from this Point3.

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
x - - -number - - - -

The value to subtract from Point3.x.

y - - -number - - - -

The value to subtract from Point3.y.

z - - -number - - - -

The value to subtract from Point3.z.

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

This Point3 object. Useful for chaining method calls.

-
- - - -
-
- Type -
-
- -Phaser.Plugin.Isometric.Point3 - - -
-
- - - - - -
- - - -
-

<static> add(a, b, out) → {Phaser.Plugin.Isometric.Point3}

- - -
-
- - -
-

Adds the coordinates of two points together to create a new point.

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
a - - -Phaser.Plugin.Isometric.Point3 - - - - - - - - - -

The first Point3 object.

b - - -Phaser.Plugin.Isometric.Point3 - - - - - - - - - -

The second Point3 object.

out - - -Phaser.Plugin.Isometric.Point3 - - - - - - <optional>
- - - - - -

Optional Point3 to store the value in, if not supplied a new Point3 object will be created.

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

The new Point3 object.

-
- - - -
-
- Type -
-
- -Phaser.Plugin.Isometric.Point3 - - -
-
- - - - - -
- - - -
-

<static> divide(a, b, out) → {Phaser.Plugin.Isometric.Point3}

- - -
-
- - -
-

Divides the coordinates of two points to create a new point.

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
a - - -Phaser.Plugin.Isometric.Point3 - - - - - - - - - -

The first Point3 object.

b - - -Phaser.Plugin.Isometric.Point3 - - - - - - - - - -

The second Point3 object.

out - - -Phaser.Plugin.Isometric.Point3 - - - - - - <optional>
- - - - - -

Optional Point3 to store the value in, if not supplied a new Point3 object3 will be created.

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

The new Point3 object.

-
- - - -
-
- Type -
-
- -Phaser.Plugin.Isometric.Point3 - - -
-
- - - - - -
- - - -
-

<static> equals(a, b) → {boolean}

- - -
-
- - -
-

Determines whether the two given Point3 objects are equal. They are considered equal if they have the same x, y and z values.

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
a - - -Phaser.Plugin.Isometric.Point3 - - - -

The first Point3 object.

b - - -Phaser.Plugin.Isometric.Point3 - - - -

The second Point3 object.

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

A value of true if the Points3 are equal, otherwise false.

-
- - - -
-
- Type -
-
- -boolean - - -
-
- - - - - -
- - - -
-

<static> multiply(a, b, out) → {Phaser.Plugin.Isometric.Point3}

- - -
-
- - -
-

Multiplies the coordinates of two points to create a new point.

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
a - - -Phaser.Plugin.Isometric.Point3 - - - - - - - - - -

The first Point3 object.

b - - -Phaser.Plugin.Isometric.Point3 - - - - - - - - - -

The second Point3 object.

out - - -Phaser.Plugin.Isometric.Point3 - - - - - - <optional>
- - - - - -

Optional Point3 to store the value in, if not supplied a new Point3 object will be created.

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

The new Point3 object.

-
- - - -
-
- Type -
-
- -Phaser.Plugin.Isometric.Point3 - - -
-
- - - - - -
- - - -
-

<static> subtract(a, b, out) → {Phaser.Plugin.Isometric.Point3}

- - -
-
- - -
-

Subtracts the coordinates of two points to create a new point.

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
a - - -Phaser.Plugin.Isometric.Point3 - - - - - - - - - -

The first Point3 object.

b - - -Phaser.Plugin.Isometric.Point3 - - - - - - - - - -

The second Point3 object.

out - - -Phaser.Plugin.Isometric.Point3 - - - - - - <optional>
- - - - - -

Optional Point3 to store the value in, if not supplied a new Point3 object will be created.

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

The new Point3 object.

-
- - - -
-
- Type -
-
- -Phaser.Plugin.Isometric.Point3 - - -
-
- - - - - -
- -
- - - - - -
- - - - - - - -

Class: Point3

-
- -
-

- .Isometric. - - Point3 -

+var myPoint = new Phaser.Plugin.Isometric.Point3();

+

Creates a new Point3 object. If you pass no parameters a Point3 is created set to (0, 0, 0).

@@ -3294,10 +108,6 @@ If however you set both x and y, but no z, the z value will be set to 0.

-
-

Creates a new Point3 object. If you pass no parameters a Point3 is created set to (0, 0, 0).

-
- @@ -3480,7 +290,7 @@ If however you set both x and y, but no z, the z value will be set to 0.

@@ -3615,7 +425,7 @@ If however you set both x and y, but no z, the z value will be set to 0.

@@ -3724,7 +534,7 @@ If however you set both x and y, but no z, the z value will be set to 0.

@@ -3833,7 +643,7 @@ If however you set both x and y, but no z, the z value will be set to 0.

@@ -4000,7 +810,7 @@ If however you set both x and y, but no z, the z value will be set to 0.

@@ -4148,7 +958,7 @@ If however you set both x and y, but no z, the z value will be set to 0.

@@ -4296,7 +1106,7 @@ If however you set both x and y, but no z, the z value will be set to 0.

@@ -4490,7 +1300,7 @@ If however you set both x and y, but no z, the z value will be set to 0.

@@ -4641,7 +1451,7 @@ If however you set both x and y, but no z, the z value will be set to 0.

@@ -4835,7 +1645,7 @@ If however you set both x and y, but no z, the z value will be set to 0.

@@ -5062,7 +1872,7 @@ If however you set both x and y, but no z, the z value will be set to 0.

@@ -5289,7 +2099,7 @@ If however you set both x and y, but no z, the z value will be set to 0.

@@ -5483,7 +2293,7 @@ If however you set both x and y, but no z, the z value will be set to 0.

@@ -5705,7 +2515,7 @@ If however you set both x and y, but no z, the z value will be set to 0.

@@ -5927,7 +2737,7 @@ If however you set both x and y, but no z, the z value will be set to 0.

@@ -6098,7 +2908,7 @@ If however you set both x and y, but no z, the z value will be set to 0.

@@ -6320,7 +3130,7 @@ If however you set both x and y, but no z, the z value will be set to 0.

@@ -6542,7 +3352,7 @@ If however you set both x and y, but no z, the z value will be set to 0.

@@ -6618,7 +3428,7 @@ If however you set both x and y, but no z, the z value will be set to 0.

Documentation generated by JSDoc 3.2.2 - on Wed Aug 6th 2014 using the DocStrap template. diff --git a/doc/Phaser.Plugin.Isometric.Projector.html b/doc/Phaser.Plugin.Isometric.Projector.html index 4c4d0c5..d16ad65 100644 --- a/doc/Phaser.Plugin.Isometric.Projector.html +++ b/doc/Phaser.Plugin.Isometric.Projector.html @@ -86,7 +86,7 @@ Projector -

Phaser.Plugin.Isometric.Projector

+

Creates a new Isometric Projector object, which has helpers for projecting x, y and z coordinates into axonometric x and y equivalents.

@@ -104,10 +104,6 @@
-
-

Creates a new Isometric Projector object, which has helpers for projecting x, y and z coordinates into axonometric x and y equivalents.

-
- @@ -215,7 +211,7 @@
@@ -373,7 +369,7 @@ @@ -482,7 +478,7 @@ @@ -591,7 +587,7 @@ @@ -735,7 +731,7 @@ @@ -906,7 +902,7 @@ @@ -982,7 +978,7 @@ Documentation generated by JSDoc 3.2.2 - on Wed Aug 6th 2014 using the DocStrap template. diff --git a/doc/Phaser.Plugin.Isometric.html b/doc/Phaser.Plugin.Isometric.html index 04cc409..77ea6d7 100644 --- a/doc/Phaser.Plugin.Isometric.html +++ b/doc/Phaser.Plugin.Isometric.html @@ -84,7 +84,9 @@ Isometric -

Phaser.Plugin.Isometric

+

Isometric is a comprehensive axonometric plugin for Phaser which provides an API for handling axonometric projection of assets in 3D space to the screen. +The goal has been to mimic as closely as possible the existing APIs provided by Phaser for standard orthogonal 2D projection, but add a third dimension. +Also included is an Arcade-based 3D AABB physics engine, which again is closely equivalent in functionality and its API.

@@ -102,12 +104,6 @@
-
-

Isometric is a comprehensive axonometric plugin for Phaser which provides an API for handling axonometric projection of assets in 3D space to the screen. -The goal has been to mimic as closely as possible the existing APIs provided by Phaser for standard orthogonal 2D projection, but add a third dimension. -Also included is an Arcade-based 3D AABB physics engine, which again is closely equivalent in functionality and its API.

-
- @@ -192,7 +188,7 @@ Also included is an Arcade-based 3D AABB physics engine, which again is closely
@@ -250,9 +246,6 @@ Also included is an Arcade-based 3D AABB physics engine, which again is closely
Point3
-
Point3
-
-
Projector
@@ -287,7 +280,7 @@ Also included is an Arcade-based 3D AABB physics engine, which again is closely Documentation generated by JSDoc 3.2.2 - on Wed Aug 6th 2014 using the DocStrap template. diff --git a/doc/Point3.js.html b/doc/Point3.js.html index edcf269..aa93921 100644 --- a/doc/Point3.js.html +++ b/doc/Point3.js.html @@ -83,14 +83,13 @@
/**
  * @class Phaser.Plugin.Isometric.Point3
+ * 
  * @classdesc
  * The Point3 object represents a location in a three-dimensional coordinate system,
  * where x and y represent the horizontal axes and z represents the vertical axis.
  * The following code creates a point at (0,0,0):
  * `var myPoint = new Phaser.Plugin.Isometric.Point3();`
- */
-
-/**
+ * 
  * Creates a new Point3 object. If you pass no parameters a Point3 is created set to (0, 0, 0).
  *
  * @constructor
@@ -402,7 +401,7 @@ Phaser.Plugin.Isometric.Point3.equals = function (a, b) {
 					
 		
 		Documentation generated by JSDoc 3.2.2
-		on Wed Aug 6th 2014 using the DocStrap template.
 		
 				
diff --git a/doc/Projector.js.html b/doc/Projector.js.html
index 6b8897f..f84319a 100644
--- a/doc/Projector.js.html
+++ b/doc/Projector.js.html
@@ -82,9 +82,11 @@
 	
/**
- * Creates a new Isometric Projector object, which has helpers for projecting x, y and z coordinates into axonometric x and y equivalents.
- *
  * @class Phaser.Plugin.Isometric.Projector
+ * 
+ * @classdesc
+ * Creates a new Isometric Projector object, which has helpers for projecting x, y and z coordinates into axonometric x and y equivalents.
+ * 
  * @constructor
  * @param {Phaser.Game} game - The current game object.
  * @param {number} projectionRatio - The ratio of the axonometric projection.
@@ -178,7 +180,7 @@ Phaser.Plugin.Isometric.Projector.prototype = {
 					
 		
 		Documentation generated by JSDoc 3.2.2
-		on Wed Aug 6th 2014 using the DocStrap template.
 		
 				
diff --git a/doc/World.js.html b/doc/World.js.html
index b35c1d0..f5d730d 100644
--- a/doc/World.js.html
+++ b/doc/World.js.html
@@ -1179,7 +1179,7 @@ Phaser.Physics.prototype.destroy = (function (_super) {
 					
 		
 		Documentation generated by JSDoc 3.2.2
-		on Wed Aug 6th 2014 using the DocStrap template.
 		
 				
diff --git a/doc/classes.list.html b/doc/classes.list.html
index e84a3cb..3d97d14 100644
--- a/doc/classes.list.html
+++ b/doc/classes.list.html
@@ -160,9 +160,6 @@
             
Point3
-
Point3
-
-
Projector
@@ -197,7 +194,7 @@ Documentation generated by JSDoc 3.2.2 - on Wed Aug 6th 2014 using the DocStrap template. diff --git a/doc/index.html b/doc/index.html index b5bc516..49f0144 100644 --- a/doc/index.html +++ b/doc/index.html @@ -118,7 +118,7 @@ Documentation generated by JSDoc 3.2.2 - on Wed Aug 6th 2014 using the DocStrap template. diff --git a/package.json b/package.json new file mode 100644 index 0000000..9e5ebe5 --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "name": "phaser-plugin-isometric", + "version": "0.7.3", + "devDependencies": { + "grunt": "~0.4.5", + "grunt-contrib-clean": "^0.5.0", + "grunt-contrib-jshint": "^0.9.2", + "grunt-contrib-uglify": "^0.4.0", + "grunt-contrib-concat": "^0.4.0", + "grunt-contrib-watch": "*", + "grunt-jsdoc": "~0.5.6" + } +} diff --git a/src/Cube.js b/src/Cube.js index 53a79ad..d53d2db 100644 --- a/src/Cube.js +++ b/src/Cube.js @@ -1,7 +1,9 @@ /** - * Creates a new Cube object with the bottom-back corner specified by the x, y and z parameters, with the specified breadth (widthX), depth (widthY) and height parameters. If you call this function without parameters, a Cube with x, y, z, breadth, depth and height properties set to 0 is created. - * * @class Phaser.Plugin.Isometric.Cube + * + * @classdesc + * Creates a new Cube object with the bottom-back corner specified by the x, y and z parameters, with the specified breadth (widthX), depth (widthY) and height parameters. If you call this function without parameters, a Cube with x, y, z, breadth, depth and height properties set to 0 is created. + * * @constructor * @param {number} x - The x coordinate of the bottom-back corner of the Cube. * @param {number} y - The y coordinate of the bottom-back corner of the Cube. diff --git a/src/IsoSprite.js b/src/IsoSprite.js index 580c8bb..9d7fe73 100644 --- a/src/IsoSprite.js +++ b/src/IsoSprite.js @@ -1,11 +1,24 @@ /** - * Phaser IsoSprite constructor - * @class Phaser.Plugin.Isometric.IsoSprite - * @constructor +* @class Phaser.Plugin.Isometric.IsoSprite +* +* @classdesc +* Create a new `IsoSprite` object. IsoSprites are extended versions of standard Sprites that are suitable for axonometric positioning. +* +* IsoSprites are simply Sprites that have three new position properties (isoX, isoY and isoZ) and ask the instance of Phaser.Plugin.Isometric.Projector what their position should be in a 2D scene whenever these properties are changed. +* The IsoSprites retain their 2D position property to prevent any problems and allow you to interact with them as you would a normal Sprite. The upside of this simplicity is that things should behave predictably for those already used to Phaser. +* +* @constructor +* @extends Phaser.Sprite +* @param {Phaser.Game} game - A reference to the currently running game. +* @param {number} x - The x coordinate (in 3D space) to position the IsoSprite at. +* @param {number} y - The y coordinate (in 3D space) to position the IsoSprite at. +* @param {number} z - The z coordinate (in 3D space) to position the IsoSprite at. +* @param {string|Phaser.RenderTexture|Phaser.BitmapData|PIXI.Texture} key - This is the image or texture used by the IsoSprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture. +* @param {string|number} frame - If this IsoSprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index. */ -Phaser.Plugin.Isometric.IsoSprite = function (game, x, y, z, key, frame, parent) { +Phaser.Plugin.Isometric.IsoSprite = function (game, x, y, z, key, frame) { - Phaser.Sprite.call(this, game, x, y, key, frame, parent); + Phaser.Sprite.call(this, game, x, y, key, frame); /** * @property {number} type - The const type of this object. @@ -20,7 +33,7 @@ Phaser.Plugin.Isometric.IsoSprite = function (game, x, y, z, key, frame, parent) this._isoPosition = new Phaser.Plugin.Isometric.Point3(x, y, z); /** - * @property {number} snap - Snap this IsoSprite's position to this value; handy for keeping pixel art snapped to whole pixels. + * @property {number} snap - Snap this IsoSprite's position to the specified value; handy for keeping pixel art snapped to whole pixels. * @default */ this.snap = 0; @@ -28,18 +41,21 @@ Phaser.Plugin.Isometric.IsoSprite = function (game, x, y, z, key, frame, parent) /** * @property {number} _depth - Internal cached depth value. * @readonly + * @private */ this._depth = 0; /** * @property {boolean} _depthChanged - Internal invalidation control for depth management. * @readonly + * @private */ this._depthChanged = true; /** * @property {boolean} _isoPositionChanged - Internal invalidation control for positioning. * @readonly + * @private */ this._isoPositionChanged = true; @@ -83,7 +99,7 @@ Phaser.Plugin.Isometric.IsoSprite.prototype._project = function () { /** * The axonometric position of the IsoSprite on the x axis. Increasing the x coordinate will move the object down and to the right on the screen. * - * @name Phaser.Sprite#isoX + * @name Phaser.Plugin.Isometric.IsoSprite#isoX * @property {number} isoX - The axonometric position of the IsoSprite on the x axis. */ Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoX", { @@ -99,7 +115,7 @@ Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoX", { /** * The axonometric position of the IsoSprite on the y axis. Increasing the y coordinate will move the object down and to the left on the screen. * - * @name Phaser.Sprite#isoY + * @name Phaser.Plugin.Isometric.IsoSprite#isoY * @property {number} isoY - The axonometric position of the IsoSprite on the y axis. */ Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoY", { @@ -115,7 +131,7 @@ Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoY", { /** * The axonometric position of the IsoSprite on the z axis. Increasing the z coordinate will move the object directly upwards on the screen. * - * @name Phaser.Sprite#isoZ + * @name Phaser.Plugin.Isometric.IsoSprite#isoZ * @property {number} isoZ - The axonometric position of the IsoSprite on the z axis. */ Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoZ", { @@ -131,7 +147,7 @@ Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoZ", { /** * A Point3 object representing the axonometric position of the IsoSprite. * - * @name Phaser.Sprite#isoPosition + * @name Phaser.Plugin.Isometric.IsoSprite#isoPosition * @property {Point3} isoPosition - The axonometric position of the IsoSprite on the z axis. * @readonly */ @@ -144,14 +160,14 @@ Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "isoPosition" /** * The non-unit distance of the IsoSprite from the 'front' of the scene. Used to correctly depth sort a group of IsoSprites. * - * @name Phaser.Sprite#depth + * @name Phaser.Plugin.Isometric.IsoSprite#depth * @property {number} depth - A calculated value used for depth sorting. * @readonly */ Object.defineProperty(Phaser.Plugin.Isometric.IsoSprite.prototype, "depth", { get: function () { if (this._depthChanged === true) { - this._depth = (this._isoPosition.x + this._isoPosition.y) + (this._isoPosition.z * 0.95); + this._depth = (this._isoPosition.x + this._isoPosition.y); this._depthChanged = false; } return this._depth; diff --git a/src/Isometric.js b/src/Isometric.js index 60bf330..a4b7c1b 100644 --- a/src/Isometric.js +++ b/src/Isometric.js @@ -32,13 +32,14 @@ */ /** + * @class Phaser.Plugin.Isometric + * + * @classdesc * Isometric is a comprehensive axonometric plugin for Phaser which provides an API for handling axonometric projection of assets in 3D space to the screen. * The goal has been to mimic as closely as possible the existing APIs provided by Phaser for standard orthogonal 2D projection, but add a third dimension. * Also included is an Arcade-based 3D AABB physics engine, which again is closely equivalent in functionality and its API. - * - * @class Phaser.Plugin.Isometric + * * @constructor - * * @param {Phaser.Game} game The current game instance. */ Phaser.Plugin.Isometric = function (game, parent) { @@ -52,7 +53,7 @@ Phaser.Plugin.Isometric = function (game, parent) { Phaser.Plugin.Isometric.prototype = Object.create(Phaser.Plugin.prototype); Phaser.Plugin.Isometric.prototype.constructor = Phaser.Plugin.Isometric; -Phaser.Plugin.Isometric.VERSION = '0.7.2'; +Phaser.Plugin.Isometric.VERSION = '0.7.3'; // Directional consts Phaser.Plugin.Isometric.UP = 0; diff --git a/src/Octree.js b/src/Octree.js new file mode 100644 index 0000000..f0c5fe7 --- /dev/null +++ b/src/Octree.js @@ -0,0 +1,388 @@ +/** + * Octree Constructor + * + * @class Phaser.Plugin.Isometric.Octree + * @classdesc A Octree implementation based on Phaser.QuadTree. + * Original version at https://github.com/timohausmann/quadtree-js/ + * + * @constructor + * @param {number} x - The bottom-back coordinate of the octree. + * @param {number} y - The bottom-back coordinate of the octree. + * @param {number} z - The bottom-back coordinate of the octree. + * @param {number} widthX - The width X (breadth) of the octree. + * @param {number} widthY - The width Y (depth) of the octree. + * @param {number} height - The height (Z) of the octree. + * @param {number} [maxObjects=10] - The maximum number of objects per node. + * @param {number} [maxLevels=4] - The maximum number of levels to iterate to. + * @param {number} [level=0] - Which level is this? + */ +Phaser.Plugin.Isometric.Octree = function (x, y, z, widthX, widthY, height, maxObjects, maxLevels, level) { + + /** + * @property {number} maxObjects - The maximum number of objects per node. + * @default + */ + this.maxObjects = 10; + + /** + * @property {number} maxLevels - The maximum number of levels to break down to. + * @default + */ + this.maxLevels = 4; + + /** + * @property {number} level - The current level. + */ + this.level = 0; + + /** + * @property {object} bounds - Object that contains the octree bounds. + */ + this.bounds = {}; + + /** + * @property {array} objects - Array of octree children. + */ + this.objects = []; + + /** + * @property {array} nodes - Array of associated child nodes. + */ + this.nodes = []; + + /** + * @property {array} _empty - Internal empty array. + * @private + */ + this._empty = []; + + this.reset(x, y, z, widthX, widthY, height, maxObjects, maxLevels, level); + +}; + +Phaser.Plugin.Isometric.Octree.prototype = { + + /** + * Resets the QuadTree. + * + * @method Phaser.Plugin.Isometric.Octree#reset + * @param {number} x - The bottom-back coordinate of the octree. + * @param {number} y - The bottom-back coordinate of the octree. + * @param {number} z - The bottom-back coordinate of the octree. + * @param {number} widthX - The width X (breadth) of the octree. + * @param {number} widthY - The width Y (depth) of the octree. + * @param {number} height - The height (Z) of the octree. + * @param {number} [maxObjects=10] - The maximum number of objects per node. + * @param {number} [maxLevels=4] - The maximum number of levels to iterate to. + * @param {number} [level=0] - Which level is this? + */ + reset: function (x, y, z, widthX, widthY, height, maxObjects, maxLevels, level) { + + this.maxObjects = maxObjects || 10; + this.maxLevels = maxLevels || 4; + this.level = level || 0; + + this.bounds = { + x: Math.round(x), + y: Math.round(y), + z: Math.round(z), + widthX: widthX, + widthY: widthY, + height: height, + subWidthX: Math.floor(widthX * 0.5), + subWidthY: Math.floor(widthY * 0.5), + subHeight: Math.floor(height * 0.5), + frontX: Math.round(x) + Math.floor(widthX * 0.5), + frontY: Math.round(y) + Math.floor(widthY * 0.5), + top: Math.round(z) + Math.floor(height * 0.5) + }; + + this.objects.length = 0; + this.nodes.length = 0; + + }, + + /** + * Populates this octree with the children of the given Group. In order to be added the child must exist and have a body property. + * + * @method Phaser.Plugin.Isometric.Octree#populate + * @param {Phaser.Group} group - The Group to add to the octree. + */ + populate: function (group) { + + group.forEach(this.populateHandler, this, true); + + }, + + /** + * Handler for the populate method. + * + * @method Phaser.Plugin.Isometric.Octree#populateHandler + * @param {Phaser.Plugin.Isometric.IsoSprite|object} sprite - The Sprite to check. + */ + populateHandler: function (sprite) { + + if (sprite.body && sprite.exists) { + this.insert(sprite.body); + } + + }, + + /** + * Split the node into 8 subnodes + * + * @method Phaser.Plugin.Isometric.Octree#split + */ + split: function () { + + // bottom four octants + // -x-y-z + this.nodes[0] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.y, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); + // +x-y-z + this.nodes[1] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.y, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); + // -x+y-z + this.nodes[2] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.frontY, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); + // +x+y-z + this.nodes[3] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.frontY, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); + + // top four octants + // -x-y+z + this.nodes[4] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.y, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); + // +x-y+z + this.nodes[5] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.y, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); + // -x+y+z + this.nodes[6] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.frontY, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); + // +x+y+z + this.nodes[7] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.frontY, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); + }, + + /** + * Insert the object into the node. If the node exceeds the capacity, it will split and add all objects to their corresponding subnodes. + * + * @method Phaser.Plugin.Isometric.Octree#insert + * @param {Phaser.Plugin.Isometric.Body|Phaser.Plugin.Isometric.Cube|object} body - The Body object to insert into the octree. Can be any object so long as it exposes x, y, z, frontX, frontY and top properties. + */ + insert: function (body) { + + var i = 0; + var index; + + // if we have subnodes ... + if (this.nodes[0] !== null) { + index = this.getIndex(body); + + if (index !== -1) { + this.nodes[index].insert(body); + return; + } + } + + this.objects.push(body); + + if (this.objects.length > this.maxObjects && this.level < this.maxLevels) { + // Split if we don't already have subnodes + if (this.nodes[0] === null) { + this.split(); + } + + // Add objects to subnodes + while (i < this.objects.length) { + index = this.getIndex(this.objects[i]); + + if (index !== -1) { + // this is expensive - see what we can do about it + this.nodes[index].insert(this.objects.splice(i, 1)[0]); + } else { + i++; + } + } + } + + }, + + /** + * Determine which node the object belongs to. + * + * @method Phaser.Plugin.Isometric.Octree#getIndex + * @param {Phaser.Plugin.Isometric.Cube|object} cube - The bounds in which to check. + * @return {number} index - Index of the subnode (0-7), or -1 if cube cannot completely fit within a subnode and is part of the parent node. + */ + getIndex: function (cube) { + + // default is that cube doesn't fit, i.e. it straddles the internal octants + var index = -1; + + if (cube.x < this.bounds.frontX && cube.frontX < this.bounds.frontX) { + if (cube.y < this.bounds.frontY && cube.frontY < this.bounds.frontY) { + if (cube.z < this.bounds.top && cube.top < this.bounds.top) { + // cube fits into -x-y-z octant + index = 0; + } else if (cube.z > this.bounds.top) { + // cube fits into -x-y+z octant + index = 4; + } + } else if (cube.y > this.bounds.frontY) { + if (cube.z < this.bounds.top && cube.top < this.bounds.top) { + // cube fits into -x+y-z octant + index = 2; + } else if (cube.z > this.bounds.top) { + // cube fits into -x+y+z octant + index = 6; + } + } + } else if (cube.x > this.bounds.frontX) { + if (cube.y < this.bounds.frontY && cube.frontY < this.bounds.frontY) { + if (cube.z < this.bounds.top && cube.top < this.bounds.top) { + // cube fits into +x-y-z octant + index = 1; + } else if (cube.z > this.bounds.top) { + // cube fits into +x-y+z octant + index = 5; + } + } else if (cube.y > this.bounds.frontY) { + if (cube.z < this.bounds.top && cube.top < this.bounds.top) { + // cube fits into +x+y-z octant + index = 3; + } else if (cube.z > this.bounds.top) { + // cube fits into +x+y+z octant + index = 7; + } + } + } + + + return index; + + }, + + /** + * Return all objects that could collide with the given IsoSprite or Cube. + * + * @method Phaser.Plugin.Isometric.Octree#retrieve + * @param {Phaser.Plugin.Isometric.IsoSprite|Phaser.Plugin.Isometric.Cube} source - The source object to check the Octree against. Either a IsoSprite or Cube. + * @return {array} - Array with all detected objects. + */ + retrieve: function (source) { + + var returnObjects, index; + + if (source instanceof Phaser.Plugin.Isometric.Cube) { + returnObjects = this.objects; + + index = this.getIndex(source); + } else { + if (!source.body) { + return this._empty; + } + + returnObjects = this.objects; + + index = this.getIndex(source.body); + } + + if (this.nodes[0]) { + // If cube fits into a subnode .. + if (index !== -1) { + returnObjects = returnObjects.concat(this.nodes[index].retrieve(source)); + } else { + // If cube does not fit into a subnode, check it against all subnodes (unrolled for speed) + returnObjects = returnObjects.concat(this.nodes[0].retrieve(source)); + returnObjects = returnObjects.concat(this.nodes[1].retrieve(source)); + returnObjects = returnObjects.concat(this.nodes[2].retrieve(source)); + returnObjects = returnObjects.concat(this.nodes[3].retrieve(source)); + returnObjects = returnObjects.concat(this.nodes[4].retrieve(source)); + returnObjects = returnObjects.concat(this.nodes[5].retrieve(source)); + returnObjects = returnObjects.concat(this.nodes[6].retrieve(source)); + returnObjects = returnObjects.concat(this.nodes[7].retrieve(source)); + } + } + + return returnObjects; + + }, + + /** + * Clear the octree. + * @method Phaser.Plugin.Isometric.Octree#clear + */ + clear: function () { + + this.objects.length = 0; + + var i = this.nodes.length; + + while (i--) { + this.nodes[i].clear(); + this.nodes.splice(i, 1); + } + + this.nodes.length = 0; + } + +}; + +Phaser.Plugin.Isometric.Octree.prototype.constructor = Phaser.Plugin.Isometric.Octree; + +/** + * Visually renders an Octree to the display. + * + * @method Phaser.Utils.Debug#octree + * @param {Phaser.Plugin.Isometric.Octree} octree - The octree to render. + * @param {string} color - The color of the lines in the quadtree. + */ +Phaser.Utils.Debug.prototype.octree = function (octree, color) { + + color = color || 'rgba(255,0,0,0.3)'; + + this.start(); + + var bounds = octree.bounds, + i, points; + + if (octree.nodes.length === 0) { + + this.context.strokeStyle = color; + + var cube = new Phaser.Plugin.Isometric.Cube(bounds.x, bounds.y, bounds.z, bounds.widthX, bounds.widthY, bounds.height); + var corners = cube.getCorners(); + + points = corners.slice(0, corners.length); + points = points.map(function (p) { + return this.game.iso.project(p); + }); + + this.context.moveTo(points[0].x, points[0].y); + this.context.beginPath(); + this.context.strokeStyle = color; + + this.context.lineTo(points[1].x, points[1].y); + this.context.lineTo(points[3].x, points[3].y); + this.context.lineTo(points[2].x, points[2].y); + this.context.lineTo(points[6].x, points[6].y); + this.context.lineTo(points[4].x, points[4].y); + this.context.lineTo(points[5].x, points[5].y); + this.context.lineTo(points[1].x, points[1].y); + this.context.lineTo(points[0].x, points[0].y); + this.context.lineTo(points[4].x, points[4].y); + this.context.moveTo(points[0].x, points[0].y); + this.context.lineTo(points[2].x, points[2].y); + this.context.moveTo(points[3].x, points[3].y); + this.context.lineTo(points[7].x, points[7].y); + this.context.lineTo(points[6].x, points[6].y); + this.context.moveTo(points[7].x, points[7].y); + this.context.lineTo(points[5].x, points[5].y); + this.context.stroke(); + this.context.closePath(); + + for (i = 0; i < octree.objects.length; i++) { + this.body(octree.objects[i].sprite, 'rgb(0,255,0)', false); + } + } else { + for (i = 0; i < octree.nodes.length; i++) { + this.octree(octree.nodes[i]); + } + } + + this.stop(); + +}; diff --git a/src/Point3.js b/src/Point3.js index dbc0814..db20986 100644 --- a/src/Point3.js +++ b/src/Point3.js @@ -1,13 +1,12 @@ /** * @class Phaser.Plugin.Isometric.Point3 + * * @classdesc * The Point3 object represents a location in a three-dimensional coordinate system, * where x and y represent the horizontal axes and z represents the vertical axis. * The following code creates a point at (0,0,0): * `var myPoint = new Phaser.Plugin.Isometric.Point3();` - */ - -/** + * * Creates a new Point3 object. If you pass no parameters a Point3 is created set to (0, 0, 0). * * @constructor diff --git a/src/Projector.js b/src/Projector.js index c121178..903950f 100644 --- a/src/Projector.js +++ b/src/Projector.js @@ -1,7 +1,9 @@ /** - * Creates a new Isometric Projector object, which has helpers for projecting x, y and z coordinates into axonometric x and y equivalents. - * * @class Phaser.Plugin.Isometric.Projector + * + * @classdesc + * Creates a new Isometric Projector object, which has helpers for projecting x, y and z coordinates into axonometric x and y equivalents. + * * @constructor * @param {Phaser.Game} game - The current game object. * @param {number} projectionRatio - The ratio of the axonometric projection. diff --git a/src/physics/Body.js b/src/physics/Body.js index e2bb8b4..0e8daf8 100644 --- a/src/physics/Body.js +++ b/src/physics/Body.js @@ -1,9 +1,10 @@ /** + * @class Phaser.Plugin.Isometric.Body + * + * @classdesc * The Physics Body is linked to a single IsoSprite. All physics operations should be performed against the body rather than * the IsoSprite itself. For example you can set the velocity, acceleration, bounce values etc all on the Body. - * - * @class Phaser.Plugin.Isometric.Body - * @classdesc IsoArcade Physics Body Constructor + * * @constructor * @param {Phaser.Plugin.Isometric.IsoSprite} sprite - The IsoSprite object this physics body belongs to. */ @@ -712,7 +713,7 @@ Phaser.Plugin.Isometric.Body.prototype = { this.position.x = x + ((this.widthX * -this.sprite.anchor.x) + this.widthX * 0.5) + this.offset.x; this.position.y = y + ((this.widthY * this.sprite.anchor.x) - this.widthY * 0.5) + this.offset.y; - this.position.z = z - ((this.height * -this.sprite.anchor.y * 2) + this.height) + this.offset.z; + this.position.z = z - (Math.abs(this.sprite.height) * (1 - this.sprite.anchor.y)) + (Math.abs(this.sprite.width * 0.5)) + this.offset.z; this.prev.x = this.position.x; this.prev.y = this.position.y; @@ -726,6 +727,8 @@ Phaser.Plugin.Isometric.Body.prototype = { this.center.setTo(this.position.x + this.halfWidthX, this.position.y + this.halfWidthY, this.position.z + this.halfHeight); + this.sprite._isoPositionChanged = true; + }, /** @@ -1090,395 +1093,6 @@ Phaser.Plugin.Isometric.Body.renderBodyInfo = function (debug, body) { Phaser.Plugin.Isometric.Body.prototype.constructor = Phaser.Plugin.Isometric.Body; -/** - * Octree Constructor - * - * @class Phaser.Plugin.Isometric.Octree - * @classdesc A Octree implementation. The original code was a conversion of the Java code posted to GameDevTuts. - * However I've tweaked it massively to add node indexing, removed lots of temp. var creation and significantly increased performance as a result. - * Original version at https://github.com/timohausmann/quadtree-js/ - * @constructor - * @param {number} x - The bottom-back coordinate of the octree. - * @param {number} y - The bottom-back coordinate of the octree. - * @param {number} z - The bottom-back coordinate of the octree. - * @param {number} widthX - The width X (breadth) of the octree. - * @param {number} widthY - The width Y (depth) of the octree. - * @param {number} height - The height (Z) of the octree. - * @param {number} [maxObjects=10] - The maximum number of objects per node. - * @param {number} [maxLevels=4] - The maximum number of levels to iterate to. - * @param {number} [level=0] - Which level is this? - */ -Phaser.Plugin.Isometric.Octree = function (x, y, z, widthX, widthY, height, maxObjects, maxLevels, level) { - - /** - * @property {number} maxObjects - The maximum number of objects per node. - * @default - */ - this.maxObjects = 10; - - /** - * @property {number} maxLevels - The maximum number of levels to break down to. - * @default - */ - this.maxLevels = 4; - - /** - * @property {number} level - The current level. - */ - this.level = 0; - - /** - * @property {object} bounds - Object that contains the octree bounds. - */ - this.bounds = {}; - - /** - * @property {array} objects - Array of octree children. - */ - this.objects = []; - - /** - * @property {array} nodes - Array of associated child nodes. - */ - this.nodes = []; - - /** - * @property {array} _empty - Internal empty array. - * @private - */ - this._empty = []; - - this.reset(x, y, z, widthX, widthY, height, maxObjects, maxLevels, level); - -}; - -Phaser.Plugin.Isometric.Octree.prototype = { - - /** - * Resets the QuadTree. - * - * @method Phaser.Plugin.Isometric.Octree#reset - * @param {number} x - The bottom-back coordinate of the octree. - * @param {number} y - The bottom-back coordinate of the octree. - * @param {number} z - The bottom-back coordinate of the octree. - * @param {number} widthX - The width X (breadth) of the octree. - * @param {number} widthY - The width Y (depth) of the octree. - * @param {number} height - The height (Z) of the octree. - * @param {number} [maxObjects=10] - The maximum number of objects per node. - * @param {number} [maxLevels=4] - The maximum number of levels to iterate to. - * @param {number} [level=0] - Which level is this? - */ - reset: function (x, y, z, widthX, widthY, height, maxObjects, maxLevels, level) { - - this.maxObjects = maxObjects || 10; - this.maxLevels = maxLevels || 4; - this.level = level || 0; - - this.bounds = { - x: Math.round(x), - y: Math.round(y), - z: Math.round(z), - widthX: widthX, - widthY: widthY, - height: height, - subWidthX: Math.floor(widthX * 0.5), - subWidthY: Math.floor(widthY * 0.5), - subHeight: Math.floor(height * 0.5), - frontX: Math.round(x) + Math.floor(widthX * 0.5), - frontY: Math.round(y) + Math.floor(widthY * 0.5), - top: Math.round(z) + Math.floor(height * 0.5) - }; - - this.objects.length = 0; - this.nodes.length = 0; - - }, - - /** - * Populates this octree with the children of the given Group. In order to be added the child must exist and have a body property. - * - * @method Phaser.Plugin.Isometric.Octree#populate - * @param {Phaser.Group} group - The Group to add to the octree. - */ - populate: function (group) { - - group.forEach(this.populateHandler, this, true); - - }, - - /** - * Handler for the populate method. - * - * @method Phaser.Plugin.Isometric.Octree#populateHandler - * @param {Phaser.Plugin.Isometric.IsoSprite|object} sprite - The Sprite to check. - */ - populateHandler: function (sprite) { - - if (sprite.body && sprite.exists) { - this.insert(sprite.body); - } - - }, - - /** - * Split the node into 8 subnodes - * - * @method Phaser.Plugin.Isometric.Octree#split - */ - split: function () { - - // bottom four octants - // -x-y-z - this.nodes[0] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.y, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); - // +x-y-z - this.nodes[1] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.y, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); - // -x+y-z - this.nodes[2] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.frontY, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); - // +x+y-z - this.nodes[3] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.frontY, this.bounds.z, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); - - // top four octants - // -x-y+z - this.nodes[4] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.y, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); - // +x-y+z - this.nodes[5] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.y, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); - // -x+y+z - this.nodes[6] = new Phaser.Plugin.Isometric.Octree(this.bounds.x, this.bounds.frontY, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); - // +x+y+z - this.nodes[7] = new Phaser.Plugin.Isometric.Octree(this.bounds.frontX, this.bounds.frontY, this.bounds.top, this.bounds.subWidthX, this.bounds.subWidthY, this.bounds.subHeight, this.maxLevels, (this.level + 1)); - }, - - /** - * Insert the object into the node. If the node exceeds the capacity, it will split and add all objects to their corresponding subnodes. - * - * @method Phaser.Plugin.Isometric.Octree#insert - * @param {Phaser.Plugin.Isometric.Body|Phaser.Plugin.Isometric.Cube|object} body - The Body object to insert into the octree. Can be any object so long as it exposes x, y, z, frontX, frontY and top properties. - */ - insert: function (body) { - - var i = 0; - var index; - - // if we have subnodes ... - if (this.nodes[0] !== null) { - index = this.getIndex(body); - - if (index !== -1) { - this.nodes[index].insert(body); - return; - } - } - - this.objects.push(body); - - if (this.objects.length > this.maxObjects && this.level < this.maxLevels) { - // Split if we don't already have subnodes - if (this.nodes[0] === null) { - this.split(); - } - - // Add objects to subnodes - while (i < this.objects.length) { - index = this.getIndex(this.objects[i]); - - if (index !== -1) { - // this is expensive - see what we can do about it - this.nodes[index].insert(this.objects.splice(i, 1)[0]); - } else { - i++; - } - } - } - - }, - - /** - * Determine which node the object belongs to. - * - * @method Phaser.Plugin.Isometric.Octree#getIndex - * @param {Phaser.Plugin.Isometric.Cube|object} cube - The bounds in which to check. - * @return {number} index - Index of the subnode (0-7), or -1 if cube cannot completely fit within a subnode and is part of the parent node. - */ - getIndex: function (cube) { - - // default is that cube doesn't fit, i.e. it straddles the internal octants - var index = -1; - - if (cube.x < this.bounds.frontX && cube.frontX < this.bounds.frontX) { - if (cube.y < this.bounds.frontY && cube.frontY < this.bounds.frontY) { - if (cube.z < this.bounds.top && cube.top < this.bounds.top) { - // cube fits into -x-y-z octant - index = 0; - } else if (cube.z > this.bounds.top) { - // cube fits into -x-y+z octant - index = 4; - } - } else if (cube.y > this.bounds.frontY) { - if (cube.z < this.bounds.top && cube.top < this.bounds.top) { - // cube fits into -x+y-z octant - index = 2; - } else if (cube.z > this.bounds.top) { - // cube fits into -x+y+z octant - index = 6; - } - } - } else if (cube.x > this.bounds.frontX) { - if (cube.y < this.bounds.frontY && cube.frontY < this.bounds.frontY) { - if (cube.z < this.bounds.top && cube.top < this.bounds.top) { - // cube fits into +x-y-z octant - index = 1; - } else if (cube.z > this.bounds.top) { - // cube fits into +x-y+z octant - index = 5; - } - } else if (cube.y > this.bounds.frontY) { - if (cube.z < this.bounds.top && cube.top < this.bounds.top) { - // cube fits into +x+y-z octant - index = 3; - } else if (cube.z > this.bounds.top) { - // cube fits into +x+y+z octant - index = 7; - } - } - } - - - return index; - - }, - - /** - * Return all objects that could collide with the given IsoSprite or Cube. - * - * @method Phaser.Plugin.Isometric.Octree#retrieve - * @param {Phaser.Plugin.Isometric.IsoSprite|Phaser.Plugin.Isometric.Cube} source - The source object to check the Octree against. Either a IsoSprite or Cube. - * @return {array} - Array with all detected objects. - */ - retrieve: function (source) { - - var returnObjects, index; - - if (source instanceof Phaser.Plugin.Isometric.Cube) { - returnObjects = this.objects; - - index = this.getIndex(source); - } else { - if (!source.body) { - return this._empty; - } - - returnObjects = this.objects; - - index = this.getIndex(source.body); - } - - if (this.nodes[0]) { - // If cube fits into a subnode .. - if (index !== -1) { - returnObjects = returnObjects.concat(this.nodes[index].retrieve(source)); - } else { - // If cube does not fit into a subnode, check it against all subnodes (unrolled for speed) - returnObjects = returnObjects.concat(this.nodes[0].retrieve(source)); - returnObjects = returnObjects.concat(this.nodes[1].retrieve(source)); - returnObjects = returnObjects.concat(this.nodes[2].retrieve(source)); - returnObjects = returnObjects.concat(this.nodes[3].retrieve(source)); - returnObjects = returnObjects.concat(this.nodes[4].retrieve(source)); - returnObjects = returnObjects.concat(this.nodes[5].retrieve(source)); - returnObjects = returnObjects.concat(this.nodes[6].retrieve(source)); - returnObjects = returnObjects.concat(this.nodes[7].retrieve(source)); - } - } - - return returnObjects; - - }, - - /** - * Clear the octree. - * @method Phaser.Plugin.Isometric.Octree#clear - */ - clear: function () { - - this.objects.length = 0; - - var i = this.nodes.length; - - while (i--) { - this.nodes[i].clear(); - this.nodes.splice(i, 1); - } - - this.nodes.length = 0; - } - -}; - -Phaser.Plugin.Isometric.Octree.prototype.constructor = Phaser.Plugin.Isometric.Octree; - -/** - * Visually renders an Octree to the display. - * - * @method Phaser.Utils.Debug#octree - * @param {Phaser.Plugin.Isometric.Octree} octree - The octree to render. - * @param {string} color - The color of the lines in the quadtree. - */ -Phaser.Utils.Debug.prototype.octree = function (octree, color) { - - color = color || 'rgba(255,0,0,0.3)'; - - this.start(); - - var bounds = octree.bounds, - i, points; - - if (octree.nodes.length === 0) { - - this.context.strokeStyle = color; - - var cube = new Phaser.Plugin.Isometric.Cube(bounds.x, bounds.y, bounds.z, bounds.widthX, bounds.widthY, bounds.height); - var corners = cube.getCorners(); - - points = corners.slice(0, corners.length); - points = points.map(function (p) { - return this.game.iso.project(p); - }); - - this.context.moveTo(points[0].x, points[0].y); - this.context.beginPath(); - this.context.strokeStyle = color; - - this.context.lineTo(points[1].x, points[1].y); - this.context.lineTo(points[3].x, points[3].y); - this.context.lineTo(points[2].x, points[2].y); - this.context.lineTo(points[6].x, points[6].y); - this.context.lineTo(points[4].x, points[4].y); - this.context.lineTo(points[5].x, points[5].y); - this.context.lineTo(points[1].x, points[1].y); - this.context.lineTo(points[0].x, points[0].y); - this.context.lineTo(points[4].x, points[4].y); - this.context.moveTo(points[0].x, points[0].y); - this.context.lineTo(points[2].x, points[2].y); - this.context.moveTo(points[3].x, points[3].y); - this.context.lineTo(points[7].x, points[7].y); - this.context.lineTo(points[6].x, points[6].y); - this.context.moveTo(points[7].x, points[7].y); - this.context.lineTo(points[5].x, points[5].y); - this.context.stroke(); - this.context.closePath(); - - for (i = 0; i < octree.objects.length; i++) { - this.body(octree.objects[i].sprite, 'rgb(0,255,0)', false); - } - } else { - for (i = 0; i < octree.nodes.length; i++) { - this.octree(octree.nodes[i]); - } - } - - this.stop(); - -}; - Phaser.Utils.Debug.prototype.body = (function (_super) { return function (sprite, color, filled) {