• Advertisement
Sign in to follow this  

Box2D in LibGDX - Throwing body based on swipe angle.

This topic is 736 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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!

 

 

 

Share this post


Link to post
Share on other sites
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).

Edited by Wyrframe

Share this post


Link to post
Share on other sites

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? 

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement