liabru / matter-js

a 2D rigid body physics engine for the web ▲● ■
MIT License
16.78k stars 1.96k forks source link

I'm setting the same force with applyForce but the path rarely it's equal. #1167

Closed dFrance closed 3 months ago

dFrance commented 1 year ago

Hi everyone, i'm trying to launch a ball to top, in a plinko game, but i could't launch the ball to the same height even setting the same force with applyForce. Sometimes the ball up 600px, other 800px and rarely do the same path when drop by the plinko.

When i create the ball at the top of the plinko the ball ALWAYS do the same path, always. So i'd like to reproduce this behavior but launching the ball. Anyone has an idea how can i do this?

If you've some doubt let me know to clarify.

liabru commented 1 year ago

Can you try setting runner.isFixed to true and let me know if that solves?

dFrance commented 1 year ago

Hi @liabru, i tried but i didn't success. So i noticed that when i launch the ball with a timeout, e.g 500ms, the ball always do the same path. So i imagine that what you suggested make sense but i couldn't implement. Follow some parts of my code.

Here i create the engine and render.

const engine = Engine.create();
const renderer = Render.create({
        element: sectionTag,
        engine: engine,
        options: {
          width: canvaW,
          height: canvaH,
          background: backgroundImageCanvas
            ? backgroundImageCanvas
            : backgroundColorCanvas,
          backgroundSize: "100%",
          backgroundPosition: "-8px 1px",
          backgroundRepeat: "no-repeat",
          showDebug: false,
          wireframes: false,
          pixelRatio: window.devicePixelRatio,
        },
      });

and at the final i run

var runner = Runner.create({
        isFixed: true,
      });

      Render.run(renderer);
      Runner.run(runner, engine);

Am i doing something wrong? I'll try read again the doc. Anyway thanks for the tip.

mateusgamba commented 1 year ago

I'm facing the same issue :(

liabru commented 1 year ago

Do you have a link to an example I could try? Are you launching the ball exactly the same every time?

dFrance commented 1 year ago

Hi @liabru, sorry for delay. I had a lot tasks last weeks. Follow my link to you see. I'm launching the ball with the same force, from the same position and setup the runner with isFixed: true, but many times i got different simulations. Do you know what i could do wrong. I need to get the same simulation independent the time that i launch. https://codepen.io/difrance/pen/rNKrxzz

liabru commented 1 year ago

This is due to changing timeScale which is actually changing the timestep so it's no longer fixed. Removing that from your code seems to give the same results:

    function launchPinball() {
    // var timescale = ((1000 / runner.fps) / 16).toFixed(2);
    // engine.timing.timeScale = timescale;
        updateScore(0);
        Matter.Body.setPosition(pinball, { x: 465, y: 765 });
        Matter.Body.setVelocity(pinball, { x: 0, y: -35 });
        Matter.Body.setAngularVelocity(pinball, 0);
    }

I've made a note to improve the docs around this.

dFrance commented 1 year ago

@liabru when i removed this part of code and i faced two issues. The first is that i don't have the same simulation e.g in 10 times. The second is when you use different frame rate you have different simulation between each frame rate. So in 60hz you will have simulations similar and close, still not equal. However if you change to another monitor, 120hz, you'll have another power, gravity another simulation, for my game it is vital. I updated the code to you test.

liabru commented 3 months ago

As of 0.20.0 there is now built in Matter.Runner support by default for fixed timestep with high refresh displays see https://github.com/liabru/matter-js/pull/1300.

Therefore hopefully this will now be much easier. Thanks for the report!