Creating Sensors:
First of all, lets explain where can we use "sensor" and what exactly it is. Quoting official box2d manual: A sensor is a fixture that detects collision but does not produce a response.You can flag any fixture as being a sensor. Sensors may be static or dynamic. Remember that you may have multiple fixtures per body and you can have any mix of sensors and solid fixtures.
1. Example of usage:
Lets say we want to create some kind of zone/area in our game, when our player enter this area, some kind of action should be executed (ex. displaying message etc.)
Lets say we want to create some kind of zone/area in our game, when our player enter this area, some kind of action should be executed (ex. displaying message etc.)
final Sprite area = new Sprite(x, y, 100, 300, textureRegion, vbo); FixtureDef areaFixtureDef = PhysicsFactory.createFixtureDef(0, 0, 0); areaFixtureDef.isSensor = true; Body b = PhysicsFactory.createBoxBody(physicsWorld, area, BodyType.StaticBody, areaFixtureDef); scene.attachChild(area);
As you can see, we have created new Sprite which is our visual zone/area representation, and created new body for physical representation, to make this body act like sensor (overlapping with different bodies) we set isSensor flag to true in our FixtureDef object.
Now main question, how can we detect when our player`s body entered our zone/area created above? As always to handle contacts between bodies we will use Contact Listener (click for article) Make sure you understand how does it work, if not, check it again.
Now main question, how can we detect when our player`s body entered our zone/area created above? As always to handle contacts between bodies we will use Contact Listener (click for article) Make sure you understand how does it work, if not, check it again.
- we have to serUserData for our area sensor body
- in beginContact() we have to put check
- craete new field, boolean isInsideZoone = false;
- set this boolean to true if contact occurs - beginContact()
- set this boolean to false on endContact()
private boolean isInsideZoone = false; private ContactListener createContactListener() { ContactListener contactListener = new ContactListener() { @Override public void beginContact(Contact contact) { final Fixture x1 = contact.getFixtureA(); final Fixture x2 = contact.getFixtureB(); if(x2.getBody().getUserData().equals("player")&&x1.getBody().getUserData().equals("area")) { isInsideZoone = true; //action on enter } } @Override public void endContact(Contact contact) { final Fixture x1 = contact.getFixtureA(); final Fixture x2 = contact.getFixtureB(); if(x2.getBody().getUserData().equals("player")&&x1.getBody().getUserData().equals("area")) { isInsideZoone = false; //action on exit } } @Override public void preSolve(Contact contact, Manifold oldManifold) { } @Override public void postSolve(Contact contact, ContactImpulse impulse) { } }; return contactListener; }
Note that in this example we used "area" as user data of our zone/area body, and "player" for our player`s body. With this simple way, we can detect whenever player is inside of our zone/area or not, and execute actions, depends on state, really useful for wide area of different purposes etc.
HTML Comment Box is loading comments...