7

I'm working on a project using Matter.js where I want gravity enabled in general, but I want to be able to disabled and re-enable it for a single object at certain times. I do not want to set that object as static, because I want the physics engine to handle it in other ways, I just don't want gravity to affect it.

I found this question that deals with disabling gravity in general, but as I said I want gravity to work for most objects. Is there a simple way to do this?

Community
  • 1
  • 1
Teale Fristoe
  • 71
  • 1
  • 3
  • could you load the object into a new world that is contained within the main world? from browsing the API quickly it looks like this would be the only way http://brm.io/matter-js/docs/classes/World.html – tmaxxcar Apr 06 '16 at 23:33

7 Answers7

7

Here is a simple code snippet that you could have toggle on/off to accomplish what you're asking (where body is the object that should ignore gravity, and noGravity is a boolean that can be toggled to turn it on and off):

Events.on(engine, 'beforeUpdate', function() {
    var gravity = engine.world.gravity;

    if (noGravity) {
        Body.applyForce(body, body.position, {
            x: -gravity.x * gravity.scale * body.mass,
            y: -gravity.y * gravity.scale * body.mass
        });
    }
});
Derek
  • 298
  • 3
  • 12
6

Disable the built in gravity and then apply your own selectively, something like this but filter only the bodies you want:

engine.world.gravity.scale = 0;

Events.on(engine, 'beforeUpdate', function() {
    var bodies = Composite.allBodies(engine.world);

    for (var i = 0; i < bodies.length; i++) {
        var body = bodies[i];

        if (body.isStatic || body.isSleeping)
            continue;

        body.force.y += body.mass * 0.001;
    }
});
liabru
  • 962
  • 8
  • 9
3

I know this is an old question, but nowadays you can use this:

body.ignoreGravity = true;
Hexus
  • 340
  • 4
  • 9
1

I found that was very easy to implement that. Just look for the Engine._bodiesApplyGravity function on the Matter source code and just put whatever condition you need for a body to be excluded.

        Engine._bodiesApplyGravity = function (bodies, gravity) {
            var gravityScale = typeof gravity.scale !== 'undefined' ? gravity.scale : 0.001;

            if ((gravity.x === 0 && gravity.y === 0) || gravityScale === 0) {
                return;
            }

            for (var i = 0; i < bodies.length; i++) {
                var body = bodies[i];

                // I just added body.ignoreGravity
                if (body.isStatic || body.isSleeping || body.ignoreGravity)  
                    continue;

                // apply gravity
                body.force.y += body.mass * gravity.y * gravityScale;
                body.force.x += body.mass * gravity.x * gravityScale;
            }
        };
  • What's the best practice to apply this override, without actually touching the original module? – Kalnode May 06 '23 at 22:31
0

This seems to provide a counter force. I'm not sure where the 200 is coming from it just worked. Maybe the engine calculates force twice a cycle.

playerBody.force.y = -engine.world.gravity.y / 200;

You will have to run it every cycle to keep it up.

0

In my case I wanted an object to follow the mouse. Setting isStatic: true made gravity not apply to give me full control over the object's position.

Zach Saucier
  • 24,871
  • 12
  • 85
  • 147
-1

there is an official working example

this.matter.add.image(100, 100, 'block').setIgnoreGravity(true);

ignoring gravity phaser3 matter physic