0
\$\begingroup\$

In a top down game using Box2D, I would like the player's Box2D body to rotate towards the mouse click, and then move to a point on mouse click (move, not teleport). I have worked out the rotation part, but cannot figure out the movement.

Every time the screen is touched, the target point (mouse click) is updated:

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

Here is the Rot2D class:

package com.elsealabs.ghostr;

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 getAngle() { // radians
     return Math.atan2(sin, cos); // atan2(y, x)
  }

   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);
   }
}

(Source)

I am showing these because it may be helpful, but what I need to get working is the movement. I do not want to use setTransform, as it may end up letting the player travel through walls.

Using the vectors below, and any other variables needed, how would I move the player gradually towards a point on mouse click?

private Vector2 touch_prev = new Vector2(0, 0);
private Vector2 touch_target
\$\endgroup\$
2

2 Answers 2

1
\$\begingroup\$
  • Get vec2 from start point to target point (mouse coords in world space).
  • Set b2body velocity to normalized version of that vec2, multiplied by your desired speed.
  • Keep stepping - velocity will carry you closer to target point each time.
  • On each step, if distance from current point to target point (magnitude) is less than velocity, set b2body position to the target point, and set velocity to zero.
\$\endgroup\$
0
\$\begingroup\$

Okay, So I think you're asking how to do it so here's my Bullet class remodeled to fit a player. Keep in mind this was a bullet class so edit it to fit for your player. Pay close attention to the use of Vectors.

public class MovingPlayer {

   static final float PLAYER_SPEED = 800;

   Vector3 position, velocity, acceleration;
   Texture texture;

   public Vector3 target;
   public Rectangle Bb;
   Player player;

   public Bullet(Texture texture, Player player) {
      this.texture = texture;
      this.player = player;
      reset();
      Pb = new Rectangle(0, 0, 10, 10);
      acceleration = new Vector3(0, -400, 0); // gravity

   }

   private void reset() {
      position = new Vector3(player.getX() + 20, player.getY() + 20, 0);
      target = new Vector3(Gdx.input.getX(), Gdx.input.getY(),0);
      GameScreen.cam.unproject(target); 
      velocity = target.cpy().sub(position).nor().scl(BULLET_SPEED); // go towards target
   }

   public void render(SpriteBatch batch) {
      batch.draw(texture, position.x, position.y);
      Pb.setX(position.x);
      Pb.setY(position.y);
   }

   public void update(float delta) {           
      // simple Euler integration
      position.add(velocity.cpy().scl(delta));
   }
}

This sends the object towards the mouse using Vectors at the speed "PLAYER_SPEED". As you can see, most of the math is done in the reset() method

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .