Rotating a Box2D entity to mouse input point?

Connorelsea

How would I make a Box2D body rotate such that it faces the a point given when the user clicks their mouse?

I am trying to implement a mechanic you can visualize as a top-down flashlight.

Problems:

  • I feel like I am scaling the camera with PPM (pixels per meter) incorrectly
  • The light does not turn correctly
  • Do not know how to tween between positions

To do this, in the show() method, I have attached a ConeLight to a Box2D body using the following method:

    PolygonShape shape = new PolygonShape();
    shape.setAsBox(5 / PPM, 5 / PPM);

    BodyDef bdef = new BodyDef();
    bdef.position.set(160 / PPM, 200 / PPM);
    bdef.type = BodyType.DynamicBody;
    body = world.createBody(bdef);
    
    FixtureDef fdef = new FixtureDef();
    fdef.shape = shape;
    body.createFixture(fdef);
    
    rayHandler = new RayHandler(world);
    cone = new ConeLight
    (rayHandler, 40, Color.WHITE, 30, 160 / PPM, 200 / PPM, -90, 40);

Then, again in the show() method, I set up the camera:

    b2dcam = new OrthographicCamera();
    b2dcam.setToOrtho(false, Gdx.graphics.getWidth() / PPM, Gdx.graphics.getHeight() / PPM);

I am rendering it like this in the render() method:

    Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);
    world.step(1f/60f, 6, 2);
    b2dr.render(world, b2dcam.combined);
    rayHandler.setCombinedMatrix(b2dcam.combined);
    rayHandler.updateAndRender();

I am handling the input in this fashion:

public boolean touchDown(int screenX, int screenY, int pointer, int button) {
    
    if(button == Buttons.LEFT){
        body.setTransform(body.getPosition(), (float) (Math.atan2( (body.getPosition().y - screenY),
                                                       (screenX - body.getPosition().x) ) ));
    }
    return false;
}

The light rotates on mouse click, which means the listener is working, but it does not rotate to the correct point. I assume it has something to do with my math being incorrect, and the scaling done from meters to pixels being wrong.

Can someone help me on both of these issues? The intended behavior is illustrated below:

The setup I wish to use

The intended behavior of the moving flash light

When the mouse is clicked, the body, and by association the ConeLight, should move to face the direction of the mouse click.

My full code can be viewed here: https://gist.githubusercontent.com/Elsealabs/1afaa812aafb56ecd3c2/raw/5d0959df795516c89fb7e6ab81aecc01dc8cd441/gistfile1.txt

Connorelsea

I never got an answer to this, but I figured it out with some help from some friends.

To handle this problem, I created a class that does a lot of the math automatically.

public class Rot2D {
  public static Rot2D fromDegrees(double angle) {
     return fromRadians(Math.toRadians(angle));
  }

  public static Rot2D fromRadians(double angle) {
     return new Rot2D(Math.cos(angle), Math.sin(angle));
  }

  public static Rot2D fromVector(double dx, double dy) {
     float length = (float) Math.sqrt(dx * dx + dy * dy);
     return new Rot2D(dx / length, dy / length);
  }

  public double cos, sin;

  private Rot2D(double cos, double sin) {
     this.cos = cos;
     this.sin = sin;
  }

  public Rot2D load(Rot2D that) {
     this.cos = that.cos;
     this.sin = that.sin;

     return this;
  }

  public Rot2D copy() {
     return new Rot2D(cos, sin);
  }

  public Rot2D rotate(Rot2D that) {
     double cos = (this.cos * that.cos) - (this.sin * that.sin);
     double sin = (this.cos * that.sin) + (this.sin * that.cos);

     this.cos = cos;
     this.sin = sin;

     return this;
  }

  public static double cross(Rot2D a, Rot2D b) {
     return (a.cos * b.sin) - (a.sin * b.cos);
  }
}

And in my game code I used the following code to implement the movement:

    if (Gdx.input.isTouched())
    {
        Vector3 tmp = camera.unproject(new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0));
        touch_target = new Vector2(tmp.x, tmp.y);
    }

    touch_angleWant = Rot2D.fromVector(
        touch_target.x - entity_player.getBody().getPosition().x,
        touch_target.y - entity_player.getBody().getPosition().y
    );

    double cross1 = Rot2D.cross(touch_angleCur, touch_angleWant);

    if (cross1 > 0.0)
        touch_angleCur.rotate(Rot2D.fromDegrees(5.0));
    else
        touch_angleCur.rotate(Rot2D.fromDegrees(-5.0));

    double cross2 = Rot2D.cross(touch_angleCur, touch_angleWant);

    if (Math.signum(cross1) != Math.signum(cross2))
        touch_angleCur.load(touch_angleWant);

     entity_player.getBody().setTransform(entity_player.getBody().getPosition(), (float) (touch_angleCur.getAngle()));

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

How to move an entity to the mouse position, rotating towards it

分類Dev

Input Listener on libgdx Actor with Box2D

分類Dev

Rotating Rectangle with mouse isn't consistant

分類Dev

Rotating around a point, object consistently getting further

分類Dev

Fabric js, Rotating point in each side

分類Dev

D3 linechart mouse move point position is wrong

分類Dev

Trying to get a triangle to point to the mouse

分類Dev

Move user mouse to a certain point

分類Dev

Move user mouse to a certain point

分類Dev

Get 2 bars from mouse click and project 3rd point in time

分類Dev

how to simulate rotating down the scroll button using mouse_event(MOUSEEVENTF_WHEEL

分類Dev

Box2D libgdx polygon shape

分類Dev

libgdx and Box2d collision optimisation

分類Dev

applyLinearImpulse not working (Box2d)

分類Dev

libGDX Box2D Assertion Failed

分類Dev

Box2DとXcode

分類Dev

OnChange in input does not fire if mouse is not moving

分類Dev

Moving a square from a starting point to the position of a mouse click at a fixed speed

分類Dev

Box2D debug draw with OpenGL ES 2

分類Dev

Unstable b2RevoluteJoint Box2D

分類Dev

What is the point of marking a property as "Value generated on add or update" in Entity Framework?

分類Dev

Box2D衝突エラー

分類Dev

Box2D図面の修正

分類Dev

Issue using Box2D and video in the same Processing sketch

分類Dev

Adding color to lines Box2d (EdgeShape)

分類Dev

AndEngine Box2d - how to avoid joint "stretching"?

分類Dev

Box2d本体のOnUpdate関数

分類Dev

LibGdx Box2d PlatformerJumpの実装

分類Dev

LibGDX + Box2D +スパイン