Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how should i set the max velocity so that wall does not pass through the walls? #840

Closed
kushal0406 opened this issue Mar 23, 2020 · 5 comments
Labels

Comments

@kushal0406
Copy link

Initially

1

When I press the down key for a long time. Ball becomes so fast that it goes through the wall and reaches the bottom like shown below

2

Also if ball strikes the borders with a high speed  it disappears and cannot be brought back.

If I set a maximum value for the velocity what should should be the max velocity? 

`document.addEventListener('keydown', event =>{

const {x,y} = ball.velocity;
if(event.keyCode === 87 || event.keyCode === 38){
console.log('Move the ball Up')
Body.setVelocity(ball, {x, y:y-5})
}
if(event.keyCode === 83 || event.keyCode === 40){
console.log('Move the ball down')
Body.setVelocity(ball, {x, y:y+5})
}
if(event.keyCode === 68 || event.keyCode === 39){
console.log('Move the ball right')
Body.setVelocity(ball, {x:x+5, y})
}
if(event.keyCode === 65 || event.keyCode === 37){
console.log('Move the ball left')
Body.setVelocity(ball, {x:x-5, y})
}
})`

@michael-garofalo
Copy link

I'm not understanding how you're setting Velocity.

There are usually four parts...
https://brm.io/matter-js/docs/classes/Body.html#method_setVelocity

  • x:
  • the X value
  • y:
  • the Y value

{ x: xSpeed, y: ySpeed }

It looks like you're setting up 4-way controls. If the ball is moving left or right, why not change the "y" speed to "0" instead?

I use Hype and Matter.js, so it might be different for me, but I usually have be specific with both X & Y values. If I only want to change the Y value, I get (getVelocity) the current X value before using setVelocity. If I simply put "x" instead of "x: 0", I get this...

ReferenceError: Can't find variable: x

Anyway, that's how I do it. While matter.js doesn't have CCD, at least not yet, if the speeds are slow enough, it should be good. Here's an example that is very similar to your project...

https://photics.com/games/picopede/

Picopede's speed is set to 2.5. You're using 5, which is faster, but doesn't seem too fast — not for Picopede. I tried setting Picopede's speed to 5 and it was OK. Perhaps the problem is that the walls are too thin. 🤔

@AsishRaju
Copy link

@michael-garofalo walls being a thin is not a problem i even tried of setting "x:0" for setting velocity when i am just moving in "y" direction but the problem mentioned by @kushal0406 still exists

I am afraid that this is a famous problem called tunneling and still an open issue since 2014,
more on this issue here #5 , sad thing is @liabru is still trying to work this out, i hope he does it.

Simulating Physics in computational world is very hard

@liabru
Copy link
Owner

liabru commented Sep 12, 2020

As mentioned it looks like your problem is most likely a combination of:

  • there's currently no CCD (I know, I know)
  • bodies are too thin (make them thicker)
  • bodies are too fast (slow them down)
  • timestep is too large (use a smaller timestep and multiple updates per frame)

You should implement your own checks (e.g. do a ray cast) before letting the player move if possible.

I should say too though that most CCD implementations will still not be a magic bullet and will have edge cases, so unfortunately satisfying the above problems too is always recommended.

@bozhich
Copy link

bozhich commented Oct 16, 2020

With a bit thicker walls, limiting the velocity may do the trick

For example:

        const limitMaxSpeed = () => {
            let maxSpeed = 1;
            if (body.velocity.x > maxSpeed) {
                Body.setVelocity(body, { x: maxSpeed, y: body.velocity.y });
            }
        
            if (body.velocity.x < -maxSpeed) {
                Body.setVelocity(body, { x: -maxSpeed, y: body.velocity.y });
            }
        
            if (body.velocity.y > maxSpeed) {
                Body.setVelocity(body, { x: body.velocity.x, y: maxSpeed });
            }
        
            if (body.velocity.y < -maxSpeed) {
                Body.setVelocity(body, { x: -body.velocity.x, y: -maxSpeed });
            }
        }
        Events.on(engine, 'beforeUpdate', limitMaxSpeed);

@BataevDaniil
Copy link

BataevDaniil commented Jan 8, 2024

With a bit thicker walls, limiting the velocity may do the trick

For example:

        const limitMaxSpeed = () => {
            let maxSpeed = 1;
            if (body.velocity.x > maxSpeed) {
                Body.setVelocity(body, { x: maxSpeed, y: body.velocity.y });
            }
        
            if (body.velocity.x < -maxSpeed) {
                Body.setVelocity(body, { x: -maxSpeed, y: body.velocity.y });
            }
        
            if (body.velocity.y > maxSpeed) {
                Body.setVelocity(body, { x: body.velocity.x, y: maxSpeed });
            }
        
            if (body.velocity.y < -maxSpeed) {
                Body.setVelocity(body, { x: -body.velocity.x, y: -maxSpeed });
            }
        }
        Events.on(engine, 'beforeUpdate', limitMaxSpeed);

This solution without bug and simpler

    const limitMaxSpeed = (event) => {
      event.source.world.bodies.forEach((body) => {
        let maxSpeed = 10
        Matter.Body.setVelocity(body, {
          x: Math.min(maxSpeed, Math.max(-maxSpeed, body.velocity.x)),
          y: Math.min(maxSpeed, Math.max(-maxSpeed, body.velocity.y)),
        })
      })
    }
    Matter.Events.on(engine.current, 'beforeUpdate', limitMaxSpeed)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants