I tried almost everything but nothing works.
If you run it you will see a square falling down very slow.
I'm a beginner so explain it not too complicated.
Any questions about this code dylan.missu#gmail.com
Here is my code:
#Override
public void show() {
camera = new OrthographicCamera();
debugRenderer = new Box2DDebugRenderer();
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set(100,100);
body = world.createBody(bodyDef);
PolygonShape shape = new PolygonShape();
shape.setAsBox(Gdx.graphics.getHeight()/6,Gdx.graphics.getHeight()/6);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = 1f;
fixtureDef.restitution = 2;
Fixture fixture = body.createFixture(fixtureDef);
}
private void line(float X, float Y, float w, float h)
{
BodyDef bodyDef = new BodyDef();
bodyDef.type=BodyDef.BodyType.StaticBody;
bodyDef.position.set(X,Y);
PolygonShape polygonShape=new PolygonShape();
polygonShape.setAsBox(w,h);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape=polygonShape;
fixtureDef.restitution=0.4f;
fixtureDef.friction=0.5f;
Body theFloor=world.createBody(bodyDef);
theFloor.createFixture(fixtureDef);
}
private void wall(float A)
{
// is there a better way of doing this?
line(0,Gdx.graphics.getHeight()/2-A,Gdx.graphics.getWidth()/2-A,0);
line(Gdx.graphics.getWidth()/2-A,0,0,Gdx.graphics.getHeight()/2-A);
line(0,-Gdx.graphics.getHeight()/2+A,Gdx.graphics.getWidth()/2-A,0);
line(-Gdx.graphics.getWidth()/2+A,0,0,Gdx.graphics.getHeight()/2-A);
}
#Override
public void render(float delta) {
world.step(1 / 5f, 6, 2);
OrthographicCamera camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
processAccelerometer();
wall(1);
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
debugRenderer.render(world, camera.combined);
}
#Override
public void dispose() {
world.dispose();
debugRenderer.dispose();
}
private void processAccelerometer() {
float y = Gdx.input.getAccelerometerY();
float x = Gdx.input.getAccelerometerX();
if (prevAccelX != x || prevAccelY != y) {
world.setGravity(new Vector2(y, -x));
prevAccelX = x;
prevAccelY = y;
}
}
#Override
public void hide()
{
// TODO: Implement this method
}
#Override
public void resize(int p1, int p2)
{
// TODO: Implement this method
}
#Override
public void resume()
{
// TODO: Implement this method
}
#Override
public void pause()
{
// TODO: Implement this method
}
#Override
public void render()
{
// TODO: Implement this method
}
}
In Box2D you have to take into account that 1 pixel = 1 meter. So, basically, everything you simulate in Box2D will be HUGE by default. And Box2D simulations are not accurate for huge distances, huge masses, huge speeds...
So all you have to do is convert your viewport with a conversion factor, so you'll just look at small entities, that will be easier to simulate.
For example, let's say you want 100 pixel = 1 meter, you'll put that code when you create your game screen :
WORLD_TO_BOX = 1/100f;
BOX_TO_WORLD = 1/WORLD_TO_BOX;
//Creation of the camera with your factor 100
camera = new OrthographicCamera();
camera.viewportHeight = Gdx.graphics.getHeight() * WORLD_TO_BOX;
camera.viewportWidth = Gdx.graphics.getWidth() * WORLD_TO_BOX;
camera.position.set(camera.viewportWidth/2, camera.viewportHeight/2, 0f);
camera.update();
Then, you'll create your boxes in term of camera.viewportWidth and camera.viewportHeight, instead of Gdx.graphics.getWidth() and Gdx.graphics.getHeight()
I your case you'll have :
PolygonShape shape = new PolygonShape();
shape.setAsBox(camera.viewportHeight/6,camera.viewportHeight/6);
You can see in my code, there is also a BOX_TO_WORLD conversion factor. It will be used when you want to render graphics over your box2D bodies.
For that, look at the answer of this question.
Related
I am trying to control drone with command sendVirtualStickFlightControlData.
To move the drone left I use following code.
sendVirtualStickDataTask = new SendVirtualStickDataTask(0, -5, 0, 0);
sendVirtualStickDataTimer = new Timer();
sendVirtualStickDataTimer.schedule(sendVirtualStickDataTask, 100, 200);
private class SendVirtualStickDataTask extends TimerTask {
private float pitch;
private float roll;
private float yaw;
private float throttle;
private long startTime = System.currentTimeMillis();
public SendVirtualStickDataTask(float inputPitch, float inputRoll, float inputYaw, float inputThrottle) {
pitch = inputPitch;
roll = inputRoll;
yaw = inputYaw;
throttle = inputThrottle;
}
#Override
public void run() {
if (System.currentTimeMillis() - startTime > 300) {
mFlightController.sendVirtualStickFlightControlData(new FlightControlData(0, 0, 0, 0),
new CommonCallbacks.CompletionCallback() {
#Override
public void onResult(final DJIError djiError) {
}
});
cancel();
} else {
mFlightController
.sendVirtualStickFlightControlData(new FlightControlData(pitch,
roll,
yaw,
throttle),
new CommonCallbacks.CompletionCallback() {
#Override
public void onResult(final DJIError djiError) {
}
});
}
}
}
However, the drone moves to the left and then drops down sharply.
What is the reason for this drone behavior?
I have no clue why it is dropping sharply downwards, since you are not changing the throttle values. Make sure to enable virtual sticks before usage. It might have to do with you needing to set maximum values. This code works fine for me.
/* controllers virtual sticks command and triggers drone movement */
private void sendVirtualStickCommands(final float pX, final float pY, final float pZ, final float pYaw){
//maximum amounts
float verticalJoyControlMaxSpeed = 2;
float yawJoyControlMaxSpeed = 30;
float pitchJoyControlMaxSpeed = 10;
float rollJoyControlMaxSpeed = 10;
//set yaw, pitch, throttle, roll
float mYaw = (float)(yawJoyControlMaxSpeed * pYaw);
float mThrottle = (float)(verticalJoyControlMaxSpeed * pZ);
float mPitch = (float)(pitchJoyControlMaxSpeed * pX);
float mRoll = (float)(rollJoyControlMaxSpeed * pY);
if (mFlightController != null){
//if virtual sticks are enabled, send the command, otherwise turn them on
if (virtualSticksEnabled){
mFlightController.sendVirtualStickFlightControlData(
new FlightControlData(
mPitch, mRoll, mYaw, mThrottle
), new CommonCallbacks.CompletionCallback() {
#Override
public void onResult(DJIError djiError) {
if (djiError!=null){
setResultToToast(djiError.getDescription());
}
}
}
);
} else {
setResultToToast("flight controller virtual mode off");
//if not enabled, enable
mFlightController.setVirtualStickModeEnabled(true, new CommonCallbacks.CompletionCallback() {
#Override
public void onResult(DJIError djiError) {
if (djiError != null){
setResultToToast(djiError.getDescription());
}else
{
setResultToToast("Enable Virtual Stick Success");
virtualSticksEnabled = true;
sendVirtualStickCommands(pX, pY, pZ, pYaw);
}
}
});
}
} else{
setResultToToast("Flight Controller Null");
}
}
Then, to move in a direction:
sendVirtualStickCommands(0.1f, 0, 0, 0);//move right
sendVirtualStickCommands(-0.1f, 0, 0, 0);//move left
sendVirtualStickCommands(0, 0.1f, 0, 0);//move forward
sendVirtualStickCommands(0, -0.1f, 0, 0);//move backwards
sendVirtualStickCommands(0, 0, 0.1f, 0);//move upwards
sendVirtualStickCommands(0, 0, -0.1f, 0);//move downwards
try this
mFlightController.setRollPitchControlMode(RollPitchControlMode.VELOCITY);
mFlightController.setYawControlMode(YawControlMode.ANGULAR_VELOCITY);
mFlightController.setVerticalControlMode(VerticalControlMode.POSITION);
mFlightController.setRollPitchCoordinateSystem(FlightCoordinateSystem.BODY);
and set mThrottle >= 0.0f
in VerticalControlMode.POSITION, mThrottle is a flight height you want to set in meters above the ground.
For example mThrottle = 2.0f means to move the drone to 2 meters above the ground. Set the height you want and the drone will rise to it or "drops down" if mThrottle = 0f.
I've a sprite (rectangular) that rotates around its central point. I used:
setOriginCenter();
setRotation(angleDegrees);
That works fine.
I defined a DynamicBody (box2d) using a CircleShape.
In the update method of the sprite, I want to center the sprite (rotated sprite) with the center of the DynamicBody.
I tried several method but I can't get a solution:
This doesn't work
Rectangle rect = myRotatedSprite.getBoundingRectangle();
myRotatedSprite.setPosition(b2body.getPosition().x - rect.getWidth() / 2, b2body.getPosition().y - rect.getHeight() / 2);
This doesn't work
myRotatedSprite.setPosition(b2body.getPosition().x - myRotatedSprite.getWidth() / 2, b2body.getPosition().y - myRotatedSprite.getHeight() / 2);
This doesn't work
float rot = myRotatedSprite.getRotation();
myRotatedSprite.setRotation(0);
Rectangle rect = getBoundingRectangle();
myRotatedSprite.setPosition(b2body.getPosition().x - rect.width / 2,
b2body.getPosition().y - rect.height / 2);
myRotatedSprite.setRotation(rot);
myRotatedSprite.getBoundingRectangle();
What I am doing wrong ? It seems to me that getBoundingRectangle() is not correct when the sprite is rotated...
Here is my full code:
public class HeroBullet extends Weapon {
private static final String TAG = HeroBullet.class.getName();
private float stateTimer;
private Animation heroBulletAnimation;
private Vector2 tmp; // Temp GC friendly vector
public HeroBullet(PlayScreen screen, float x, float y, float width, float height, float circleShapeRadius, float angle, Animation animation) {
super(screen, x, y, circleShapeRadius > 0 ? circleShapeRadius : Constants.HEROBULLET_CIRCLESHAPE_RADIUS_METERS);
setOriginCenter();
width = width > 0 ? width : Constants.HEROBULLET_WIDTH_METERS;
height = height > 0 ? height : Constants.HEROBULLET_HEIGHT_METERS;
setBounds(getX(), getY(), width, height);
velocity = new Vector2(Constants.HEROBULLET_VELOCITY_X, Constants.HEROBULLET_VELOCITY_Y);
if (angle > 0) {
velocity.rotate(angle);
setRotation(angle);
}
if (animation != null) {
heroBulletAnimation = animation;
} else {
heroBulletAnimation = Assets.instance.heroBullet.heroBulletAnimation;
}
stateTimer = 0;
currentState = State.SHOT;
AudioManager.instance.play(Assets.instance.sounds.heroShoot, 0.2f, MathUtils.random(1.0f, 1.1f));
tmp = new Vector2();
}
#Override
protected void defineWeapon() {
BodyDef bdef = new BodyDef();
bdef.position.set(getX(), getY()); // In b2box the origin is at the center of the body
bdef.type = BodyDef.BodyType.DynamicBody;
b2body = world.createBody(bdef);
FixtureDef fdef = new FixtureDef();
CircleShape shape = new CircleShape();
shape.setRadius(circleShapeRadius);
fdef.filter.categoryBits = Constants.HERO_WEAPON_BIT; // Depicts what this fixture is
fdef.filter.maskBits = Constants.BORDERS_BIT |
Constants.OBSTACLE_BIT |
Constants.POWERBOX_BIT |
Constants.FINAL_ENEMY_LEVEL_ONE_BIT |
Constants.ENEMY_BIT; // Depicts what this Fixture can collide with
fdef.shape = shape;
b2body.createFixture(fdef).setUserData(this);
}
#Override
public void update(float dt) {
switch (currentState) {
case SHOT:
stateShot(dt);
break;
case ONTARGET:
stateOnTarget();
break;
case FINISHED:
break;
default:
break;
}
super.checkBoundaries();
}
private void stateShot(float dt) {
b2body.setLinearVelocity(velocity);
/* ***********
Here I want to center the sprite (rotated sprite) with the center of the DynamicBody, but I don't know how
******** */
setRegion((TextureRegion) heroBulletAnimation.getKeyFrame(stateTimer, true));
stateTimer += dt;
}
private void stateOnTarget() {
world.destroyBody(b2body);
currentState = State.FINISHED;
}
#Override
public void renderDebug(ShapeRenderer shapeRenderer) {
shapeRenderer.rect(getBoundingRectangle().x, getBoundingRectangle().y, getBoundingRectangle().width, getBoundingRectangle().height);
}
#Override
public void onTarget() {
currentState = State.ONTARGET;
}
public void draw(Batch batch) {
if (currentState == State.SHOT) {
super.draw(batch);
}
}
}
I am using Scene2D.
This is my Shoot Actor
public class ActorDisparo extends Actor {
private TextureRegion textureDisparo = new TextureRegion();
private World world;
public static Body body;
//private Fixture fixture;
private FixtureDef fdef;
private String userData;
private float anchoDisparo, altoDisparo;
private float positionX,positionY;
private static float porcentajeDeancho = 0,anchoMediano = 0, anchoPequeno = 0, anchoDiminuto = 0;
private TextureRegion arponRegion = new TextureRegion();
public ActorDisparo(World world, TextureRegion disparo, Vector2 position, float anchoDisparo, float altoDisparo, float fuerzaX, float fuerzaY, String userData){
this.textureDisparo = disparo;
this.world = world;
this.anchoDisparo = anchoDisparo;
this.altoDisparo = altoDisparo;
this.userData = userData;
BodyDef bodyDef = new BodyDef();
bodyDef.position.set(position);
bodyDef.type = BodyDef.BodyType.DynamicBody;
body = world.createBody(bodyDef);
PolygonShape shapeDisparo = new PolygonShape();
shapeDisparo.setAsBox((anchoDisparo/2)/2,altoDisparo/2);
fdef = new FixtureDef();
fdef.shape = shapeDisparo;
//fdef.restitution = 0.70f;
fdef.filter.categoryBits = BolasGame.DISPARO_BIT;
fdef.filter.maskBits = BolasGame.BOLAROJA_BIT |
BolasGame.TECHO_BIT;
body.createFixture(fdef).setUserData(userData);
shapeDisparo.dispose();
body.setGravityScale(0f);
body.applyLinearImpulse(fuerzaX,fuerzaY,position.x,position.y,true);
setSize( anchoDisparo *BolasGame.MetrosAPixels ,altoDisparo*BolasGame.MetrosAPixels);
//setBounds(0, 0, getWidth(), getHeight());
}
public float getPositionX() {
return getPositionX();
}
public float getPositionY() {
return getPositionY();
}
#Override
public void act(float delta) {
super.act(delta);
}
#Override
public void draw(Batch batch, float parentAlpha) {
super.draw(batch, parentAlpha);
setPosition( (body.getPosition().x * BolasGame.MetrosAPixels) - getWidth()/2, (body.getPosition().y * BolasGame.MetrosAPixels) - getHeight()/2);
batch.draw(textureDisparo,getX(),getY(),getWidth(),getHeight());
}
public void detach(){
world.destroyBody(body);
remove();
}
}
and this is the call to shoot class
if(Gdx.input.justTouched() && hasdisparado == false){
hasdisparado =true;
touch = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
stage.getCamera().unproject(touch);
arponRegion = new TextureRegion(textureDisparo, 0, 0, 20, 40);
actorDisparo = new ActorDisparo(world,arponRegion,new Vector2(touch.x/BolasGame.MetrosAPixels,touch.y/BolasGame.MetrosAPixels ),20/BolasGame.MetrosAPixels,40/BolasGame.MetrosAPixels,0,2f,BolasGame.USERDATA_DISPARO);
stage.addActor(actorDisparo);
}
this creates a shot like a bullet but I need since I touched the screen until it is destroyed is continuous like the harpoon of game pang
the textureregion the charge of a texture whose dimensions are 446x20
textureDisparo = new Texture("gfx/disparo.png");
I have no idea how to do this because you have to repeat the image and body in box2d for collisions.
I totally lost
if someone can give me an idea would appreciate
Thank you
(Sorry for my English, I'm learning now)
I'm working on moving vehicle based on Box 2d physics for my Android game (Java + LibGDX). When I thought I have everything up and running my, my car with two wheels stands on the ground but when I rotate the wheels The car does not move.
That's my Game class:
public class MyGdxGame implements ApplicationListener {
World world = new World(new Vector2(0, -10), true);
Box2DDebugRenderer debugRenderer;
OrthographicCamera camera;
static final float BOX_STEP=1/60f;
static final int BOX_VELOCITY_ITERATIONS=6;
static final int BOX_POSITION_ITERATIONS=2;
static final int WIDTH=256;
static final int HEIGHT=169;
Hero hero;
MovableBox box;
#Override
public void create() {
camera = new OrthographicCamera();
camera.viewportHeight = HEIGHT;
camera.viewportWidth = WIDTH;
camera.position.set(camera.viewportWidth * .5f, camera.viewportHeight * .5f, 0f);
camera.update();
Vector2[] anArray;
anArray = new Vector2[4];
anArray[0]= new Vector2(-30,0);
anArray[1]= new Vector2(55,55);
anArray[2]= new Vector2(110,55);
anArray[3]= new Vector2(195,0);
//Ground body
BodyDef groundBodyDef =new BodyDef();
groundBodyDef.position.set(new Vector2(-8-13-20-20-10, -44));
Body groundBody = world.createBody(groundBodyDef);
PolygonShape groundBox = new PolygonShape();
groundBox.set(anArray);
//groundBox.setAsBox((camera.viewportWidth) * 2, 10.0f);
groundBody.createFixture(groundBox, 0.0f);
//Ground body
BodyDef groundBodyDef2 =new BodyDef();
groundBodyDef2.position.set(new Vector2(13*11-4-7-8-13-20-20-10, -44));
Body groundBody2 = world.createBody(groundBodyDef2);
PolygonShape groundBox2 = new PolygonShape();
groundBox2.set(anArray);
//groundBox.setAsBox((camera.viewportWidth) * 2, 10.0f);
groundBody2.createFixture(groundBox2, 0.0f);
hero = new Hero();
hero.create(world, 0, 0);
box.create(world, WIDTH / 4 * 3, HEIGHT / 2);
boxes.add(box);
debugRenderer = new Box2DDebugRenderer();
}
private void update(){
hero.update();
for(MovableBox b : boxes) {
b.update();
}
}
#Override
public void dispose() {
}
#Override
public void render() {
update();
camera.position.set(hero.getPos(), 0f);
camera.update();
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
debugRenderer.render(world, camera.combined);
world.step(BOX_STEP, BOX_VELOCITY_ITERATIONS, BOX_POSITION_ITERATIONS);
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
And Hero class (which should be called a car actually)
Body body;
Body wheel, wheel2;
public void create(World world, int posx, int posy){
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set(posx, posy);
body = world.createBody(bodyDef);
PolygonShape dynamicCircle = new PolygonShape();
dynamicCircle.setAsBox(8, 3);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = dynamicCircle;
fixtureDef.density = 4.0f;
fixtureDef.restitution = 0.1f;
fixtureDef.friction=0.95f;
body.createFixture(fixtureDef);
BodyDef bodyDef2 = new BodyDef();
bodyDef2.type = BodyDef.BodyType.DynamicBody;
wheel = world.createBody(bodyDef2);
CircleShape dynamicCircle2 = new CircleShape();
dynamicCircle2.setRadius(2);
FixtureDef fixtureDef2 = new FixtureDef();
fixtureDef2.shape = dynamicCircle2;
fixtureDef2.density = 4;
fixtureDef2.friction=3.0f;
fixtureDef2.restitution=0.1f;
wheel.createFixture(fixtureDef2);
wheel2 = world.createBody(bodyDef2);
wheel2.createFixture(fixtureDef2);
RevoluteJointDef revoluteJointDef = new RevoluteJointDef();
revoluteJointDef.bodyA = body;
revoluteJointDef.bodyB = wheel;
revoluteJointDef.localAnchorA.add(-8,-6);
world.createJoint(revoluteJointDef);
RevoluteJointDef revoluteJointDef2 = new RevoluteJointDef();
revoluteJointDef2.bodyA = body;
revoluteJointDef2.bodyB = wheel2;
revoluteJointDef2.localAnchorA.add(8,-6);
world.createJoint(revoluteJointDef2);
}
public Vector2 getPos(){
return body.getPosition();
}
public void update(){
if(Gdx.input.isTouched())
{
if(Gdx.input.getX()<600){
wheel.setTransform(wheel.getPosition().x,wheel.getPosition().y,wheel.getAngle()+0.1f);
wheel2.setTransform(wheel2.getPosition().x,wheel2.getPosition().y, wheel2. getAngle() + 0.1f);
}
else{
wheel.setTransform(wheel.getPosition().x,wheel.getPosition().y,wheel.getAngle()-0.1f);
wheel2.setTransform(wheel2.getPosition().x,wheel2.getPosition().y,wheel2.getAngle()-0.1f);
}
}
}
Well I think there are two things you need to consider.
First of all I think if you want your physics engine to "force" the car to move on wheels spin, you probably should look into damping parameters of BodyDef (linearDamping and angularDamping). Setting those for ground and car wheels might help you move your car on wheels spin.
The second thing is that you really need to analyze if it's the proper approach. Maybe you should think about simulating movement of your car by moving the body of your car itself and spinning your wheels. I think this approach should give you more control on the car movement.
I want to control the box by 2 fingers like below:
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?
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;
}
}
}