with tutorial studio how game development java android box2d libgdx physics

java - tutorial - Box2D a través de libGDX: ¿Cómo crear un MouseJoint por cuerpo para toques de Android por separado?



libgdx android studio tutorial (1)

Que tal estáis todos,

Gracias por tu tiempo.

Estoy haciendo un clon de Pong, y quiero restringir Box2D a dos máximos de MouseJoints; un máximo de MouseJoint por paddle. Los MouseJoints deben crearse solo si uno de los dos toques del usuario cae dentro de cualquiera de los dos límites de la paleta.

Estoy obteniendo un resultado extraño con mi código. Si mi primer toque aterriza dentro de la paleta izquierda y mi segundo toque cae fuera de cualquiera de las paletas, se crea una segunda MouseJoint en la paleta izquierda (ver imagen adjunta).

Nota: Además de los dos MouseJoints en la paleta izquierda, hay dos PrismaticJoints en la imagen; uno adjunto a cada paleta.

En vano, probé todos los algoritmos que pude pensar o adaptar del código de otras personas.

Si se publicara un ejemplo de solución de código o un enlace, estaría muy agradecido.

Aquí está mi código:

public class MyScreen implements Screen, InputProcessor{ /*========some variables and methods omitted for clarity========*/ /*multiple mouse joint experiment*/ public MouseJoint mouseJoint[] = new MouseJoint[2]; Body hitBody[] = new Body[2]; Body tempBody; public MyScreen(Pong game) { this.game = game; } /*---------------------Screen interface methods--------------------------*/ //methods omitted for clarity /*---------------------end Screen interface methods----------------------*/ /*---------------------InputProcessor interface methods------------------*/ @Override public boolean keyDown(int keycode) { return false; } @Override public boolean keyUp(int keycode) { return false; } @Override public boolean keyTyped(char character) { return false; } @Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { testPoint.set(screenX, screenY, 0); camera.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 - 1.0f, testPoint.y - 1.0f, testPoint.x + 1.0f, testPoint.y + 1.0f); hitBody[pointer] = tempBody; // if we hit something we create a new mouse joint // and attach it to the hit body. if (hitBody[pointer] != null) { MouseJointDef def = new MouseJointDef(); def.bodyA = groundBody; def.bodyB = hitBody[pointer]; def.collideConnected = true; def.target.set(hitBody[pointer].getPosition().x, hitBody[pointer].getPosition().y); def.maxForce = 3000.0f * hitBody[pointer].getMass(); mouseJoint[pointer] = (MouseJoint)world.createJoint(def); hitBody[pointer].setAwake(true); } else { } return false; } @Override public boolean touchUp(int screenX, int screenY, int pointer, int button) { if (mouseJoint[pointer] != null) { world.destroyJoint(mouseJoint[pointer]); mouseJoint[pointer] = null; } return false; } /**a temporary vector for delta target destination during touchDragged() method**/ Vector2 target = new Vector2(); @Override public boolean touchDragged(int screenX, int screenY, int pointer) { if (mouseJoint[pointer] != null) { camera.unproject(testPoint.set(screenX, screenY, 0)); mouseJoint[pointer].setTarget(target.set(testPoint.x, testPoint.y)); } return false; } @Override public boolean mouseMoved(int screenX, int screenY) { return false; } @Override public boolean scrolled(int amount) { return false; } /*----------------end InputProcessor interface methods------------------*/ /*------------------------helper methods------------------------------------*/ /*android screen touch vector for a mouse joint*/ Vector3 testPoint = new Vector3(); //we instantiate this vector and the callback here so we don''t irritate the GC 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 (fixture.testPoint(testPoint.x, testPoint.y)) { tempBody = fixture.getBody(); return false; } else return true; } }; /*------------------------end helper methods-------------------------------*/ }


Por lo que puedo ver, el tempBody nunca se restablece a nulo. Lo que eso significa es que la primera vez que toca el pad establece el tempBody en la paleta tocada y luego, cuando presiona fuera del cuerpo, la devolución de llamada no encontrará un nuevo cuerpo pero no restablecerá el testBody a nulo, por lo tanto, cuando asigne testBody a hitBody[pointer] lo está estableciendo en la primera paleta.

La forma en que debería verse su función de toque es:

@Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { testPoint.set(screenX, screenY, 0); camera.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 - 1.0f, testPoint.y - 1.0f, testPoint.x + 1.0f, testPoint.y + 1.0f); hitBody[pointer] = tempBody; // if we hit something we create a new mouse joint // and attach it to the hit body. if (hitBody[pointer] != null) { MouseJointDef def = new MouseJointDef(); def.bodyA = groundBody; def.bodyB = hitBody[pointer]; def.collideConnected = true; def.target.set(hitBody[pointer].getPosition().x, hitBody[pointer].getPosition().y); def.maxForce = 3000.0f * hitBody[pointer].getMass(); mouseJoint[pointer] = (MouseJoint)world.createJoint(def); hitBody[pointer].setAwake(true); } else { } tempBody = null; return false;

}

De esta forma, el tempBody siempre se restablece a nulo después de su uso.