我正在尝试摆脱使用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
缩放IMPULSE
和PIXELS_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)有更好的方法吗?
答案 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米相匹配。
祝你好运。