Search code examples
androidbox2dlibgdxgame-physics

LibGDX - Box2D: using MouseJoint for 2 fingers


I want to control the box by 2 fingers like below:

enter image description here

I have basic MouseJoint implementation:

public class MyMouseJoint{

OrthographicCamera cam; 
World world;

Body groundBody ;   
public MouseJoint mouseJoint = null;    
Body hitBody = null;    
Vector2 target = new Vector2(); 
Vector3 testPoint = new Vector3();

QueryCallback callback = new QueryCallback() {
    @Override
    public boolean reportFixture (Fixture fixture) {
        // if the hit fixture's body is the ground body we ignore it            
        if (fixture.getBody() == groundBody) return true;

        // if the hit point is inside the fixture of the body
        // we report it
        if (fixture.testPoint(testPoint.x, testPoint.y)) {
            hitBody = fixture.getBody();
            return false;
        } else
            return true;
    }
};

public MyMouseJoint(OrthographicCamera cam, World world, Body groundBody){
    this.cam=cam;
    this.world=world;
    this.groundBody = groundBody;  
}

    //USE THIS FUNCTION IN touchDown
public void createMouseJoint(float x, float y){
    // translate the mouse coordinates to world coordinates
            testPoint.set(x, y, 0);
            cam.unproject(testPoint);

            // ask the world which bodies are within the given
            // bounding box around the mouse pointer
            hitBody = null;
            world.QueryAABB(callback, testPoint.x - 0.1f, testPoint.y - 0.1f, testPoint.x + 0.1f, testPoint.y + 0.1f);

            if (hitBody != null) {
                MouseJointDef def = new MouseJointDef();
                def.bodyA = groundBody;
                def.bodyB = hitBody;
                def.collideConnected = true;
                def.target.set(testPoint.x, testPoint.y);
                def.maxForce = 10000.0f * hitBody.getMass();
                def.frequencyHz=100;
                def.dampingRatio=0;

                mouseJoint = (MouseJoint)world.createJoint(def);
                hitBody.setAwake(true);
            }

}

    //USE THIS FUNCTION IN touchDragged
public void dragMouseJoint(float x, float y){
    if (mouseJoint != null) {
        cam.unproject(testPoint.set(x, y, 0));
        mouseJoint.setTarget(target.set(testPoint.x, testPoint.y));
    }
}

    //USE THIS FUNCTION IN touchUp
public void releaseMouseJoint(){
    if (mouseJoint != null) {
        world.destroyJoint(mouseJoint);
        mouseJoint = null;
    }
}
}

How can modify this class for using 2 fingers?


Solution

  • What you can do is create an array of Body and initialize hitbody[] with the pointer of your touch. you can change the above code to following code.

    In the following function the varable pointer is the pointer if your current touch

    public class MyMouseJoint{
    
    OrthographicCamera cam; 
    World world;
    
    Body groundBody ;   
    public MouseJoint mouseJoint[] = new MouseJoint[2];    
    Body hitBody[] = new Body[2];    
    Vector2 target = new Vector2(); 
    Vector3 testPoint = new Vector3();
    
    Body tempBody;
    
    QueryCallback callback = new QueryCallback() {
        @Override
        public boolean reportFixture (Fixture fixture) {
            // if the hit fixture's body is the ground body we ignore it            
            if (fixture.getBody() == groundBody) return true;
    
            // if the hit point is inside the fixture of the body
            // we report it
            if (fixture.testPoint(testPoint.x, testPoint.y)) {
                tempBody = fixture.getBody();
                return false;
            } else
                return true;
        }
    };
    public MyMouseJoint(OrthographicCamera cam, World world, Body groundBody){
        this.cam=cam;
        this.world=world;
        this.groundBody = groundBody;  
    }
    
        //USE THIS FUNCTION IN touchDown
    public void createMouseJoint(float x, float y,int pointer){
        // translate the mouse coordinates to world coordinates
                testPoint.set(x, y, 0);
                cam.unproject(testPoint);
    
                // ask the world which bodies are within the given
                // bounding box around the mouse pointer
                hitBody[pointer] = null;
    
                world.QueryAABB(callback, testPoint.x - 0.1f, testPoint.y - 0.1f, testPoint.x + 0.1f, testPoint.y + 0.1f);
                hitBody[pointer] = tempBody;
    
                if (hitBody[pointer] != null) {
                    MouseJointDef def = new MouseJointDef();
                    def.bodyA = groundBody;
                    def.bodyB = hitBody[pointer];
                    def.collideConnected = true;
                    def.target.set(testPoint.x, testPoint.y);
                    def.maxForce = 10000.0f * hitBody[pointer].getMass();
                    def.frequencyHz=100;
                    def.dampingRatio=0;
    
                    mouseJoint[pointer] = (MouseJoint)world.createJoint(def);
                    hitBody[pointer].setAwake(true);
                }
    
    }
    
        //USE THIS FUNCTION IN touchDragged
    public void dragMouseJoint(float x, float y,int pointer){
        if (mouseJoint[pointer] != null) {
            cam.unproject(testPoint.set(x, y, 0));
            mouseJoint[pointer].setTarget(target.set(testPoint.x, testPoint.y));
        }
    }
    
        //USE THIS FUNCTION IN touchUp
    public void releaseMouseJoint(int pointer){
        if (mouseJoint[pointer] != null) {
            world.destroyJoint(mouseJoint[pointer]);
            mouseJoint[pointer] = null;
        }
    }
    }