mirror of
https://github.com/photonstorm/phaser
synced 2025-03-01 13:57:26 +00:00
MatterTileBody: wrapper around a Tile that provides access to a matter body
This commit is contained in:
parent
b82179268f
commit
348da8c81e
2 changed files with 194 additions and 0 deletions
|
@ -182,6 +182,12 @@ var Tile = new Class({
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
this.tint = 0xffffff;
|
this.tint = 0xffffff;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An empty object where physics-engine specific information (e.g. bodies) may be stored.
|
||||||
|
* @property {object} physics
|
||||||
|
*/
|
||||||
|
this.physics = {};
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
188
src/physics/matter-js/MatterTileBody.js
Normal file
188
src/physics/matter-js/MatterTileBody.js
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
var AnimationComponent = require('../../gameobjects/components/Animation');
|
||||||
|
var Bodies = require('./lib/factory/Bodies');
|
||||||
|
var Class = require('../../utils/Class');
|
||||||
|
var Components = require('./components');
|
||||||
|
var GetFastValue = require('../../utils/object/GetFastValue');
|
||||||
|
var HasValue = require('../../utils/object/HasValue');
|
||||||
|
var Extend = require('../../utils/object/Extend');
|
||||||
|
var Body = require('./lib/body/Body');
|
||||||
|
var Vertices = require('./lib/geometry/Vertices');
|
||||||
|
|
||||||
|
var MatterTileBody = new Class({
|
||||||
|
|
||||||
|
Mixins: [
|
||||||
|
Components.Bounce,
|
||||||
|
Components.Collision,
|
||||||
|
Components.Friction,
|
||||||
|
Components.Gravity,
|
||||||
|
Components.Mass,
|
||||||
|
Components.Sensor,
|
||||||
|
Components.Sleep,
|
||||||
|
Components.Static
|
||||||
|
],
|
||||||
|
|
||||||
|
initialize:
|
||||||
|
|
||||||
|
function MatterTileBody (world, tile, options)
|
||||||
|
{
|
||||||
|
this.tile = tile;
|
||||||
|
this.world = world;
|
||||||
|
|
||||||
|
// A tile is only allowed one matter body
|
||||||
|
if (tile.physics.matterBody)
|
||||||
|
{
|
||||||
|
tile.physics.matterBody.destroy();
|
||||||
|
}
|
||||||
|
tile.physics.matterBody = this;
|
||||||
|
|
||||||
|
// Set the body either from an existing body (if provided), the shapes in the tileset
|
||||||
|
// collision layer (if it exists) or a rectangle matching the tile.
|
||||||
|
var body = GetFastValue(options, 'body', null);
|
||||||
|
var addToWorld = GetFastValue(options, 'addToWorld', true);
|
||||||
|
if (!body)
|
||||||
|
{
|
||||||
|
var tileset = tile.layer.tilemapLayer.tileset;
|
||||||
|
var collisionGroup = tileset.getTileCollisionGroup(tile.index);
|
||||||
|
var collisionObjects = GetFastValue(collisionGroup, 'objects', []);
|
||||||
|
if (collisionObjects.length > 0)
|
||||||
|
{
|
||||||
|
this.setFromTileCollision(options);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.setFromTileRectangle(options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.setBody(body, addToWorld);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setFromTileRectangle: function (options)
|
||||||
|
{
|
||||||
|
if (options === undefined) { options = {}; }
|
||||||
|
if (!HasValue(options, "isStatic")) { options.isStatic = true; }
|
||||||
|
if (!HasValue(options, "addToWorld")) { options.addToWorld = true; }
|
||||||
|
|
||||||
|
var tile = this.tile;
|
||||||
|
var tilemapLayer = tile.layer.tilemapLayer;
|
||||||
|
var tileset = tilemapLayer.tileset;
|
||||||
|
var w = tile.width * tilemapLayer.scaleX;
|
||||||
|
var h = tile.height * tilemapLayer.scaleY;
|
||||||
|
var x = tilemapLayer.tileToWorldX(tile.x);
|
||||||
|
var y = tilemapLayer.tileToWorldY(tile.y);
|
||||||
|
var body = Bodies.rectangle(x + (w / 2), y + (h / 2), w, h, options);
|
||||||
|
this.setBody(body, options.addToWorld);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
setFromTileCollision: function (options)
|
||||||
|
{
|
||||||
|
if (options === undefined) { options = {}; }
|
||||||
|
if (!HasValue(options, "isStatic")) { options.isStatic = true; }
|
||||||
|
if (!HasValue(options, "addToWorld")) { options.addToWorld = true; }
|
||||||
|
|
||||||
|
var tile = this.tile;
|
||||||
|
var tilemapLayer = tile.layer.tilemapLayer;
|
||||||
|
var tileset = tilemapLayer.tileset;
|
||||||
|
var w = tile.width * tilemapLayer.scaleX;
|
||||||
|
var h = tile.height * tilemapLayer.scaleY;
|
||||||
|
var x = tilemapLayer.tileToWorldX(tile.x);
|
||||||
|
var y = tilemapLayer.tileToWorldY(tile.y);
|
||||||
|
|
||||||
|
var collisionGroup = tileset.getTileCollisionGroup(tile.index);
|
||||||
|
var collisionObjects = GetFastValue(collisionGroup, 'objects', []);
|
||||||
|
|
||||||
|
var parts = [];
|
||||||
|
for (var i = 0; i < collisionObjects.length; i++)
|
||||||
|
{
|
||||||
|
var object = collisionObjects[i];
|
||||||
|
var ox = x + object.x;
|
||||||
|
var oy = y + object.y;
|
||||||
|
var ow = object.width;
|
||||||
|
var oh = object.height;
|
||||||
|
var body = null;
|
||||||
|
|
||||||
|
if (object.rectangle)
|
||||||
|
{
|
||||||
|
body = Bodies.rectangle(ox + ow / 2, oy + oh / 2, ow, oh, options);
|
||||||
|
}
|
||||||
|
else if (object.ellipse)
|
||||||
|
{
|
||||||
|
body = Bodies.circle(ox + ow / 2, oy + oh / 2, ow / 2, options);
|
||||||
|
}
|
||||||
|
else if (object.polygon || object.polyline)
|
||||||
|
{
|
||||||
|
// Polygons and polylines are both treated as closed polygons. Concave shapes are
|
||||||
|
// supported if poly-decomp library is included, but it's best to manually create
|
||||||
|
// convex polygons.
|
||||||
|
var originalPoints = object.polygon ? object.polygon : object.polyline;
|
||||||
|
var points = originalPoints.map(function (p) {
|
||||||
|
return { x: p[0], y: p[1] };
|
||||||
|
});
|
||||||
|
var vertices = Vertices.create(points);
|
||||||
|
|
||||||
|
// Translate from object position to center of mass
|
||||||
|
var center = Vertices.centre(vertices);
|
||||||
|
body = Bodies.fromVertices(ox + center.x, oy + center.y, vertices, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (body)
|
||||||
|
{
|
||||||
|
parts.push(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parts.length === 1)
|
||||||
|
{
|
||||||
|
this.setBody(parts[0], options.addToWorld);
|
||||||
|
}
|
||||||
|
else if (parts.length > 1)
|
||||||
|
{
|
||||||
|
options.parts = parts;
|
||||||
|
this.setBody(Body.create(options), options.addToWorld);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
setBody: function (body, addToWorld)
|
||||||
|
{
|
||||||
|
if (addToWorld === undefined) { addToWorld = true; }
|
||||||
|
|
||||||
|
if (this.body)
|
||||||
|
{
|
||||||
|
this.removeBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.body = body;
|
||||||
|
this.body.gameObject = this;
|
||||||
|
|
||||||
|
if (addToWorld)
|
||||||
|
{
|
||||||
|
this.world.add(this.body);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
removeBody: function ()
|
||||||
|
{
|
||||||
|
if (this.body)
|
||||||
|
{
|
||||||
|
this.world.remove(this.body);
|
||||||
|
this.body.gameObject = undefined;
|
||||||
|
this.body = undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function ()
|
||||||
|
{
|
||||||
|
this.removeBody();
|
||||||
|
tile.physics.matterBody = undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = MatterTileBody;
|
Loading…
Add table
Reference in a new issue