1
\$\begingroup\$

Im making a game for android im using LibGDX and Jbox2D it is a space flying exploration game controlled with the accelerometer. so I have set the world to no have no gravity. the objects in Box2D don't like having forces applied to them apparently. Just to get an object moving more then a few pixels at a time I need to use over 10,000 in applyForceToCenter()

in the Game class I get the accelerometer in the update method and create a direction vector from the input and pass that to the player

    accelX = Gdx.input.getAccelerometerX();//get the various tilts
    accelY = Gdx.input.getAccelerometerY();
    accelZ = Gdx.input.getAccelerometerZ();

    //These are backwards because the game is in landscape and not portrait
    p1Direction.x = (accelY/10); //getAccelerometer comes back -10 to 10 
    p1Direction.y = -(accelX/10); //reduce this to -1 to 1;

    p1.setDirection(p1Move);
    p1.update(Gdx.graphics.getDeltaTime());

Then In the player I apply a force to the object based on the direction:

    acceleration.x += (directionVector.x * SPEED)*deltaTime; //speed is set to 200
    acceleration.y += (directionVector.y * SPEED)*deltaTime;

    this.getBody().applyForceToCenter(acceleratiom, true);

to try and get it moving I had to add:

    acceleration.x += (directionVector.x * SPEED)*deltaTime*1000; //speed is set to 200
    acceleration.y += (directionVector.y * SPEED)*deltaTime*1000;

    this.getBody().applyForceToCenter(acceleratiom, true);

now it moves a little better, but once it gets moving it won't stop

Is there a way to fix this?

Update: The Mass, Friction, density, and restitution are all 1 right now here's the camera:

    camera = new OrthographicCamera(screenWidth,screenHeight);
    camera.setToOrtho(false,screenWidth,screenHeight);
    camera.position.set(0, 0, 0);

and the player is rendered with

batch.draw(playerTexture, this.getBody().getPosition().x, this.getBody().getPosition().y,        
    (playerTexture.getWidth()/2), (playerTexture.getHeight()/2),   
    playerTexture.getWidth(), playerTexture.getHeight(), 
    1.0f, 1.0f, this.getBody().getAngle(), 0, 0, 
    playerTexture.getWidth(),  playerTexture.getHeight(), 
false, false);
//Texture position half width(so the texture rotates in the center), width and height of the texture, scale of 1, rotate by the angle (doesn't rotate right now) source position source width and height
\$\endgroup\$
  • \$\begingroup\$ Does the body have a mass and if so, what is it? Is everything on the same scale? \$\endgroup\$ – Ben Oct 10 '14 at 9:02
  • \$\begingroup\$ Right now the body has a Mass of 1, friction of 1, density of 1, restitution of 0. Everything in the game world is on the same scale(the HUD is on a different projection matrix) \$\endgroup\$ – Snowdrama Oct 10 '14 at 9:07
  • \$\begingroup\$ What type of unit is friction in? Is 1 not quite high for friction? \$\endgroup\$ – Kurley Oct 10 '14 at 9:19
  • \$\begingroup\$ Reading through the Box2D info, friction actually only applies to objects rubbing against each other, like a box against a platform on an incline would slip with low friction, but does not effect free floating objects. the function setLinearDamping(0f); slows the linear velocity in free floating space(space friction essentially?) \$\endgroup\$ – Snowdrama Oct 10 '14 at 9:27
2
\$\begingroup\$

LET THIS BE A CAUTIONARY TALE ABOUT BOX2D! Haha! Here's the solution I came up with

The problem I amrunning into is due to the fact that Box2D uses meters instead of pixels for the scale, in my game a screen that is 1920x1080 would be 1920 meters wide and if I am using sprites a small sprite will be only as many meters wide as it is in pixels.

The reason it needs so much force is because the object is not moving in relationship to the screen well a velocity of 1 would only move it 1 pixel per step assuming Box2D iterates 1 time per "step"

to compensate for this you need to scale up the game world and then apply a pixels to meter ratio. for example:

//using this will get you the current screen resolutions
int screenWidth = Gdx.graphics.getWidth();
int screenHeight = Gdx.graphics.getHeight();

//Now set a Pixels to Meters ratio 
final int PTM_RATIO = 48; //A 48 pixel wide image will be 1 meter wide

//Now set your orthographic camera to the number of meters that the current screen fits
// this way the screen will only be 4-10 meters wide
camera = new OrthographicCamera(screenWidth/PTM_RATIO,screenHeight/PTM_RATIO);
camera.position.set(0, 0, 0)
camer.update();


//Now when rendering you want to make sure that you are telling the game to use the
//PTM_RATIO When doing anything PIXEL related:

 batch.draw(playerTexture, 
            //Body is in meters
            this.getBody().getPosition().x, this.getBody().getPosition().y, 
            //This is the position of the image from the position above
            //You divide by PTM_RATIO to get the correct meter position
            (playerTexture.getWidth()/2)/PTM_RATIO,
            (playerTexture.getHeight()/2)/PTM_RATIO, 
            //Again multiply the texture width in pixels by PTM_RATIO
            (playerTexture.getWidth()/PTM_RATIO),(playerTexture.getHeight()/PTM_RATIO),
            //Scale and angle are not in pixels
            1.0f, 1.0f, this.getBody().getAngle(), 0, 0, 
            //EXCEPTION: this is asking for the width and height of the lower right
            //corner of the sprite, setting this to the PTM_Ratio will yield 1
            //Which would get you only the first pixel(not what we want)
            playerTexture.getWidth(),  playerTexture.getHeight(), 
            false, false);

Overall this should fix the problem I you are running into. tweaking the scale of the projection will allow you to zoom in and out without moving the positions or scaling of any of the objects in LibGDX with the OrthographicCamera this can be done with:

camera.setToOrho(false, (screenWidth/PTM_RATIO)*scale,(screenHeight/PTM_RATIO)*scale);

Hope this helps anyone who also runs into a similar issue! It always happens! I somehow talking about it helps me figure it out!(don't you hate when that happens?)

Final note, your object don't need to be in "meters" consider them "units" in my case its a space game and I am calling it 1 "Ship Length" because my ships are not 1 meter wide but it gives me a sense of scale things smaller then a ship are less then 1 larger then a ship is bigger (planets are like 10-20 Ship lengths for example)

\$\endgroup\$
  • \$\begingroup\$ Thanks for posting the answer. Please come back in a day or two and mark it as the "right" answer (green checkmark next to the vote count) \$\endgroup\$ – ashes999 Oct 10 '14 at 13:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.