/** * See [Demo.js](https://github.com/liabru/matter-js/blob/master/demo/js/Demo.js) * and [DemoMobile.js](https://github.com/liabru/matter-js/blob/master/demo/js/DemoMobile.js) for usage examples. * * @class Composite */ // TODO: composite translate, rotate var Composite = {}; (function() { var _nextId = 0; /** * Description * @method create * @param {} options * @return {composite} A new composite */ Composite.create = function(options) { return Common.extend({ id: Composite.nextId(), type: 'composite', parent: null, isModified: false, bodies: [], constraints: [], composites: [] }, options); }; /** * Returns the next unique compositeID * @method nextId * @return {Number} Unique compositeID */ Composite.nextId = function() { return _nextId++; }; /** * Sets the composite's `isModified` flag. * If `updateParents` is true, all parents will be set (default: false). * If `updateChildren` is true, all children will be set (default: false). * @method setModified * @param {composite} composite * @param {boolean} isModified * @param {boolean} updateParents * @param {boolean} updateChildren */ Composite.setModified = function(composite, isModified, updateParents, updateChildren) { composite.isModified = isModified; if (updateParents && composite.parent) { Composite.setModified(composite.parent, isModified, updateParents, updateChildren); } if (updateChildren) { for(var i = 0; i < composite.composites.length; i++) { var childComposite = composite.composites[i]; Composite.setModified(childComposite, isModified, updateParents, updateChildren); } } }; /** * Generic add function. Adds one or many body(s), constraint(s) or a composite(s) to the given composite. * @method add * @param {composite} composite * @param {} object * @return {composite} The original composite with the objects added */ Composite.add = function(composite, object) { var objects = [].concat(object); for (var i = 0; i < objects.length; i++) { var obj = objects[i]; switch (obj.type) { case 'body': Composite.addBody(composite, obj); break; case 'constraint': Composite.addConstraint(composite, obj); break; case 'composite': Composite.addComposite(composite, obj); break; case 'mouseConstraint': Composite.addConstraint(composite, obj.constraint); break; } } return composite; }; /** * Generic remove function. Removes one or many body(s), constraint(s) or a composite(s) to the given composite. * Optionally searching its children recursively. * @method remove * @param {composite} composite * @param {} object * @param {boolean} deep * @return {composite} The original composite with the objects removed */ Composite.remove = function(composite, object, deep) { var objects = [].concat(object); for (var i = 0; i < objects.length; i++) { var obj = objects[i]; switch (obj.type) { case 'body': Composite.removeBody(composite, obj, deep); break; case 'constraint': Composite.removeConstraint(composite, obj, deep); break; case 'composite': Composite.removeComposite(composite, obj, deep); break; case 'mouseConstraint': Composite.removeConstraint(composite, obj.constraint); break; } } return composite; }; /** * Description * @method addComposite * @param {composite} compositeA * @param {composite} compositeB * @return {composite} The original compositeA with the objects from compositeB added */ Composite.addComposite = function(compositeA, compositeB) { compositeA.composites.push(compositeB); compositeB.parent = compositeA; Composite.setModified(compositeA, true, true, false); return compositeA; }; /** * Removes a composite from the given composite, and optionally searching its children recursively * @method removeComposite * @param {composite} compositeA * @param {composite} compositeB * @param {boolean} deep * @return {composite} The original compositeA with the composite removed */ Composite.removeComposite = function(compositeA, compositeB, deep) { var position = compositeA.composites.indexOf(compositeB); if (position !== -1) { Composite.removeCompositeAt(compositeA, position); Composite.setModified(compositeA, true, true, false); } if (deep) { for (var i = 0; i < compositeA.composites.length; i++){ Composite.removeComposite(compositeA.composites[i], compositeB, true); } } return compositeA; }; /** * Removes a composite from the given composite * @method removeCompositeAt * @param {composite} composite * @param {number} position * @return {composite} The original composite with the composite removed */ Composite.removeCompositeAt = function(composite, position) { composite.composites.splice(position, 1); Composite.setModified(composite, true, true, false); return composite; }; /** * Description * @method addBody * @param {composite} composite * @param {body} body * @return {composite} The original composite with the body added */ Composite.addBody = function(composite, body) { composite.bodies.push(body); Composite.setModified(composite, true, true, false); return composite; }; /** * Removes a body from the given composite, and optionally searching its children recursively * @method removeBody * @param {composite} composite * @param {body} body * @param {boolean} deep * @return {composite} The original composite with the body removed */ Composite.removeBody = function(composite, body, deep) { var position = composite.bodies.indexOf(body); if (position !== -1) { Composite.removeBodyAt(composite, position); Composite.setModified(composite, true, true, false); } if (deep) { for (var i = 0; i < composite.composites.length; i++){ Composite.removeBody(composite.composites[i], body, true); } } return composite; }; /** * Removes a body from the given composite * @method removeBodyAt * @param {composite} composite * @param {number} position * @return {composite} The original composite with the body removed */ Composite.removeBodyAt = function(composite, position) { composite.bodies.splice(position, 1); Composite.setModified(composite, true, true, false); return composite; }; /** * Description * @method addConstraint * @param {composite} composite * @param {constraint} constraint * @return {composite} The original composite with the constraint added */ Composite.addConstraint = function(composite, constraint) { composite.constraints.push(constraint); Composite.setModified(composite, true, true, false); return composite; }; /** * Removes a constraint from the given composite, and optionally searching its children recursively * @method removeConstraint * @param {composite} composite * @param {constraint} constraint * @param {boolean} deep * @return {composite} The original composite with the constraint removed */ Composite.removeConstraint = function(composite, constraint, deep) { var position = composite.constraints.indexOf(constraint); if (position !== -1) { Composite.removeConstraintAt(composite, position); } if (deep) { for (var i = 0; i < composite.composites.length; i++){ Composite.removeConstraint(composite.composites[i], constraint, true); } } return composite; }; /** * Removes a body from the given composite * @method removeConstraintAt * @param {composite} composite * @param {number} position * @return {composite} The original composite with the constraint removed */ Composite.removeConstraintAt = function(composite, position) { composite.constraints.splice(position, 1); Composite.setModified(composite, true, true, false); return composite; }; /** * Removes all bodies, constraints and composites from the given composite * Optionally clearing its children recursively * @method clear * @param {world} world * @param {boolean} keepStatic * @param {boolean} deep */ Composite.clear = function(composite, keepStatic, deep) { if (deep) { for (var i = 0; i < composite.composites.length; i++){ Composite.clear(composite.composites[i], keepStatic, true); } } if (keepStatic) { composite.bodies = composite.bodies.filter(function(body) { return body.isStatic; }); } else { composite.bodies.length = 0; } composite.constraints.length = 0; composite.composites.length = 0; Composite.setModified(composite, true, true, false); return composite; }; /** * Returns all bodies in the given composite, including all bodies in its children, recursively * @method allBodies * @param {composite} composite * @return {body[]} All the bodies */ Composite.allBodies = function(composite) { var bodies = [].concat(composite.bodies); for (var i = 0; i < composite.composites.length; i++) bodies = bodies.concat(Composite.allBodies(composite.composites[i])); return bodies; }; /** * Returns all constraints in the given composite, including all constraints in its children, recursively * @method allConstraints * @param {composite} composite * @return {constraint[]} All the constraints */ Composite.allConstraints = function(composite) { var constraints = [].concat(composite.constraints); for (var i = 0; i < composite.composites.length; i++) constraints = constraints.concat(Composite.allConstraints(composite.composites[i])); return constraints; }; /** * Returns all composites in the given composite, including all composites in its children, recursively * @method allComposites * @param {composite} composite * @return {composite[]} All the composites */ Composite.allComposites = function(composite) { var composites = [].concat(composite.composites); for (var i = 0; i < composite.composites.length; i++) composites = composites.concat(Composite.allComposites(composite.composites[i])); return composites; }; })();