Disabling gravity for a specific object in Matter.js
Asked Answered
B

7

9

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?

Blakeslee answered 6/4, 2016 at 23:18 Comment(1)
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 brm.io/matter-js/docs/classes/World.htmlPotvaliant
R
8

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
        });
    }
});
Rempe answered 2/2, 2018 at 15:56 Comment(3)
Extremely helpful answer, thanks. Fixed the problem I was having.Strapping
This just makes my body spin around in one spot. Help?Dichroism
@SamSverko same here. Replace { x: 0, y: 0 } with body.position to fix. (@Rempe can you update the answer?)Gallaway
U
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;
    }
});
Ucayali answered 18/10, 2016 at 22:44 Comment(0)
I
3

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

body.ignoreGravity = true;
Idun answered 20/4, 2018 at 20:43 Comment(2)
As of which version?Cavalla
Turns out I was wrong, this is a Phaser specific feature and not supported directly by Matter.js. github.com/liabru/matter-js/issues/523Idun
P
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;
            }
        };
Platus answered 14/1, 2021 at 23:39 Comment(1)
What's the best practice to apply this override, without actually touching the original module?Mokas
V
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.

Vibrant answered 9/10, 2016 at 22:13 Comment(0)
D
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.

Derian answered 7/5, 2020 at 1:16 Comment(0)
F
-1

there is an official working example

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

ignoring gravity phaser3 matter physic

Forwent answered 26/8, 2019 at 16:12 Comment(1)
Phaser != MatterDerian

© 2022 - 2024 — McMap. All rights reserved.