schteppe / p2.js

JavaScript 2D physics library
Other
2.64k stars 330 forks source link

Disable relaxation / Set relexation = 0 error #187

Closed dobin closed 8 years ago

dobin commented 8 years ago

I want to disable relaxation completely (because i move the body manually by updating position[0] / [1], and dont want it to rebound upon collision). When i set world.setGlobalRelaxation=1, the player body still moves into wall bodies and rebounds a few pixels. If i set relaxation = 0, strange things start to happen (e.g. bouncing forth and back).

Edit: e.g. i want to prevent the player body moving into the other body and then bounce back, like here: http://phaser.io/sandbox/edit/qbqGKkLI

schteppe commented 8 years ago

If you want same settings, use them?

Keep in mid there will always be a small penetration and rebound, to make the simulation work.

By the way, you're probably doing something fishy if you set position... What mechanics do you want in the end? Move a character around?

dobin commented 8 years ago

Thanks for your answer. But i dont relly understand your first sentence.

Anyway, yes I use (or to be more exact, "misuse") P2 in NodeJS to implement the server part of a Phaser game. ATM I send the player key presses/releases to the server, record the time changes with Date().getTime() in an update() loop, and manually update the position of the character bodies (I do the same on the Phaser client part). So basically I just want the collision detection part of P2 ;-). I'm completely aware that this is indeed fishy, and not how the library is intended to be used. But it works pretty well currently (near pixel-perfect synchronization with the client), except that little penetration of bodies when the character is forcing himself to walk into a wall or other static objects. Edit: The objects should just stop before going into each other. Like a character walking on the ground. He should not sink in.

It would be very nice to be able to completely disable that small penetration, and I assumed that could be achieved by setting relaxation = 0, or something like 0.00001 :-) Sadly, this seems to be unspecified behavior (as afaik relaxation is something like the amount of frames it takes to rebound, and having 0 frames is bad).

If that penetration is inherent part of the simulation to make it work and can't be easily disabled, i'm a sad panda and will close this issue :-)

schteppe commented 8 years ago

Nevermind the first sentence :P

Oh, so you move the sprite by setting the position? Don't do that :)

A simple approach is using force instead:

    if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT))
    {
        keys.left = 1;
        ship.body.force.x -= 10000;
    } else {
        keys.left = 0;   
    }

    if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
    {
        keys.right = 1;
        ship.body.force.x += 10000;
    }  else {
        keys.right = 0;
    }

    if (game.input.keyboard.isDown(Phaser.Keyboard.UP))
    {
        keys.up = 1;
        ship.body.force.y -= 10000;
    } else {
        keys.up = 0;
    }

    if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN))
    {
        keys.down = 1;
        ship.body.force.y += 10000;
    } else {
        keys.down = 1;
    }

Using this code in update(), the character seems to do virtually no rebound.

You should never modify the position or velocity vectors that comes out from a physics engine. This destroys the simulation (in your case, you got a weird rebound effect). Instead, use force, impulse, or constraints.

I hope this helps :)

dobin commented 8 years ago

Sadly, i have to update the positions of the objects manually. With the latency between client and server, when the server is receiving a "stop movement" command, the object on the server is already like 100ms (the ping) in to the future at the wrong location, and has to be manually moved back.

But yes, my usage is clearly wrong :-) I'll probably use a pure-collision detection library, like rbush. Thanks anyway, and keep up the good work.