I am making simple game - kind of race game, where you see from the "sky" your sprites with circle Box2D bodies attached and they have to move along some path/track. My idea was to detect if they will go out of the path by detecting their contact with invisible body (set as sensor) covering the path. My code looks like that:
ArrayList<Vector2> UniqueBodyVertices = new ArrayList<Vector2>();
UniqueBodyVertices.addAll((List<Vector2>) ListUtils.toList(new Vector2[] {
new Vector2(-432, -95),
new Vector2(-326, -22),
new Vector2(-327, 17),
new Vector2(-440, 96),
new Vector2(-444, 238),
new Vector2(-393, 290),
...
new Vector2(-303, -279),
new Vector2(-425, -285)
}));
List<Vector2> UniqueBodyVerticesTriangulated = new EarClippingTriangulator().computeTriangles(UniqueBodyVertices);
float[] meshTriangles = new float[UniqueBodyVerticesTriangulated.size() * 3];
for(int i = 0; i < UniqueBodyVerticesTriangulated.size(); i++){
meshTriangles[i*3] = UniqueBodyVerticesTriangulated.get(i).x;
meshTriangles[i*3+1] = UniqueBodyVerticesTriangulated.get(i).y;
UniqueBodyVerticesTriangulated.get(i).mul(1/PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT);
}
Sprite bg = new Sprite(0, 0, 1024, 768, ResourceManager.getInstance().mBackGroundRegion, getVertexBufferObjectManager());
Mesh mesh = new Mesh(0, 0, meshTriangles, UniqueBodyVerticesTriangulated.size(), DrawMode.LINE_STRIP , getVertexBufferObjectManager());
mesh.setColor(Color.RED);
Body meshBody = PhysicsFactory.createTrianglulatedBody(physicsWorld, mesh, UniqueBodyVerticesTriangulated, BodyType.StaticBody, PhysicsFactory.createFixtureDef(0f, 0f, 0f, true));
physicsWorld.registerPhysicsConnector(new PhysicsConnector(mesh, meshBody, true, true));
meshBody.setUserData("trasa");
I deleted some of the vertices just to shorten the code here. I also know that there should be BodyType.Triangles
and not BodyType.LineStrip
- it is just for checking bodies behaviour and does not change anything. Anyway what I pasted here works, and my path is covered with body like I want to, but the problem is detecting the contact. I have another part of code for ContactListener
:
EDIT Added full ContactListener code.
private ContactListener createContactLister(){
ContactListener contactListener = new ContactListener() {
@Override
public void preSolve(Contact contact, Manifold oldManifold) {
// TODO Auto-generated method stub
}
@Override
public void postSolve(Contact contact, ContactImpulse impulse) {
// TODO Auto-generated method stub
}
@Override
public void endContact(Contact contact) {
final Fixture x1 = contact.getFixtureA();
final Fixture x2 = contact.getFixtureB();
if(x2.getBody().getUserData().equals("kapselBialy")&&x1.getBody().getUserData().equals("trasa"))
{
if(contact.isTouching() == false){
mScene.setBackground(new Background(Color.RED));
}
}
if(x2.getBody().getUserData().equals("trasa")&&x1.getBody().getUserData().equals("kapselBialy"))
{
if(contact.isTouching() == false){
mScene.setBackground(new Background(Color.RED));
}
}
}
@Override
public void beginContact(Contact contact) {
final Fixture x1 = contact.getFixtureA();
final Fixture x2 = contact.getFixtureB();
if(x2.getBody().getUserData().equals("kapselBialy")&&x1.getBody().getUserData().equals("trasa"))
{
if(contact.isTouching() == true){
mScene.setBackground(new Background(Color.CYAN));
}
}
if(x2.getBody().getUserData().equals("trasa")&&x1.getBody().getUserData().equals("kapselBialy"))
{
if(contact.isTouching() == true){
mScene.setBackground(new Background(Color.CYAN));
}
}
}
};
return contactListener;
}
The problem is that inside my track body there are a lot of trinagles and when my player body leaves one of them and goes inside another it is detected as leaving a sensor area. From outside the whole path is treated as one body. So if my player moves from outside the first triangle it contacts is treated as sensor, but when in the next move it goes to another triangle it is detected as leaving a track body and endContact` fires up. I attach image from the project.As you can see there are triangles created by the triangulation. My sprite detects some of them as a body of the path, and some not. So how can I do that so all of the triangles are treated as one body? Just to add: If I swith the path body as not a sensor, and try to bounce my sprite from outside it works: the path body is solid from outside on whole length, but not inside of the path body. Hope it is more clear now.