为什么不简单地在LibGDX和Box2D中进行扩展工作?

时间:2015-01-04 19:40:55

标签: java libgdx box2d

我正在尝试摆脱使用Box2D和LibGDX时必须缩放精灵上的所有坐标。

以下是我的视口和物理世界的设置:

// Used to create an Extend Viewport
public static final int MIN_WIDTH = 480;
public static final int MIN_HEIGHT = 800;
// Used to scale all sprite's coordinates
public static final float PIXELS_TO_METERS = 100f;
// Used with physics world.
public static final float GRAVITY = -9.8f;
public static final float IMPULSE = 0.15f;
world.setGravity(new Vector2(0f, GRAVITY));

当我对我的角色施加线性冲动时(当用户点击屏幕时)一切正常:

body.setLinearVelocity(0f, 0f);
body.applyLinearImpulse(0, IMPULSE, body.getPosition().x, body.getPosition().y, true);

正文的密度为0f,但将其更改为1f甚至100f似乎没有任何实际效果。

这意味着我必须通过PIXELS_TO_METERS缩放draw方法中所有精灵的位置。我想(也许是错误的)我可以简单地按GRAVITY缩放IMPULSEPIXELS_TO_METERS并让它完全相同。似乎并非如此。重力似乎很小,施加冲动几乎没有任何影响。

// Used to scale all sprite's coordinates
public static final float PIXELS_TO_METERS = 1f;
// Used with physics world.
public static final float GRAVITY = -9.8f * 100;
public static final float IMPULSE = 0.15f * 100;

所以:

1)为什么不简单地放大所有值使其工作原理相同?

2)有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

看起来你通过使用一些虚构的像素单元使你的设计变得复杂(我怀疑它是你所指的实际像素)。我建议你使用有意义的单位,例如meters,并坚持下去。因此,对所有坐标(包括虚拟视口)使用米。所以,实际上修改你的代码看起来像这样:

// Used to create an Extend Viewport
public static final float MIN_WIDTH = 4.8f; // at least 4.8 meters in width is visible
public static final float MIN_HEIGHT = 8.0f; // at least 8 meter in height is visible

这完全消除了将仪表缩放到虚构像素单元的需要。从您的单位(虚拟视口大小)到screen (values between -1 and +1)的实际缩放由camera完成。您不必考虑在设计中缩放单位。

确保删除PIXELS_TO_METERS常量(不要将其设置为1f,这只会使代码无法获得增益)并确保您根本不使用虚拟像素你的代码。后者包括您创建的所有精灵,而不是以米为单位明确指定其大小。

由于有正当理由,与SI单位相比,仍然可以“缩放”您的单位(在您的游戏逻辑中)。例如,在创建太空游戏时,您可能会在使用仪表时发现自己使用非常大的数字。通常,您希望将值保持在1f左右以避免浮点错误。在这种情况下,使用例如它是有用的。 dekameters(x10),百米(x100)或千米(x1000)代替。如果这样做,请确保一致。在评论中添加单位可能会有所帮助,因此您不要忘记正确缩放(例如GRAVITY = -0.0098f; // kilometer per second per second)。

答案 1 :(得分:0)

我已经实现了这个:

// in declaration
float PIXELS_TO_METERS = 32; // in my case: 1m = 32 pixels
Matrix4 projection = new Matrix4();

// in creation
viewport = new FitViewport(
        Application.width
        , Application.height
        , Application.camera);
viewport.apply();

// set vieport dimensions
camera.setToOrtho(false, gameWidth, gameHeight);

// in render
projection.set(batch.getProjectionMatrix());
projection.scl(PIXELS_TO_METERS);
box2dDebugRenderer.render(world, projection);

// in player body creation
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.x = getPosition().x / PIXELS_TO_METERS;
bodyDef.position.y = getPosition().y / PIXELS_TO_METERS;

CircleShape shape = new CircleShape();
shape.setRadius((getBounds().width * 0.5f) / PIXELS_TO_METERS);

// in player update
setPosition(
    body.getPosition().x * PIXELS_TO_METERS - playerWidth,
    body.getPosition().y * PIXELS_TO_METERS - playerHeight);

因此,要在box2d方法中将像素设置为米,您必须将像素位置除以PIXELS_TO_METERS,并将米设置为玩家位置的像素,您必须将box2d值乘以PIXELS_TO_METERS。

将PIXELS_TO_METERS正确设置为屏幕中的像素与1米相匹配。

祝你好运。