所以我在2d的盒子里制作游戏。在一个部分中,我需要一个具有恒定弹跳高度的球。我将球的恢复原状设定为1并且不对其施加任何力(当然除了重力)。现在这个球在每次弹跳时,每次弹跳都会高一点,直到它从屏幕的顶部边缘移出。这段代码有什么问题?
public class Ball implements ApplicationListener {
World world ;
Box2DDebugRenderer debugRenderer;
OrthographicCamera camera;
static final float BOX_STEP=1/60f;
static final int BOX_VELOCITY_ITERATIONS=8;
static final int BOX_POSITION_ITERATIONS=3;
static final float WORLD_TO_BOX=0.01f;
static final float BOX_WORLD_TO=100f;
Rectangle ball;
Body body;
/* (non-Javadoc)
* @see com.badlogic.gdx.ApplicationListener#create()
*/
@Override
public void create() {
world = new World(new Vector2(0, -10), true);
camera = new OrthographicCamera();
camera.viewportHeight = 480;
camera.viewportWidth = 800;
camera.position.set(camera.viewportWidth * .5f, camera.viewportHeight * .5f, 0f);
camera.update();
//Ground body
BodyDef groundBodyDef =new BodyDef();
groundBodyDef.position.set(new Vector2(0, 10 * WORLD_TO_BOX));
Body groundBody = world.createBody(groundBodyDef);
PolygonShape groundBox = new PolygonShape();
float w = (camera.viewportWidth * 2) * WORLD_TO_BOX;
float h = 10.0f * WORLD_TO_BOX;
groundBox.setAsBox(w,h);
groundBody.createFixture(groundBox, 0.0f);
String a="gb";
groundBody.setUserData(a);
//Dynamic Body
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.DynamicBody;
float posX = (camera.viewportWidth / 8) * WORLD_TO_BOX;
float posY = (camera.viewportHeight / 2) * WORLD_TO_BOX;
bodyDef.position.set(posX, posY);
body = world.createBody(bodyDef);
// create a Rectangle to logically represent the ball
CircleShape dynamicCircle = new CircleShape();
dynamicCircle.setRadius(1f);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = dynamicCircle;
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.0f;
fixtureDef.restitution =1f;
body.createFixture(fixtureDef);
debugRenderer = new Box2DDebugRenderer();
}
@Override
public void dispose() {
}
@Override
public void render() {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
debugProjection.set(camera.combined);
debugProjection.scl(BOX_WORLD_TO);
debugRenderer.render(world, debugProjection);
world.step(BOX_STEP, BOX_VELOCITY_ITERATIONS, BOX_POSITION_ITERATIONS);
}
@Override
public void resize(int width, int height) {
}
@Override
public void pause() {
}
@Override
public void resume() {
}
}
答案 0 :(得分:2)
这可能是由numerical instability引起的。反复计算你的球的位置不可避免地会引入微小的数值误差(因为浮点数只能容纳有限数量的数字)。这些可能会增长并从迭代到迭代相加,反弹到反弹。
您可以尝试使用恢复原状0.9999999或其他东西。但是很可能没有恢复价值可以产生预期的结果。
尝试主动补偿数值不稳定性,例如通过在非迭代计算值的情况下控制球的位置和/或速度。 (我不知道Box2D。也许当球撞到地面时你可以重置它的速度等等。)
答案 1 :(得分:0)
好的我通过将恢复原状设置为0并在每个接触上施加5N的向上力来解决它。正如halfbit所说,问题是因为box2d使用float,位置计算不精确,导致每次弹跳时高度发生微小变化。
答案 2 :(得分:0)
如果我已经完成了计算的数学运算,你的球体半径为1米,你的球体尺寸为16米x 0.1米。
在Box2d中,一切都需要在0.1米到10米的范围内。您的身体在数值上不稳定的原因是因为宽度与高度的比率大于对象的正常尺寸。虽然你可以通过改变恢复原状来获得稳定性,但我认为你将永远处于这些维度的“毛边”。
尝试更改对象的尺寸,使宽度为8,高度为0.1。