0
\$\begingroup\$

I have a game object with a Kinematic body and a sprite. The object's "draw" method will always position the sprite to match a position of actual body, so the sprite is completely passive.

Now, I have a situation where I want to hold a mouse button (or touch) over that body and draw that body to another position on the screen, bur I don't know how to implement that properly.

For input, I'm processing the Gdx.input.isTouched method and passing unprojected Gdx.input.x and Gdx.input.y coordinates to my "move" method, but nothing happens. My "move" method looks like this:

public void move(float X, float Y) { body.getPosition().set(X / PPM, Y / PPM); } 

If I disconnect sprite from body and use those coordinates to move just sprite, it works perfectly, so those coordinates are ok.

How would you suggest I should do that instead, without recreating the full body definition for every pixel body moved?

\$\endgroup\$
1
  • \$\begingroup\$ does getPosition() return a reference to the stored position, or a copy? If it returns a copy, you may need to call another method to set the body's position to the position now stored in your modified copy. \$\endgroup\$ Commented Jan 25 at 4:35

1 Answer 1

2
\$\begingroup\$

You need to set the transform of the Body to move it to the specified coordinates:

body.setTransform(position.x, position.y, body.getAngle()); 

Doing that will snap the Body to the coordinates and will give you an accurate way of dragging the Body, but beware that the simulation might be unstable in some scenarios as you are moving things explicity instead of using forces and velocities (usually it's fine though).

sample box2d simulation dragging kinetic body

The full source for the example above is:

public class SandboxGame extends ApplicationAdapter { private OrthographicCamera camera; private World world; private Box2DDebugRenderer debugRenderer; private Body body; private Body kinematicBody; private Body ground; private Vector3 unprojectVector = new Vector3(); private Vector2 worldTouchPosition = new Vector2(); @Override public void create () { float aspectRatio = (float)Gdx.graphics.getWidth() / Gdx.graphics.getHeight(); float w = 100.0f; camera = new OrthographicCamera(w, w / aspectRatio); world = new World(new Vector2(0, -80), false); debugRenderer = new Box2DDebugRenderer(); // Create body { PolygonShape shape = new PolygonShape(); shape.setAsBox(4, 4); FixtureDef fixtureDef = new FixtureDef(); fixtureDef.shape = shape; fixtureDef.density = 1.0f; BodyDef bodyDef = new BodyDef(); bodyDef.type = BodyDef.BodyType.DynamicBody; body = world.createBody(bodyDef); body.createFixture(fixtureDef); shape.dispose(); } // Create kinematic body { PolygonShape shape = new PolygonShape(); shape.setAsBox(4, 2); FixtureDef fixtureDef = new FixtureDef(); fixtureDef.shape = shape; fixtureDef.density = 1.0f; BodyDef bodyDef = new BodyDef(); bodyDef.type = BodyDef.BodyType.KinematicBody; kinematicBody = world.createBody(bodyDef); kinematicBody.createFixture(fixtureDef); kinematicBody.setTransform(-20, 0, 0); shape.dispose(); } // Create ground { PolygonShape shape = new PolygonShape(); shape.setAsBox(100, 2); FixtureDef fixtureDef = new FixtureDef(); fixtureDef.shape = shape; fixtureDef.density = 1.0f; BodyDef bodyDef = new BodyDef(); bodyDef.type = BodyDef.BodyType.StaticBody; ground = world.createBody(bodyDef); ground.createFixture(fixtureDef); ground.setTransform(0, -20, 0); shape.dispose(); } Gdx.input.setInputProcessor(new InputAdapter() { public boolean touchDragged(int screenX, int screenY, int pointer) { Vector2 position = unproject(screenX, screenY); kinematicBody.setTransform(position.x, position.y, kinematicBody.getAngle()); return false; } }); } @Override public void render () { world.step(Gdx.graphics.getDeltaTime(), 6, 6); camera.update(); ScreenUtils.clear(Color.BLACK); debugRenderer.render(world, camera.combined); } private Vector2 unproject(int screenX, int screenY) { camera.unproject(unprojectVector.set(screenX, screenY, 1)); worldTouchPosition.set(unprojectVector.x, unprojectVector.y); return worldTouchPosition; } } 
\$\endgroup\$
0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.