0
\$\begingroup\$

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.

enter image description here

\$\endgroup\$
  • \$\begingroup\$ as far as i can tell you are looking for something like a IsTouching() method rather than EndContant, you haven't found something like that yet ? like contact.IsTouching ? \$\endgroup\$ – dimitris93 Jan 17 '15 at 14:24
  • \$\begingroup\$ Hmmm, so I should not use buid in methods of contactlistener and use isTouching somehow instead? \$\endgroup\$ – Łukasz Motyczka Jan 17 '15 at 14:46
0
\$\begingroup\$

SOLVED! Ok so the idea to check if our player body left the body of our path is to count borders playerbody passes. So in contactlistener we make beginContact to add one to some int variable (lets say bordersPassed) and endContact subtracts one from it. So when our player is inside path this variable will always be bigger than 0. When it leaves path it will be 0. And thats what we check.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.