Skip to content

Commit ce28eaa

Browse files
committed
Added the Attractors and Wrap matter plugins. Fixed the Plugin register. Added silence option to stop plugin logging to the console.
1 parent ffeff9d commit ce28eaa

6 files changed

Lines changed: 353 additions & 3 deletions

File tree

v3/src/physics/matter-js/CustomMain.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
var Matter = module.exports = require('./lib/core/Matter');
1+
var Matter = require('./lib/core/Matter');
22

33
Matter.Body = require('./lib/body/Body');
44
Matter.Composite = require('./lib/body/Composite');
@@ -38,3 +38,5 @@ Matter.World.addComposite = Matter.Composite.addComposite;
3838
Matter.World.addBody = Matter.Composite.addBody;
3939
Matter.World.addConstraint = Matter.Composite.addConstraint;
4040
Matter.World.clear = Matter.Composite.clear;
41+
42+
module.exports = Matter;

v3/src/physics/matter-js/Matter.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
var Class = require('../../utils/Class');
22
var Factory = require('./Factory');
3+
var GetValue = require('../../utils/object/GetValue');
4+
var MatterAttractors = require('./lib/plugins/MatterAttractors');
5+
var MatterLib = require('./lib/core/Matter');
6+
var MatterWrap = require('./lib/plugins/MatterWrap');
7+
var Plugin = require('./lib/core/Plugin');
38
var World = require('./World');
49

