Search code examples
libgdxbox2dcontacts

Libgdx Box2d Jumping through


I want to make a jump like in the Mario game. When you are under the platform and you jump, you can then pass through the collider.

When a player's velocity is going down, colliders should wake up. I know that I should use ContactListener, but when I'm using the contact.setEnable(false) method nothing happens.

My contact listener (ground checker works perfectly)

world.setContactListener(new ContactListener() {
        @Override
        public void beginContact(Contact contact) {
            if(contact.getFixtureA().getBody().getUserData() == "ground" && contact.getFixtureB().getUserData() == "groundChecker"){
                character.isGrounded = true;
                System.out.println(" Colliding");
            }
        }

        @Override
        public void endContact(Contact contact) {

        }

        @Override
        public void preSolve(Contact contact, Manifold oldManifold) {
        }

        @Override
        public void postSolve(Contact contact, ContactImpulse impulse) {

        }
    });

What and where should I put to get effect like this.

enter image description here

enter image description here

Collider should have only one side, have somebody deal with it?


Solution

  • Found a solution I hope it will be helpfull.

    world.setContactListener(new ContactListener() {
            @Override
            public void beginContact(Contact contact) {
                //setting isGrounded boolean variable in our character class, but we need to check "player" velocity, because we don't want to enable jumping when only ground will passed througt
                if(contact.getFixtureA().getBody().getUserData() == "ground" && contact.getFixtureB().getUserData() == "groundChecker" && (contact.getFixtureB().getBody().getLinearVelocity().y < 0 || contact.getFixtureB().getBody().getLinearVelocity().y == 0)){
                    character.isGrounded = true;
                }
            }
    
            @Override
            public void endContact(Contact contact) {
    
            }
    
            @Override
            public void preSolve(Contact contact, Manifold oldManifold) {
                //we have to disable contact when our "player" fixture collide with "ground" fixture
                if(contact.getFixtureA().getBody().getUserData() == "ground" && contact.getFixtureB().getUserData() == "player"){
                    contact.setEnabled(false);
                }
                //and we need to disable contact when our "groundChecker" will collide with "ground" and we need to check what velocity.y of player body is, when it is bigger than 0 contact should be falsed
                if(contact.getFixtureA().getBody().getUserData() == "ground"  && contact.getFixtureB().getUserData() == "groundChecker" && contact.getFixtureB().getBody().getLinearVelocity().y > 0){
                    contact.setEnabled(false);
                }
            }
    
            @Override
            public void postSolve(Contact contact, ContactImpulse impulse) {
    
            }
        });
    

    We have to disable contact when our "player" fixture collide with "ground" fixture. Like this.

    if(contact.getFixtureA().getBody().getUserData() == "ground" && contact.getFixtureB().getUserData() == "player"){
                    contact.setEnabled(false);
    }
    

    And we need to disable contact when our "groundChecker" will collide with "ground" and we need to check what velocity.y of player body is, when it is bigger than 0, contact should be falsed.

    if(contact.getFixtureA().getBody().getUserData() == "ground"  && contact.getFixtureB().getUserData() == "groundChecker" && contact.getFixtureB().getBody().getLinearVelocity().y > 0){
                    contact.setEnabled(false);
    }
    

    Here is a demo of the above solution:

    enter image description here