[Solved] How to use Matter-js attractors gravity helper function

Recommended Posts

Hi everyone,

I'm working on a game prototype involving planet gravitational physics. I got inspired by this example in the Phaser 3 official example archives, feature the following code :

var sun = this.matter.add.image(400, 200, 'sun', null, {
shape: {
type: 'circle',
},
plugin: {
attractors: [
function (bodyA, bodyB) {
return {
x: (bodyA.position.x - bodyB.position.x) * 0.000001,
y: (bodyA.position.y - bodyB.position.y) * 0.000001
};
}
]
}
});

Now, I'd like a more Newtonian function for attraction, and it appears Matter-js got already one ready in MatterAttractors.js, featuring the following :

/**
* Defines some useful common attractor functions that can be used
* by pushing them to your body's `body.plugin.attractors` array.
* @namespace MatterAttractors.Attractors
* @property {number} gravityConstant The gravitational constant used by the gravity attractor.
*/
Attractors: {
gravityConstant: 0.001,

/**
* An attractor function that applies Newton's law of gravitation.
* Use this by pushing `MatterAttractors.Attractors.gravity` to your body's `body.plugin.attractors` array.
* The gravitational constant defaults to `0.001` which you can change
* at `MatterAttractors.Attractors.gravityConstant`.
* @function MatterAttractors.Attractors.gravity
* @param {Matter.Body} bodyA The first body.
* @param {Matter.Body} bodyB The second body.
* @returns {void} No return value.
*/
gravity: function(bodyA, bodyB) {
// use Newton's law of gravitation
var bToA = Matter.Vector.sub(bodyB.position, bodyA.position),
distanceSq = Matter.Vector.magnitudeSquared(bToA) || 0.0001,
normal = Matter.Vector.normalise(bToA),
magnitude = -MatterAttractors.Attractors.gravityConstant * (bodyA.mass * bodyB.mass / distanceSq),
force = Matter.Vector.mult(normal, magnitude);

// to apply forces to both bodies
Matter.Body.applyForce(bodyA, bodyA.position, Matter.Vector.neg(force));
Matter.Body.applyForce(bodyB, bodyB.position, force);
}
}
};

My main problem at this point is that I don't know how to call that gravity function as the callback function for the attractor plugin of my object.

Also, I'm pretty new to using Phaser and Javascript is not a language I used much before (but I picked it for technical reasons). I'm learning a lot and it's quite well written. But I'm basically lost whenever it's about giving a list of options to an object, such as shape or plugin.attractors, or even the config var that set up the engine, because I don't know what are the *valid* options available, or their valid values. And when I use invalid options, I don't get much feedback in term of error messages, it just doesn't work.

I've tried many things to try to "reach" that function but it never worked. At best my object isn't rendered, at worst I got an error "undefined" element. Oh and I also got a case where my object was rendered but not doing any attraction what so ever.

I'd appreciate some help to keep me coding. Thank you.

Share on other sites

Well I found it out.

var sun = this.matter.add.image(400, 200, 'sun', null, {
shape: {
type: 'circle',
},
plugin: {
attractors: [Phaser.Physics.Matter.Matter.Plugin.resolve("matter-attractors").Attractors.gravity]
}
});﻿﻿

I figured it out attractors was an array.

Share on other sites

I'm down the exact same path you where a year ago, @Neomak

I managed to got what you have without any errors now, but I haven't got an gravity at all. The Phaser 3 example with simplified gravity works nice but with your code I don't see any effect.

My game config:

const config = {
type: Phaser.AUTO,
parent: "phaser-example",
width: 400,
height: 700,
physics:  {
default: 'matter',
matter: {
gravity: {
x: 0,
y: 0
},
plugins: {
attractors: true
},
debug: true
}
},
scene: [ BootScene,
SplashScene,
GameScene,
HUD]
};

If i remove the gravity-part I get weird warping anti-gravity..

My attractor planet code:

export default class Planet extends Phaser.Physics.Matter.Image {
constructor(scene, x, y) {
super(scene.matter.world, x, y, 'planet', null, {
shape: {
type: 'circle',
},
plugin: {
attractors: [Phaser.Physics.Matter.Matter.Plugin.resolve("matter-attractors").Attractors.gravity]
}
});

this.setStatic(true);
this.setBounce(0.05);
this.setFriction(1);
this.setMass(10000000000);

}
}

Here tried with a looot of mass and also tried all masses default.

Any help would be much appriciated.

Edited by Reicher

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.