diff --git a/examples/assets/physics/sprites.json b/examples/assets/physics/sprites.json new file mode 100644 index 00000000..6feeaf94 --- /dev/null +++ b/examples/assets/physics/sprites.json @@ -0,0 +1,157 @@ + { + + "contra2": [ + + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 10, 191 , 26, 158 , 25, 186 , 13, 204 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 116, 186 , 114, 165 , 130, 199 , 123, 203 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 115, 64 , 128, 91 , 132, 114 , 114, 165 , 8, 107 , 12, 85 , 25, 64 , 71, 47 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 138, 64 , 128, 91 , 115, 64 , 124, 10 , 137, 0 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 8, 107 , 114, 165 , 26, 158 , 11, 131 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 25, 64 , 12, 85 , 4, 67 , 0, 4 , 10, 0 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 114, 165 , 116, 186 , 25, 186 , 26, 158 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 116, 186 , 117, 206 , 20, 210 , 25, 186 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 142, 222 , 2, 222 , 20, 210 , 117, 206 ] + } + ] + + , + "bunny": [ + + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 140, 298 , 192, 248 , 224, 304 , 208, 318 , 164, 328 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 16, 196 , 60, 182 , 48, 246 , 10, 244 , 0, 218 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 224, 304 , 192, 248 , 224, 272 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 74, 4 , 104, 36 , 110, 58 , 64, 78 , 44, 72 , 32, 60 , 32, 30 , 48, 8 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 46, 262 , 116, 294 , 86, 336 , 46, 340 , 36, 334 , 22, 308 , 20, 284 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 172, 40 , 148, 74 , 110, 58 , 114, 22 , 128, 4 , 162, 0 , 174, 12 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 246, 230 , 238, 240 , 200, 240 , 186, 174 , 228, 184 , 244, 204 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 32, 110 , 40, 94 , 64, 78 , 110, 58 , 148, 74 , 60, 182 , 32, 146 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 194, 162 , 186, 174 , 46, 262 , 48, 246 , 148, 74 , 158, 78 , 188, 114 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 116, 294 , 46, 262 , 186, 174 , 200, 240 , 140, 298 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 148, 74 , 48, 246 , 60, 182 ] + } + ] + + , + "tetrisblock1": [ + + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 48, 0 , 96, 0 , 96, 144 , 48, 144 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 0, 48 , 48, 48 , 48, 96 , 0, 96 ] + } + ] + + , + "tetrisblock2": [ + + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 0, 144 , 0, 48 , 48, 48 , 48, 144 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 48, 0 , 96, 0 , 96, 96 , 48, 96 ] + } + ] + + , + "tetrisblock3": [ + + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 144, 0 , 144, 96 , 96, 48 , 96, 0 ] + } , + { + "density": 2, "friction": 0, "bounce": 0, + "filter": { "categoryBits": 1, "maskBits": 65535 }, + "shape": [ 96, 48 , 144, 96 , 0, 96 , 0, 48 ] + } + ] + + } \ No newline at end of file diff --git a/examples/assets/physics/sprites.pes b/examples/assets/physics/sprites.pes new file mode 100644 index 00000000..7421a26b Binary files /dev/null and b/examples/assets/physics/sprites.pes differ diff --git a/examples/wip/loadPolygon.js b/examples/wip/loadPolygon.js new file mode 100644 index 00000000..2c9336f5 --- /dev/null +++ b/examples/wip/loadPolygon.js @@ -0,0 +1,44 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('contra2', 'assets/pics/contra2.png'); + game.load.image('bunny', 'assets/sprites/bunny.png'); + game.load.image('tetrisblock1', 'assets/sprites/tetrisblock1.png'); + game.load.image('tetrisblock2', 'assets/sprites/tetrisblock2.png'); + game.load.image('tetrisblock3', 'assets/sprites/tetrisblock3.png'); + + // Load our physcs data exported from PhysicsEditor + game.load.physics('physicsData', 'assets/physics/sprites.json'); + +} + +var contra; +var start = false; + +function create() { + + contra = game.add.sprite(400, 300, 'contra2'); + contra.physicsEnabled = true; + contra.body.clearShapes(); + contra.body.loadPolygon('physicsData', 'contra2'); + + game.input.onDown.add(function() { start = true; }, this); + +} + +function update() { + + if (start) + { + contra.body.rotateLeft(5); + } + +} + +function render() { + + game.debug.renderPhysicsBody(contra.body, '#00ffff'); + +} diff --git a/src/loader/Cache.js b/src/loader/Cache.js index 37ca004a..51bbe8fc 100644 --- a/src/loader/Cache.js +++ b/src/loader/Cache.js @@ -607,7 +607,7 @@ Phaser.Cache.prototype = { { if (this._physics[key] && this._physics[key].data[object]) { - return this._physics[key].data[object][0]; + return this._physics[key].data[object]; } else { diff --git a/src/physics/Body.js b/src/physics/Body.js index a800f720..70dc7cf8 100644 --- a/src/physics/Body.js +++ b/src/physics/Body.js @@ -986,7 +986,7 @@ Phaser.Physics.Body.prototype = { * @method Phaser.Physics.Body#loadPolygon * @param {string} key - The key of the Physics Data file as stored in Game.Cache. * @param {string} object - The key of the object within the Physics data file that you wish to load the shape data from. - * @param {object} options - An object containing the build options: + * @param {object} options - An object containing the build options. Note that this isn't used if the data file contains multiple shapes. * @param {boolean} [options.optimalDecomp=false] - Set to true if you need optimal decomposition. Warning: very slow for polygons with more than 10 vertices. * @param {boolean} [options.skipSimpleCheck=false] - Set to true if you already know that the path is not intersecting itself. * @param {boolean|number} [options.removeCollinearPoints=false] - Set to a number (angle threshold value) to remove collinear points, or false to keep all points. @@ -996,7 +996,7 @@ Phaser.Physics.Body.prototype = { var data = this.game.cache.getPhysicsData(key, object); - if (data && data.shape) + if (data.length === 1) { var temp = []; @@ -1008,6 +1008,46 @@ Phaser.Physics.Body.prototype = { return this.addPolygon(options, temp); } + else + { + // We've multiple Convex shapes, they should be CCW automatically + var cm = p2.vec2.create(); + + for (var i = 0; i < data.length; i++) + { + var vertices = []; + + for (var s = 0; s < data[i].shape.length; s += 2) + { + vertices.push([ this.px2pi(data[i].shape[s]), this.px2pi(data[i].shape[s + 1]) ]); + } + + var c = new p2.Convex(vertices); + + // Move all vertices so its center of mass is in the local center of the convex + for (var j = 0; j !== c.vertices.length; j++) + { + var v = c.vertices[j]; + p2.vec2.sub(v, v, c.centerOfMass); + } + + p2.vec2.scale(cm, c.centerOfMass, 1); + + cm[0] -= this.px2pi(this.sprite.width / 2); + cm[1] -= this.px2pi(this.sprite.height / 2); + + c.updateTriangles(); + c.updateCenterOfMass(); + c.updateBoundingRadius(); + + this.data.addShape(c, cm); + } + + // this.data.adjustCenterOfMass(); + this.data.aabbNeedsUpdate = true; + + return true; + } return false;