5

I currently have a body created that is Dynamic and moves at a constant speed with a Vector2(). What I want is for when the body leaves the edge of the screen, to come back from that current point back to its original point instantaneously. How do I do this?

    a.applyForceToCenter(aMovement, true);
    a.applyTorque(3000, true);

    FixtureDef fDef = new FixtureDef();
    BodyDef ballD = new BodyDef();

    ballD.type = BodyType.DynamicBody;

    //random location for asteroid
    int aLoc = (int) (aLocation * 15);
    float x = 300;
    switch(aLoc)
    {
    case 0:
        ballD.position.set(x, -105);
        break;
    case 1:
        ballD.position.set(x, -95);
        break;
    case 2:
        ballD.position.set(x, -80);
        break;
    case 3:
        ballD.position.set(x, -65);
        break;
    case 4:
        ballD.position.set(x, -50);
        break;
    case 5:
        ballD.position.set(x, -35);
        break;
    case 6:
        ballD.position.set(x, -20);
        break;
    case 7:
        ballD.position.set(x, -5);
        break;
    case 8:
        ballD.position.set(x, 10);
        break;
    case 9:
        ballD.position.set(x, 25);
        break;
    case 10:
        ballD.position.set(x, 40);
        break;
    case 11:
        ballD.position.set(x, 55);
        break;
    case 12:
        ballD.position.set(x, 70);
        break;
    case 13:
        ballD.position.set(x, 85);
        break;
    default:
        ballD.position.set(x, 0);
    }

    PolygonShape asteroid = new PolygonShape();
    asteroid.setAsBox(12.5f, 12.5f);

    //asteroid definition
    fDef.shape = asteroid;
    fDef.density = .5f;
    fDef.friction = .25f;
    fDef.restitution = .75f;

    a = world.createBody(ballD);
    a.createFixture(fDef);
    a.setFixedRotation(false);

   //asteroid image
    aSprite = new Sprite(new Texture("img/asteroid-icon.png"));
    aSprite.setSize(12.5f * 4, 12.5f * 4);
    aSprite.setOrigin(aSprite.getWidth() / 2, aSprite.getHeight() / 2);
    a.setUserData(aSprite);
    asteroid.dispose();
Mercify
  • 113
  • 3
  • 9

3 Answers3

5

You could use Body.setTransform() for that task, but I would not do that. setTransform() causes a lot of trouble in the long run.

For me it lead to weird bugs. For example using setTransform disabled my ContactFilter in random moments, which cost me several days of debugging until I found that.

Furthermore it causes non-physical behaviour, because you basically teleport the Body.

Better would be to destroy the Body completely and recreate a new one at the same initial position of the old one.

noone
  • 19,520
  • 5
  • 61
  • 76
  • How could I do that the way I want? What I want is for this to occur forever with the asteroid moving across the screen and then being put back in its original spot to move across again. – Mercify Mar 05 '14 at 23:40
  • Don't forget to wake up the body if you use `setTransform`. It might be inactive and will therefore not be processed at the new position! ```java body.setTransform(targetTeleportPosition, body.angle); body.setAwake(true); ``` – Thomas Jul 11 '19 at 12:30
2

You can set the position of your Box2D a body instantly through this method:

a.setTransform(new_x, new_y, new_angle);

With this, you can create a condition that sets the x and y position of the body back to its original position when the x or y value of the body is outside of the screen.

if(outsideBounds()){
    a.setTransform(start_x, start_y, start_angle);
}

You can check whether your object is offscreen by either checking its Box2D position and its converted screen coordinates, or by checking the sprite's location.

Once you've received the x and y screen positions, you can compare them to the screen bounds like this:

pos_x>screenWidth||pos_x<0||pos_y>screenHeight||pos_y<0

This can be improved by including the dimensions of the object, depending on when you want the transformation to happen:

(pos_x-objWidth)>screenWidth || (pos_x+objWidth)<0 ||
(pos_y-objHeight)>screenHeight || (pos_y+objHeight)<0
user3312130
  • 178
  • 1
  • 8
  • How do i get the position of the body? – Mercify Mar 06 '14 at 04:13
  • You can get the position `Vector2` of the body through `a.getPosition()`. For more information on LibGDX/Box2D bodies, check out [this](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/physics/box2d/Body.html) link. As pointed out in noone's answer, using `setTransform` can cause problems, so use this method at your own risk, or to avoid problems, follow noone's suggestion and recreate the body. – user3312130 Mar 06 '14 at 04:35
  • Don't forget to wake up the body if you use `setTransform`. It might be inactive and will therefore not be processed at the new position! ```java body.setTransform(targetTeleportPosition, body.angle); body.setAwake(true); ``` – Thomas Jul 11 '19 at 12:32
0

You can use the following:

body.setTransform(newX, newY, newAngle);
body.setAwake(true);

Waking up the body is important. It might be currently inactive and without waking it up neither gravity nor any immediate collisions will affect it at the new position.

Thomas
  • 650
  • 9
  • 9