510
var Matter = new Class({
@@ -15,6 +20,36 @@ var Matter = new Class({
1520
physicsManager.world = new World(physicsManager.scene, config);
1621

1722
physicsManager.add = new Factory(physicsManager.world);
23+
24+
// Matter plugins
25+
26+
if (GetValue(config, 'plugins.attractors', false))
27+
{
28+
Plugin.register(MatterAttractors);
29+
Plugin.use(MatterLib, MatterAttractors);
30+
}
31+
32+
if (GetValue(config, 'plugins.wrap', false))
33+
{
34+
Plugin.register(MatterWrap);
35+
Plugin.use(MatterLib, MatterWrap);
36+
}
37+
},
38+
39+
enableAttractorPlugin: function ()
40+
{
41+
Plugin.register(MatterAttractors);
42+
Plugin.use(MatterLib, MatterAttractors);
43+
44+
return this;
45+
},
46+
47+
enableWrapPlugin: function ()
48+
{
49+
Plugin.register(MatterWrap);
50+
Plugin.use(MatterLib, MatterWrap);
51+
52+
return this;
1853
}
1954

2055
});

v3/src/physics/matter-js/lib/core/Matter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ var Common = require('./Common');
2727
* @readOnly
2828
* @type {String}
2929
*/
30-
Matter.version = '@@VERSION@@';
30+
Matter.version = '0.13.1';
3131

3232
/**
3333
* A list of plugin dependencies to be installed. These are normally set and installed through `Matter.use`.

v3/src/physics/matter-js/lib/core/Plugin.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ var Common = require('./Common');
171171
module.used.push(plugin.name);
172172
}
173173

174-
if (status.length > 0) {
174+
if (status.length > 0 && !plugin.silent) {
175175
Common.info(status.join(' '));
176176
}
177177
};
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
var Matter = require('../../CustomMain');
2+
3+
/**
4+
* An attractors plugin for matter.js.
5+
* See the readme for usage and examples.
6+
* @module MatterAttractors
7+
*/
8+
var MatterAttractors = {
9+
// plugin meta
10+
name: 'matter-attractors', // PLUGIN_NAME
11+
version: '0.1.7', // PLUGIN_VERSION
12+
for: 'matter-js@^0.13.1',
13+
silent: true, // no console log please
14+
15+
// installs the plugin where `base` is `Matter`
16+
// you should not need to call this directly.
17+
install: function(base) {
18+
base.after('Body.create', function() {
19+
MatterAttractors.Body.init(this);
20+
});
21+
22+
base.before('Engine.update', function(engine) {
23+
MatterAttractors.Engine.update(engine);
24+
});
25+
},
26+
27+
Body: {
28+
/**
29+
* Initialises the `body` to support attractors.
30+
* This is called automatically by the plugin.
31+
* @function MatterAttractors.Body.init
32+
* @param {Matter.Body} body The body to init.
33+
* @returns {void} No return value.
34+
*/
35+
init: function(body) {
36+
body.plugin.attractors = body.plugin.attractors || [];
37+
}
38+
},
39+
40+
Engine: {
41+
/**
42+
* Applies all attractors for all bodies in the `engine`.
43+
* This is called automatically by the plugin.
44+
* @function MatterAttractors.Engine.update
45+
* @param {Matter.Engine} engine The engine to update.
46+
* @returns {void} No return value.
47+
*/
48+
update: function(engine) {
49+
var world = engine.world,
50+
bodies = Matter.Composite.allBodies(world);
51+
52+
for (var i = 0; i < bodies.length; i += 1) {
53+
var bodyA = bodies[i],
54+
attractors = bodyA.plugin.attractors;
55+
56+
if (attractors && attractors.length > 0) {
57+
for (var j = i + 1; j < bodies.length; j += 1) {
58+
var bodyB = bodies[j];
59+
60+
for (var k = 0; k < attractors.length; k += 1) {
61+
var attractor = attractors[k],
62+
forceVector = attractor;
63+
64+
if (Matter.Common.isFunction(attractor)) {
65+
forceVector = attractor(bodyA, bodyB);
66+
}
67+
68+
if (forceVector) {
69+
Matter.Body.applyForce(bodyB, bodyB.position, forceVector);
70+
}
71+
}
72+
}
73+
}
74+
}
75+
}
76+
},
77+
78+
/**
79+
* Defines some useful common attractor functions that can be used
80+
* by pushing them to your body's `body.plugin.attractors` array.
81+
* @namespace MatterAttractors.Attractors
82+
* @property {number} gravityConstant The gravitational constant used by the gravity attractor.
83+
*/
84+
Attractors: {
85+
gravityConstant: 0.001,
86+
87+
/**
88+
* An attractor function that applies Newton's law of gravitation.
89+
* Use this by pushing `MatterAttractors.Attractors.gravity` to your body's `body.plugin.attractors` array.
90+
* The gravitational constant defaults to `0.001` which you can change
91+
* at `MatterAttractors.Attractors.gravityConstant`.
92+
* @function MatterAttractors.Attractors.gravity
93+
* @param {Matter.Body} bodyA The first body.
94+
* @param {Matter.Body} bodyB The second body.
95+
* @returns {void} No return value.
96+
*/
97+
gravity: function(bodyA, bodyB) {
98+
// use Newton's law of gravitation
99+
var bToA = Matter.Vector.sub(bodyB.position, bodyA.position),
100+
distanceSq = Matter.Vector.magnitudeSquared(bToA) || 0.0001,
101+
normal = Matter.Vector.normalise(bToA),
102+
magnitude = -MatterAttractors.Attractors.gravityConstant * (bodyA.mass * bodyB.mass / distanceSq),
103+
force = Matter.Vector.mult(normal, magnitude);
104+
105+
// to apply forces to both bodies
106+
Matter.Body.applyForce(bodyA, bodyA.position, Matter.Vector.neg(force));
107+
Matter.Body.applyForce(bodyB, bodyB.position, force);
108+
}
109+
}
110+
};
111+
112+
module.exports = MatterAttractors;
113+
114+
/**
115+
* @namespace Matter.Body
116+
* @see http://brm.io/matter-js/docs/classes/Body.html
117+
*/
118+
119+
/**
120+
* This plugin adds a new property `body.plugin.attractors` to instances of `Matter.Body`.
121+
* This is an array of callback functions that will be called automatically
122+
* for every pair of bodies, on every engine update.
123+
* @property {Function[]} body.plugin.attractors
124+
* @memberof Matter.Body
125+
*/
126+
127+
/**
128+
* An attractor function calculates the force to be applied
129+
* to `bodyB`, it should either:
130+
* - return the force vector to be applied to `bodyB`
131+
* - or apply the force to the body(s) itself
132+
* @callback AttractorFunction
133+
* @param {Matter.Body} bodyA
134+
* @param {Matter.Body} bodyB
135+
* @returns {Vector|undefined} a force vector (optional)
136+
*/
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
var Matter = require('../../CustomMain');
2+
3+
/**
4+
* A coordinate wrapping plugin for matter.js.
5+
* See the readme for usage and examples.
6+
* @module MatterWrap
7+
*/
8+
var MatterWrap = {
9+
// plugin meta
10+
name: 'matter-wrap', // PLUGIN_NAME
11+
version: '0.1.4', // PLUGIN_VERSION
12+
for: 'matter-js@^0.13.1',
13+
silent: true, // no console log please
14+
15+
// installs the plugin where `base` is `Matter`
16+
// you should not need to call this directly.
17+
install: function(base) {
18+
base.after('Engine.update', function() {
19+
MatterWrap.Engine.update(this);
20+
});
21+
},
22+
23+
Engine: {
24+
/**
25+
* Updates the engine by wrapping bodies and composites inside `engine.world`.
26+
* This is called automatically by the plugin.
27+
* @function MatterWrap.Engine.update
28+
* @param {Matter.Engine} engine The engine to update.
29+
* @returns {void} No return value.
30+
*/
31+
update: function(engine) {
32+
var world = engine.world,
33+
bodies = Matter.Composite.allBodies(world),
34+
composites = Matter.Composite.allComposites(world);
35+
36+
for (var i = 0; i < bodies.length; i += 1) {
37+
var body = bodies[i];
38+
39+
if (body.plugin.wrap) {
40+
MatterWrap.Body.wrap(body, body.plugin.wrap);
41+
}
42+
}
43+
44+
for (i = 0; i < composites.length; i += 1) {
45+
var composite = composites[i];
46+
47+
if (composite.plugin.wrap) {
48+
MatterWrap.Composite.wrap(composite, composite.plugin.wrap);
49+
}
50+
}
51+
}
52+
},
53+
54+
Bounds: {
55+
/**
56+
* Returns a translation vector that wraps the `objectBounds` inside the `bounds`.
57+
* @function MatterWrap.Bounds.wrap
58+
* @param {Matter.Bounds} objectBounds The bounds of the object to wrap inside the bounds.
59+
* @param {Matter.Bounds} bounds The bounds to wrap the body inside.
60+
* @returns {?Matter.Vector} A translation vector (only if wrapping is required).
61+
*/
62+
wrap: function(objectBounds, bounds) {
63+
var x = null,
64+
y = null;
65+
66+
if (typeof bounds.min.x !== 'undefined' && typeof bounds.max.x !== 'undefined') {
67+
if (objectBounds.min.x > bounds.max.x) {
68+
x = bounds.min.x - objectBounds.max.x;
69+
} else if (objectBounds.max.x < bounds.min.x) {
70+
x = bounds.max.x - objectBounds.min.x;
71+
}
72+
}
73+
74+
if (typeof bounds.min.y !== 'undefined' && typeof bounds.max.y !== 'undefined') {
75+
if (objectBounds.min.y > bounds.max.y) {
76+
y = bounds.min.y - objectBounds.max.y;
77+
} else if (objectBounds.max.y < bounds.min.y) {
78+
y = bounds.max.y - objectBounds.min.y;
79+
}
80+
}
81+
82+
if (x !== null || y !== null) {
83+
return {
84+
x: x || 0,
85+
y: y || 0
86+
};
87+
}
88+
}
89+
},
90+
91+
Body: {
92+
/**
93+
* Wraps the `body` position such that it always stays within the given bounds.
94+
* Upon crossing a boundary the body will appear on the opposite side of the bounds,
95+
* while maintaining its velocity.
96+
* This is called automatically by the plugin.
97+
* @function MatterWrap.Body.wrap
98+
* @param {Matter.Body} body The body to wrap.
99+
* @param {Matter.Bounds} bounds The bounds to wrap the body inside.
100+
* @returns {?Matter.Vector} The translation vector that was applied (only if wrapping was required).
101+
*/
102+
wrap: function(body, bounds) {
103+
var translation = MatterWrap.Bounds.wrap(body.bounds, bounds);
104+
105+
if (translation) {
106+
Matter.Body.translate(body, translation);
107+
}
108+
109+
return translation;
110+
}
111+
},
112+
113+
Composite: {
114+
/**
115+
* Returns the union of the bounds of all of the composite's bodies
116+
* (not accounting for constraints).
117+
* @function MatterWrap.Composite.bounds
118+
* @param {Matter.Composite} composite The composite.
119+
* @returns {Matter.Bounds} The composite bounds.
120+
*/
121+
bounds: function(composite) {
122+
var bodies = Matter.Composite.allBodies(composite),
123+
vertices = [];
124+
125+
for (var i = 0; i < bodies.length; i += 1) {
126+
var body = bodies[i];
127+
vertices.push(body.bounds.min, body.bounds.max);
128+
}
129+
130+
return Matter.Bounds.create(vertices);
131+
},
132+
133+
/**
134+
* Wraps the `composite` position such that it always stays within the given bounds.
135+
* Upon crossing a boundary the composite will appear on the opposite side of the bounds,
136+
* while maintaining its velocity.
137+
* This is called automatically by the plugin.
138+
* @function MatterWrap.Composite.wrap
139+
* @param {Matter.Composite} composite The composite to wrap.
140+
* @param {Matter.Bounds} bounds The bounds to wrap the composite inside.
141+
* @returns {?Matter.Vector} The translation vector that was applied (only if wrapping was required).
142+
*/
143+
wrap: function(composite, bounds) {
144+
var translation = MatterWrap.Bounds.wrap(
145+
MatterWrap.Composite.bounds(composite),
146+
bounds
147+
);
148+
149+
if (translation) {
150+
Matter.Composite.translate(composite, translation);
151+
}
152+
153+
return translation;
154+
}
155+
}
156+
};
157+
158+
module.exports = MatterWrap;
159+
160+
/**
161+
* @namespace Matter.Body
162+
* @see http://brm.io/matter-js/docs/classes/Body.html
163+
*/
164+
165+
/**
166+
* This plugin adds a new property `body.plugin.wrap` to instances of `Matter.Body`.
167+
* This is a `Matter.Bounds` instance that specifies the wrapping region.
168+
* @property {Matter.Bounds} body.plugin.wrap
169+
* @memberof Matter.Body
170+
*/
171+
172+
/**
173+
* This plugin adds a new property `composite.plugin.wrap` to instances of `Matter.Composite`.
174+
* This is a `Matter.Bounds` instance that specifies the wrapping region.
175+
* @property {Matter.Bounds} composite.plugin.wrap
176+
* @memberof Matter.Composite
177+
*/

0 commit comments

Comments
 (0)