0
\$\begingroup\$

I have a game that was written in pixels and now I want to change it to meters like(box2D do). How I need to do that. I have wached a lot of tutorials and all they have some SCALING FACTOR but when I implement it my game don't work as I aspected. How I need to do that? For example I have a Coin and I want to make position of that coin random. I also want that coin sprite have a CircleShape (Box2D). Here are my code where I update my coin coordinates at specific time

if(time > 1.5f && !goToWallet && setUpCoin){
                coin.setCoinPosition(-100, -100); // do not show coin on the screen
                coin.update(coin.getCoinX(), coin.getCoinY());
                cam.update();
                if(showTime > MathUtils.random(5, 20) && !goToWallet){
                    coin.setCoinPosition(MathUtils.random(50, Gdx.graphics.getWidth() - 50)/100f, MathUtils.random(50, Gdx.graphics.getHeight() - 50)/100f); // random position of the screen IN PIXELS!!!
                    coin.update(coin.getCoinX(), coin.getCoinY());
                    cam.update();
                    time = showTime = 0.0f;
                }
            }

The problem is that is very easy to do in pixels, but How I need to do that in meters?

Here's my Coin class

public class Coin {
    /*
    A lot of variables
    */

    private final float radius;
    private BodyDef body;
    private FixtureDef bodyPhysics;
    private static Box2DDebugRenderer rend;
    private static World world;
    private static CircleShape coin;

    public Coin(World world, Box2DDebugRenderer rend){
        this.rend = rend;
        this.world = world;

        body = new BodyDef();
        bodyPhysics = new FixtureDef();
        coin = new CircleShape();
        coin.setRadius(.05f);
        body.type = BodyType.StaticBody;
        bodyPhysics.shape = coin;
        world.createBody(body).createFixture(bodyPhysics);
}
public void setCoinPosition(float x, float y){
    this.x = x;
    this.y = y;
    coin.setPosition(new Vector2(x, y));
}

}

\$\endgroup\$
1
\$\begingroup\$

Like you said, you need a scaling factor.

float scaling = // some number. Probably something like 100 will do for Box2D.

public Vector2 metersToPixels(float xMeters, float yMeters) {
    return new Vector2(xMeters / scaling, yMeters / scaling);    
}

public Vector2 pixelsToMeters(float xPixels, float yPixels) {
    return new Vector2(xPixels * scaling, yPixels * scaling);    
}

public void setCoinPositionPixels(float x, float y){
    // Assuming "x", "y" etc. are in pixels.
    this.x = x;
    this.y = y;
    // But Box2D is in meters
    coin.setPosition(pixelsToMeters(x, y));
}

Then all of your earlier functions should magically work.

Also, I think you're a bit confused about Box2D. In Box2D, a body is a physical object with mass, moment of inertia, etc. Many fixtures may be attached to a body, but they are relative to the body's center of mass. By default, the fixtures will move with the body (i.e they may fall with gravity). So what you probably want is something like:

coin.body.SetTransform(pixelsToMeters(x, y), 0.0f);

That will move the body instead of the fixture, which is probably what you want. Note that the body will still behave according to gravity after you've moved it.

|improve this answer|||||
\$\endgroup\$

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.