Deso2121
Deso2121

Reputation: 99

Libgdx Contact Listener - contact doesn't work both ways

I am developing a game using LibGDX and Box2D, today I implemented coins as dynamic bodies and wanted to make player gain gold by reading contact through my ContactListener.

So far everything was working, here is my example of player colliding with ladder object in the ContactListener class:

@Override
public void beginContact(Contact contact) {
    Fixture fixA = contact.getFixtureA();
    Fixture fixB = contact.getFixtureB();

    int cDef = fixA.getFilterData().categoryBits | fixB.getFilterData().categoryBits;


    switch (cDef) {
        case Constants.PLAYER_BIT | Constants.LADDER_BIT:
            if (fixA.getFilterData().categoryBits == Constants.PLAYER_BIT) {
                    ((HeroKnight) fixA.getUserData()).climbLadder();
            }
            else {
                    ((HeroKnight) fixB.getUserData()).climbLadder();
                }

However, strangely the coin collision only works one way.

case Constants.PLAYER_BIT | Constants.COIN_BIT:
            if (fixA.getFilterData().categoryBits == Constants.PLAYER_BIT) {
                ((CoinTest) fixB.getUserData()).use();
            }

When I add the else statement, as seen below, the game keeps crashing with java.lang.NullPointerException.

case Constants.PLAYER_BIT | Constants.COIN_BIT:
            if (fixA.getFilterData().categoryBits == Constants.PLAYER_BIT) {
                ((CoinTest) fixB.getUserData()).use();
            }
            else  {
                ((CoinTest) fixA.getUserData()).use();
            }

The player class's fixturedef maskbits include coin, and coin class's maskbits include the player (everything is done the same way as with ground, platforms, ladders etc., and the problem only exists here).

I hope I explained this well enough, this is my first question here.

Upvotes: 2

Views: 303

Answers (1)

Deso2121
Deso2121

Reputation: 99

I finally fixed this. There was such a rookie mistake, I totally overlooked it and didn't think that this would create such problems. The solution was just to add "break" statements in the ContactListener. This made it work without any problems:

       switch (cDef) {
        case Constants.PLAYER_BIT | Constants.LADDER_BIT:
            if (fixA.getFilterData().categoryBits == Constants.PLAYER_BIT) {
                    ((HeroKnight) fixA.getUserData()).climbLadder();
            }
            else {
                ((HeroKnight) fixB.getUserData()).climbLadder();
                }
            break;
        case Constants.PLAYER_BIT | Constants.GROUND_BIT:
        case Constants.PLAYER_BIT | Constants.PLATFORM_BIT:
            if (fixA.getFilterData().categoryBits == Constants.PLAYER_BIT) {
                ((HeroKnight) fixA.getUserData()).ground();
            }
            else {
                ((HeroKnight) fixB.getUserData()).ground();
            }
            break;
        case Constants.PLAYER_BIT | Constants.COIN_BIT:
            if (fixA.getFilterData().categoryBits == Constants.PLAYER_BIT) {
                ((CoinTest) fixB.getUserData()).use();
                ((HeroKnight) fixA.getUserData()).collectGold(10);
            }
            else  {
                ((CoinTest) fixA.getUserData()).use();
                ((HeroKnight) fixB.getUserData()).collectGold(10);
            }
            break;
    }
}

Upvotes: 1

Related Questions