简体   繁体   中英

What to do on collision in AndEngine with Box2d

In Android with AndEngine and Box2d extension, I use the following code to create sprites and set their attributes (physics etc.):

mPlayer1_Sprite = new Sprite(0, BASELINE_Y, mResourcesManager.mPlayer1_TextureRegion, mVertexManager) {
    @Override
    protected void preDraw(GLState pGLState, Camera pCamera) {
        super.preDraw(pGLState, pCamera);
        pGLState.enableDither();
    }
};
Body body = PhysicsFactory.createBoxBody(mPhysicsWorld, mPlayer1_Sprite, BodyType.DynamicBody, PhysicsFactory.createFixtureDef(10.0f, 0.0f, 0.5f));
body.setUserData(BODY_TYPE_PLAYER_1);
mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(mPlayer1_Sprite, body, true, false));
mPlayer1_Sprite.setUserData(body);

(same code for other players and game objects)

Now, for collisions, I use this piece of code:

private boolean isCollision(final Fixture x1, final Fixture x2, final String type1, final String type2) {
    return (x1.getBody().getUserData() != null && x2.getBody().getUserData() != null) && ((x1.getBody().getUserData().equals(type1) && x2.getBody().getUserData().equals(type2)) || (x1.getBody().getUserData().equals(type2) && x2.getBody().getUserData().equals(type1)));
}

@Override
public void beginContact(Contact contact) {
    final Fixture x1 = contact.getFixtureA();
    final Fixture x2 = contact.getFixtureB();
    if (isCollision(x1, x2, BODY_TYPE_PLAYER_1, BODY_TYPE_PLAYER_2)) {
        ((Body) mPlayer1_Sprite.getUserData()).applyForce(3.0f, 1.0f, 0, 0);
    }
    if (isCollision(x1, x2, BODY_TYPE_PLAYER_1, BODY_TYPE_WALL)) {
        ((Body) mPlayer1_Sprite.getUserData()).applyForce(3.0f, 1.0f, 0, 0);
    }
    if (isCollision(x1, x2, BODY_TYPE_PLAYER_2, BODY_TYPE_WALL)) {
        ((Body) mPlayer1_Sprite.getUserData()).applyForce(3.0f, 1.0f, 0, 0);
    }
}

@Override
public void endContact(Contact contact) { }

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

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

That should be correct so far, right? But what should I do if I detected the collision here? Is applying a force to the body correct? And what values do I need to use if I want that:

  • Players both bounce back if they collide with each other.
  • Players that run against a wall bounce back as well.
  • When colliding with the ground, the player stops, but only one time, as the player is then standing on the ground you should not apply forces continually to the player, should you?

Box2d is applying physical updates (collisions, friction, gravity etc.) anyway, right? So what do you do if you want to add custom physical calculations? Do you have to switch off Box2d's calculations and use it for collision detection only?

since you don't want box2d to calculate the collision physically (at least for some combinations) you should filter these collisions and calculate them (as you already do). for collision filtering see this tutorial .

physical calculated collisions would work the way, Physic works ;-) -> two objects collide and get an impulse (linear+angular) depending on their weight/density, the collision point, their speed and surface friction - meaning your bounce-back effect could result in rotations etc.

since i think (and read from your other post), your world boundaries are static and your player(s) can move, i recommend you to use collision filtering (as mentioned above).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM