Box2D in LibGDX - Throwing body based on swipe angle.

Started by
2 comments, last by Wyrframe 8 years, 3 months ago

Hello everyone,

It's my first time using the Box2D physics engine for a LibGDX project, and i'm struggling with this one thing: I'm trying to swipe a ball (wich is a b2D body) using the fling method from the GestureListener. So, when there's a fling, i apply a force to the ball, like this:

( Excuse my paint skills, hope its understandable... )

https://i.gyazo.com/94e6c3ad347eff9688d707e6bb7f4ce2.png

Here's my fling method so far:


@Override
public boolean fling(float velocityX, float velocityY, int button) {


  ball.getBody().setActive(true);
  System.out.println("Mouse pos is " + mouse.toString());
  ball.getBody().applyForce(new Vector2(mouse.x - ball.getBody().getPosition().x, 30), ball.getBody().getWorldCenter(), true);


  return super.fling(velocityX, velocityY, button);
}

So, how exaclty could i achive something like in that picture above? Any tips would be greatly appreciated!

Advertisement

Well, you're applying a constant vertical force of 30, and a lateral force of (mouse.x - [ball center]), in an attempt to fling the ball towards the mouse. A few questions:

* Does `mouse`, wherever it is, get updated before the fling() method is called? If not, this method will not have the expected results.

* Is `mouse` in world-space coordinates, or screen-space? If the latter, this method will not have the expected results.

* Why aren't you normalizing and then scaling the vector (velocityX,velocityY), since those are exactly the data you're trying to calculate based on `mouse`? See GestureListener.fling(float,float,int).

RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.

Well, you're applying a constant vertical force of 30, and a lateral force of (mouse.x - [ball center]), in an attempt to fling the ball towards the mouse. A few questions:

* Does `mouse`, wherever it is, get updated before the fling() method is called? If not, this method will not have the expected results.

* Is `mouse` in world-space coordinates, or screen-space? If the latter, this method will not have the expected results.

* Why aren't you normalizing and then scaling the vector (velocityX,velocityY), since those are exactly the data you're trying to calculate based on `mouse`? See GestureListener.fling(float,float,int).

Hey, thanks for the help. I did fix a couple of things based on your anwswer, here's how the fling method is looking so far:


@Override
public boolean fling(float velocityX, float velocityY, int button) {
  // Unprojecting the mouse coordinates here (screen into world coordinates).
  unproject(mouse);
  ball.getBody().setActive(true);
  System.out.println("Mouse pos is " + mouse.toString());
  // Forgot about the * PPM there.
  ball.getBody().applyForce (
     new Vector2(mouse.x - (ball.getBody().getPosition().x * PPM), 25),
     ball.getBody().getWorldCenter(),
     true
 );
 return super.fling(velocityX, velocityY, button);
}

So, right now, the results are slightly better, meaning that the body somewhat moves accordingly to the mouse position. Yet, the "mouse.x - ball center" value isn't for sure the right choice here; i'd like to make it so it would only be possible to start flinging if the mouse is dragging the body itself, something like this:


@Override
public boolean fling(float velocityX, float velocityY, int button) {
  unproject(mouse);
  // Something like this...
  if (ball.contains(mouse)) {
  ...
  ...
  ...
  }
  return super.fling(velocityX, velocityY, button);
}

where, my contains method looks like this:


public boolean contains(Vector2 worldCoordinates) {
  return getBounds().contains(worldCoordinates);
}

and getBounds() returns a rectangle like so:


@Override
public Rectangle getBounds() {
  return new Rectangle(
  body.getPosition().x * PlayState.PPM - size.x / 2,
  body.getPosition().y * PlayState.PPM - size.y / 2,
  size.x,
  size.y
  ); 
}

I've tried this under the GestureListener's Tap method and the contains seems to be working. Yet, i'm not sure how to do it for the fling. Should something like 'touchDragged' from the InputProcessor be more suitable?

What is this "PPM"?

Try printing out the force vector you're creating. I'm almost certain you're not creating the vector you want.

RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.

This topic is closed to new replies.

Advertisement