Skip to content

Commit fb1306e

Browse files
committed
The MatterAttractors plugin, which enables attractors between bodies, has been fixed. The original plugin only worked if the body with the attractor was _first_ in the world bodies list. It can now attract any body, no matter where in the world list it is. Fix phaserjs#5160
1 parent 0999824 commit fb1306e

1 file changed

Lines changed: 113 additions & 96 deletions

File tree

src/physics/matter-js/lib/plugins/MatterAttractors.js

Lines changed: 113 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -5,108 +5,125 @@ var Matter = require('../../CustomMain');
55
* See the readme for usage and examples.
66
* @module MatterAttractors
77
*/
8-
var MatterAttractors = {
9-
// plugin meta
10-
name: 'matter-attractors', // PLUGIN_NAME
11-
version: '0.1.7', // PLUGIN_VERSION
12-
for: 'matter-js@^0.14.2',
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-
}
8+
var MatterAttractors =
9+
{
10+
name: 'matter-attractors',
11+
version: '0.1.7',
12+
for: 'matter-js@^0.14.2',
13+
silent: true,
14+
15+
// installs the plugin where `base` is `Matter`
16+
// you should not need to call this directly.
17+
install: function (base)
18+
{
19+
base.after('Body.create', function ()
20+
{
21+
MatterAttractors.Body.init(this);
22+
});
23+
24+
base.before('Engine.update', function (engine)
25+
{
26+
MatterAttractors.Engine.update(engine);
27+
});
28+
},
29+
30+
Body:
31+
{
32+
/**
33+
* Initialises the `body` to support attractors.
34+
* This is called automatically by the plugin.
35+
* @function MatterAttractors.Body.init
36+
* @param {Matter.Body} body The body to init.
37+
* @returns {void} No return value.
38+
*/
39+
init: function (body)
40+
{
41+
body.plugin.attractors = body.plugin.attractors || [];
42+
}
43+
},
44+
45+
Engine:
46+
{
47+
/**
48+
* Applies all attractors for all bodies in the `engine`.
49+
* This is called automatically by the plugin.
50+
* @function MatterAttractors.Engine.update
51+
* @param {Matter.Engine} engine The engine to update.
52+
* @returns {void} No return value.
53+
*/
54+
update: function (engine)
55+
{
56+
var bodies = Matter.Composite.allBodies(engine.world);
57+
58+
for (var i = 0; i < bodies.length; i++)
59+
{
60+
var bodyA = bodies[i];
61+
var attractors = bodyA.plugin.attractors;
62+
63+
if (attractors && attractors.length > 0)
64+
{
65+
for (var j = 0; j < bodies.length; j++)
66+
{
67+
var bodyB = bodies[j];
68+
69+
if (i !== j)
70+
{
71+
for (var k = 0; k < attractors.length; k++)
72+
{
73+
var attractor = attractors[k];
74+
var forceVector = attractor;
75+
76+
if (Matter.Common.isFunction(attractor))
77+
{
78+
forceVector = attractor(bodyA, bodyB);
79+
}
80+
81+
if (forceVector)
82+
{
83+
Matter.Body.applyForce(bodyB, bodyB.position, forceVector);
84+
}
85+
}
86+
}
87+
}
88+
}
7189
}
72-
}
7390
}
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,
91+
},
8692

8793
/**
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.
94+
* Defines some useful common attractor functions that can be used
95+
* by pushing them to your body's `body.plugin.attractors` array.
96+
* @namespace MatterAttractors.Attractors
97+
* @property {number} gravityConstant The gravitational constant used by the gravity attractor.
9698
*/
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);
99+
Attractors:
100+
{
101+
gravityConstant: 0.001,
102+
103+
/**
104+
* An attractor function that applies Newton's law of gravitation.
105+
* Use this by pushing `MatterAttractors.Attractors.gravity` to your body's `body.plugin.attractors` array.
106+
* The gravitational constant defaults to `0.001` which you can change
107+
* at `MatterAttractors.Attractors.gravityConstant`.
108+
* @function MatterAttractors.Attractors.gravity
109+
* @param {Matter.Body} bodyA The first body.
110+
* @param {Matter.Body} bodyB The second body.
111+
* @returns {void} No return value.
112+
*/
113+
gravity: function (bodyA, bodyB)
114+
{
115+
// use Newton's law of gravitation
116+
var bToA = Matter.Vector.sub(bodyB.position, bodyA.position);
117+
var distanceSq = Matter.Vector.magnitudeSquared(bToA) || 0.0001;
118+
var normal = Matter.Vector.normalise(bToA);
119+
var magnitude = -MatterAttractors.Attractors.gravityConstant * (bodyA.mass * bodyB.mass / distanceSq);
120+
var force = Matter.Vector.mult(normal, magnitude);
121+
122+
// to apply forces to both bodies
123+
Matter.Body.applyForce(bodyA, bodyA.position, Matter.Vector.neg(force));
124+
Matter.Body.applyForce(bodyB, bodyB.position, force);
125+
}
108126
}
109-
}
110127
};
111128

112129
module.exports = MatterAttractors;

0 commit comments

Comments
 (0)