Leonardo Drici
Leonardo Drici

Reputation: 789

Libgdx - PPM world conversion

My sprite moves too slowly. Basically I want to apply less force to move my player. Current this:

getBody().applyForceToCenter(new Vector2(-10000000f,0f), true);

is the force needed to make it move a tiny bit.

I know the reason why I am not able to move it is since I haven't scaled the sprite (64x64) it weights more than 400kg. What should be the correct scale?

This is my game screen.

public class GameScreen implements Screen {
//Reference to our Game, used to set Screens
private Logang game;

//basic playscreen variables
private OrthographicCamera gamecam;
private Viewport gamePort;
//Box2d variables
private World world;
private Box2DDebugRenderer b2dr;

boolean drawn = true;
private Player p;
private int pX = 100, pY = 300;

public GameScreen(Logang game) {

    this.game = game;
    //create cam used to follow mario through cam world
    gamecam = new OrthographicCamera();
    gamePort = new ScalingViewport(Scaling.stretch, Logang.GWIDTH, Logang.GHEIGHT, gamecam);
    gamePort.apply();
    gamecam.position.set(gamecam.viewportWidth / 2, gamecam.viewportHeight / 2, 0);
    gamecam.update();
    Box2D.init();
    //create our Box2D world, setting no gravity in X, -10 gravity in Y, and allow bodies to sleep
    world = new World(new Vector2(0, Logang.GRAVITY), true);
    //allows for debug lines of our box2d world.
    b2dr = new Box2DDebugRenderer();

    //create a FitViewport to maintain virtual aspect ratio despite screen size

    p = new Player(new Sprite(new Texture("hud_p3.png")), world, pX, pY, 1);

    //initially set our gamcam to be centered correctly at the start of of map

    line();
}


@Override
public void show() {

}

public void update(float dt) {
    //handle user input first
    p.update(dt);
    //update our gamecam with correct coordinates after changes
}


@Override
public void render(float delta) {
    //separate our update logic from render
    update(delta);

    //Clear the game screen with Black
    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    world.step(1f / 60f, 6, 2);

    gamecam.position.set(p.getSprite().getX(),Logang.GHEIGHT / 2, 0); // x and y could be changed by Keyboard input for example

    gamecam.update();

    game.getBatch().setProjectionMatrix(gamecam.combined);

    //renderer our Box2DDebugLines
    b2dr.render(world, gamecam.combined);

    System.out.println("Player x: " + p.getSprite().getX() + " Camera X: " + gamecam.position.x + " Body X: " + p.getBody().getPosition().x);
    //System.out.println("Player y: " + p.getSprite().getY() + " Camera Y: " + gamecam.position.y + " Body Y: " + p.getBody().getPosition().y);


    game.getBatch().begin();


    if (p.getBody() != null)
        p.render(game.getBatch());

    EntityManager.renderTerra(game.getBatch(), delta);


    game.getBatch().end();

}

public void line() {
    Texture tmp = new Texture("hud_p3.png");
    tmp.setWrap(Texture.TextureWrap.MirroredRepeat, Texture.TextureWrap.MirroredRepeat);
    for (int i = 0; i < 50; i++) {
        EntityManager.add(new Ground(new Sprite(tmp), world, (int)(i * Logang.TILE), 1, 2));
    }
   // EntityManager.changeSize(((Logang.TILE) * 5),Logang.TILE);
}

@Override
public void resize(int width, int height) {
    //updated our game viewport
    gamePort.update(width, height);
    gamecam.position.set(gamecam.viewportWidth / 2, gamecam.viewportHeight / 2, 0);
}

public World getWorld() {
    return world;
}

@Override
public void pause() {

}

@Override
public void resume() {

}

@Override
public void hide() {

}

@Override
public void dispose() {
    world.dispose();
    b2dr.dispose();
}

And this is my entity class

private World world;
private Sprite sprite;
private Body body;
private int tipo;

public Entity(Sprite sprite, World world, int x, int y, int tipo) {
this.sprite = sprite;
this.world = world;
getSprite().setPosition(x, y);
sprite.setSize(Logang.TILE, Logang.TILE);
sprite.setOriginCenter();
define(tipo);
this.tipo = tipo;
}

public void update(float dt){
if(Gdx.input.isKeyPressed(Input.Keys.LEFT)){
    getBody().applyForceToCenter(new Vector2(-10000000f,0f), true);
}
if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)){
    getBody().applyForceToCenter(new Vector2(10000000f,0f), true);
}
if(Gdx.input.isKeyPressed(Input.Keys.SPACE)){
    //getBody().applyLinearImpulse(0f,-Logang.GRAVITY, 
getBody().getPosition().x, getBody().getPosition().y, true);
     }
}

public void define(int tipo) {
BodyDef bdef = new BodyDef();
bdef.position.set((getSprite().getX() + getSprite().getWidth() / 2), 
(getSprite().getY() + getSprite().getHeight() / 2));
switch (tipo) {
    case 1: {
        bdef.type = BodyDef.BodyType.DynamicBody;
        break;
    }
    case 2: {
        bdef.type = BodyDef.BodyType.StaticBody;
        break;
    }
    case 3: {
        bdef.type = BodyDef.BodyType.DynamicBody;
        break;
    }

}

body = world.createBody(bdef);

FixtureDef fdef = new FixtureDef();
fdef.density=0.001f; // (weight: range 0.01 to 1 is good)
PolygonShape shape = new PolygonShape();
shape.setAsBox(getSprite().getWidth() / 2, getSprite().getHeight() / 2);

fdef.shape = shape;
body.createFixture(fdef);
body.setUserData(this);

shape.dispose();
}

public void render(SpriteBatch batch) {
if (tipo != 2) {
    float posX = getBody().getPosition().x;
    float posY = getBody().getPosition().y;

        getSprite().setPosition(posX - getSprite().getWidth() / 2, posY - 
getSprite().getHeight() / 2);

    }
    getSprite().draw(batch);
}

public Sprite getSprite() {
    return sprite;
}

public void setSprite(Sprite sprite) {
    this.sprite = sprite;
}

public Body getBody() {
    return body;
}

public void setBody(Body body) {
    this.body = body;
}

And this are the in game variables

public static final int GWIDTH = 800;
public static final int GHEIGHT = (GWIDTH/16)*9;
public static final float PPM = 100f;
public static final float GRAVITY = -10f;
public static final float TILE = 64;

Could you please give me a fix? I already tried to divide body and gamecam position still no effect

Upvotes: 0

Views: 1158

Answers (1)

Madmenyo
Madmenyo

Reputation: 8584

What should be the correct scale?

The right scale would be the scale in real life where 1 unit in LibGDX (Box2D) represents 1 meter in real life. I always advice people to use this scale and zoom the camera properly.

Mind though, if you are using very large objects and zoom the camera all the way back objects appear to be falling slowly. This is obviously because your camera contains a much larger space. Not only would it fall slowly but it won't interact properly with the world if the item is supposed to be smaller.

Adept the camera to your world, not your world to your camera.

More detailed answer I gave

Upvotes: 1

Related Questions