From 569770ed21997c5d6f0bedd4e21d39e5a67477f6 Mon Sep 17 00:00:00 2001 From: Georgios Kaleadis Date: Mon, 10 Mar 2014 14:28:44 +0100 Subject: [PATCH] update --- src/physics/Physics.js | 5 +- src/physics/p2/Body.js | 51 +++++++- src/physics/p2/BodyDebug.js | 249 ++++++++++++++++++++++++++++++++++++ 3 files changed, 302 insertions(+), 3 deletions(-) create mode 100644 src/physics/p2/BodyDebug.js diff --git a/src/physics/Physics.js b/src/physics/Physics.js index e0a82822e..f4bb768ee 100644 --- a/src/physics/Physics.js +++ b/src/physics/Physics.js @@ -138,10 +138,12 @@ Phaser.Physics.prototype = { * @method Phaser.Physics#enable * @param {object|array} object - The game object to create the physics body on. Can also be an array of objects, a body will be created on every object in the array. * @param {number} [system=Phaser.Physics.ARCADE] - The physics system that will be used to create the body. Defaults to Arcade Physics. + * @param {boolean} [debug=false] - Enable the debug drawing for this body. Defaults to false. */ - enable: function (object, system) { + enable: function (object, system, debug) { if (typeof system === 'undefined') { system = Phaser.Physics.ARCADE; } + if (typeof debug === 'undefined') { debug = false; } var i = 1; @@ -172,6 +174,7 @@ Phaser.Physics.prototype = { else if (system === Phaser.Physics.P2) { object[i].body = new Phaser.Physics.P2.Body(this.game, object[i], object[i].x, object[i].y, 1); + object[i].body.debug = debug object[i].anchor.set(0.5); } else if (system === Phaser.Physics.NINJA) diff --git a/src/physics/p2/Body.js b/src/physics/p2/Body.js index b51662b04..460b7ed4a 100644 --- a/src/physics/p2/Body.js +++ b/src/physics/p2/Body.js @@ -111,6 +111,13 @@ Phaser.Physics.P2.Body = function (game, sprite, x, y, mass) { */ this._groupCallbackContext = []; + + + /** + * @property {Phaser.Physics.P2.BodyDebug} debugBody - Reference to the debug drawer. + */ + this.debugBody = null + // Set-up the default shape if (sprite) { @@ -682,6 +689,8 @@ Phaser.Physics.P2.Body.prototype = { this.data.removeShape(shape); } + this.shapeChanged() + }, /** @@ -702,6 +711,7 @@ Phaser.Physics.P2.Body.prototype = { if (typeof rotation === 'undefined') { rotation = 0; } this.data.addShape(shape, [this.px2pi(offsetX), this.px2pi(offsetY)], rotation); + this.shapeChanged() return shape; @@ -886,8 +896,10 @@ Phaser.Physics.P2.Body.prototype = { // console.log(path[1]); // console.table(path); - return this.data.fromPolygon(path, options); + result = this.data.fromPolygon(path, options); + this.shapeChanged() + return result }, /** @@ -985,6 +997,12 @@ Phaser.Physics.P2.Body.prototype = { } }, + + shapeChanged: function(){ + console.log('shapeChanged', this.debugBody) + //shape has changed, so try to redraw if debug is available + if(this.debugBody) this.debugBody.draw() + }, /** * Reads the shape data from a physics data file stored in the Game.Cache and adds it as a polygon to this Body. @@ -1052,7 +1070,7 @@ Phaser.Physics.P2.Body.prototype = { // this.data.adjustCenterOfMass(); this.data.aabbNeedsUpdate = true; - + this.shapeChanged(); return true; } @@ -1545,3 +1563,32 @@ Object.defineProperty(Phaser.Physics.P2.Body.prototype, "y", { } }); + + +/** +* @name Phaser.Physics.P2.Body#debug +* @property {boolean} debug - Enable or disable debug drawing of this body +*/ +Object.defineProperty(Phaser.Physics.P2.Body.prototype, "debug", { + + get: function () { + + return (!this.debugBody); + + }, + + set: function (value) { + + if (value && !this.debugBody) + { + //this will be added to the global space + this.debugBody = new Phaser.Physics.P2.BodyDebug(this.game, this.data) + } + else if (!value && this.debugBody) + { + //destroy this.debugBody + } + + } + +}); \ No newline at end of file diff --git a/src/physics/p2/BodyDebug.js b/src/physics/p2/BodyDebug.js new file mode 100644 index 000000000..edf33dfd4 --- /dev/null +++ b/src/physics/p2/BodyDebug.js @@ -0,0 +1,249 @@ +Phaser.Physics.P2.BodyDebug = function(game, body, settings){ + Phaser.Group.call(this, game); + + defaultSettings = { + pixelsPerLengthUnit: 20, + debugPolygons: false, + lineWidth: 1, + alpha: 0.5 + } + this.settings = Phaser.Utils.extend(defaultSettings, settings); + + this.ppu = this.settings.pixelsPerLengthUnit; + this.ppu = -1 * this.ppu; + this.body = body; + this.canvas = new Phaser.Graphics(game); + this.canvas.alpha = this.settings.alpha + this.add(this.canvas); + + this.draw(); +} + +Phaser.Physics.P2.BodyDebug.prototype = Object.create(Phaser.Group.prototype) +Phaser.Physics.P2.BodyDebug.prototype.constructor = Phaser.Physics.P2.BodyDebug + +Phaser.Utils.extend(Phaser.Physics.P2.BodyDebug.prototype,{ + update: function() { + this.updateSpriteTransform() + }, + + updateSpriteTransform: function() { + this.position.x = this.body.position[0] * this.ppu; + this.position.y = this.body.position[1] * this.ppu; + return this.rotation = this.body.angle; + }, + + draw: function() { + var angle, child, color, i, j, lineColor, lw, obj, offset, sprite, v, verts, vrot, _i, _j, _ref, _ref1, _results; + obj = this.body; + sprite = this.canvas; + sprite.clear(); + color = parseInt(this.randomPastelHex(), 16); + lineColor = 0xff0000; + lw = this.lineWidth; + + if (obj instanceof p2.Body && obj.shapes.length) { + var l = obj.shapes.length + + + i = 0; + while (i !== l) { + child = obj.shapes[i]; + offset = obj.shapeOffsets[i]; + angle = obj.shapeAngles[i]; + offset = offset || zero; + angle = angle || 0; + + if (child instanceof p2.Circle) { + this.drawCircle(sprite, offset[0] * this.ppu, -offset[1] * this.ppu, angle, child.radius * this.ppu, color, lw) + + } else if (child instanceof p2.Convex) { + verts = []; + vrot = p2.vec2.create(); + for (j = _j = 0, _ref1 = child.vertices.length; 0 <= _ref1 ? _j < _ref1 : _j > _ref1; j = 0 <= _ref1 ? ++_j : --_j) { + v = child.vertices[j]; + p2.vec2.rotate(vrot, v, angle); + verts.push([(vrot[0] + offset[0]) * this.ppu, -(vrot[1] + offset[1]) * this.ppu]); + } + this.drawConvex(sprite, verts, child.triangles, lineColor, color, lw, this.settings.debugPolygons, [offset[0] * this.ppu, -offset[1] * this.ppu]); + + } else if (child instanceof p2.Plane) { + this.drawPlane(sprite, offset[0] * this.ppu, -offset[1] * this.ppu, color, lineColor, lw * 5, lw * 10, lw * 10, this.ppu * 100, angle); + + } else if (child instanceof p2.Line) { + this.drawLine(sprite, child.length * this.ppu, lineColor, lw); + + } else if (child instanceof p2.Rectangle) { + this.drawRectangle(sprite, offset[0] * this.ppu, -offset[1] * this.ppu, angle, child.width * this.ppu, child.height * this.ppu, lineColor, color, lw); + } + + i++ + } + } + }, + + drawRectangle: function(g, x, y, angle, w, h, color, fillColor, lineWidth) { + if (typeof lineWidth === 'undefined') { lineWidth = 1; } + if (typeof color === 'undefined') { color = 0x000000; } + + g.lineStyle(lineWidth, color, 1); + g.beginFill(fillColor); + g.drawRect(x - w / 2, y - h / 2, w, h); + }, + + drawCircle: function(g, x, y, angle, radius, color, lineWidth) { + if (typeof lineWidth === 'undefined') { lineWidth = 1; } + if (typeof color === 'undefined') { color = 0xffffff; } + g.lineStyle(lineWidth, 0x000000, 1); + g.beginFill(color, 1.0); + g.drawCircle(x, y, -radius); + g.endFill(); + g.moveTo(x, y); + g.lineTo(x + radius * Math.cos(-angle), y + radius * Math.sin(-angle)); + }, + + drawLine: function(g, len, color, lineWidth) { + if (typeof lineWidth === 'undefined') { lineWidth = 1; } + if (typeof color === 'undefined') { color = 0x000000; } + + g.lineStyle(lineWidth * 5, color, 1); + g.moveTo(-len / 2, 0); + g.lineTo(len / 2, 0); + }, + + drawConvex: function(g, verts, triangles, color, fillColor, lineWidth, debug, offset) { + var colors, i, v, v0, v1, x, x0, x1, y, y0, y1; + if (typeof lineWidth === 'undefined') { lineWidth = 1; } + if (typeof color === 'undefined') { color = 0x000000; } + + if (!debug) { + g.lineStyle(lineWidth, color, 1); + g.beginFill(fillColor); + i = 0; + while (i !== verts.length) { + v = verts[i]; + x = v[0]; + y = v[1]; + if (i === 0) { + g.moveTo(x, -y); + } else { + g.lineTo(x, -y); + } + i++; + } + g.endFill(); + if (verts.length > 2) { + g.moveTo(verts[verts.length - 1][0], -verts[verts.length - 1][1]); + return g.lineTo(verts[0][0], -verts[0][1]); + } + } else { + colors = [0xff0000, 0x00ff00, 0x0000ff]; + i = 0; + while (i !== verts.length + 1) { + v0 = verts[i % verts.length]; + v1 = verts[(i + 1) % verts.length]; + x0 = v0[0]; + y0 = v0[1]; + x1 = v1[0]; + y1 = v1[1]; + g.lineStyle(lineWidth, colors[i % colors.length], 1); + g.moveTo(x0, -y0); + g.lineTo(x1, -y1); + g.drawCircle(x0, -y0, lineWidth * 2); + i++; + } + g.lineStyle(lineWidth, 0x000000, 1); + return g.drawCircle(offset[0], offset[1], lineWidth * 2); + } + }, + + drawPath: function(g, path, color, fillColor, lineWidth) { + var area, i, lastx, lasty, p1x, p1y, p2x, p2y, p3x, p3y, v, x, y; + if (typeof lineWidth === 'undefined') { lineWidth = 1; } + if (typeof color === 'undefined') { color = 0x000000; } + + g.lineStyle(lineWidth, color, 1); + if (typeof fillColor === "number") { + g.beginFill(fillColor); + } + lastx = null; + lasty = null; + i = 0; + while (i < path.length) { + v = path[i]; + x = v[0]; + y = v[1]; + if (x !== lastx || y !== lasty) { + if (i === 0) { + g.moveTo(x, y); + } else { + p1x = lastx; + p1y = lasty; + p2x = x; + p2y = y; + p3x = path[(i + 1) % path.length][0]; + p3y = path[(i + 1) % path.length][1]; + area = ((p2x - p1x) * (p3y - p1y)) - ((p3x - p1x) * (p2y - p1y)); + if (area !== 0) { + g.lineTo(x, y); + } + } + lastx = x; + lasty = y; + } + i++; + } + if (typeof fillColor === "number") { + g.endFill(); + } + if (path.length > 2 && typeof fillColor === "number") { + g.moveTo(path[path.length - 1][0], path[path.length - 1][1]); + g.lineTo(path[0][0], path[0][1]); + } + }, + + drawPlane: function(g, x0, x1, color, lineColor, lineWidth, diagMargin, diagSize, maxLength, angle) { + var max, xd, yd; + if (typeof lineWidth === 'undefined') { lineWidth = 1; } + if (typeof color === 'undefined') { color = 0xffffff; } + + g.lineStyle(lineWidth, lineColor, 11); + g.beginFill(color); + max = maxLength; + g.moveTo(x0, -x1); + xd = x0 + Math.cos(angle) * this.game.width; + yd = x1 + Math.sin(angle) * this.game.height; + g.lineTo(xd, -yd); + g.moveTo(x0, -x1); + xd = x0 + Math.cos(angle) * -this.game.width; + yd = x1 + Math.sin(angle) * -this.game.height; + g.lineTo(xd, -yd); + }, + + randomPastelHex: function() { + var blue, green, mix, red; + mix = [255, 255, 255]; + red = Math.floor(Math.random() * 256); + green = Math.floor(Math.random() * 256); + blue = Math.floor(Math.random() * 256); + red = Math.floor((red + 3 * mix[0]) / 4); + green = Math.floor((green + 3 * mix[1]) / 4); + blue = Math.floor((blue + 3 * mix[2]) / 4); + return this.rgbToHex(red, green, blue); + }, + + rgbToHex: function(r, g, b) { + return this.componentToHex(r) + this.componentToHex(g) + this.componentToHex(b); + }, + + componentToHex: function(c) { + var hex; + hex = c.toString(16); + + if (hex.len === 2) { + return hex; + } else { + return hex + '0'; + } + } +}) \ No newline at end of file