【发布时间】:2015-08-05 00:38:32
【问题描述】:
我是一名新手游戏开发者。我一直在尝试使用 LibGDX 和 Box2D 物理引擎开发游戏,但是当我导出我的 android 应用程序时,它无法正常工作。
这个问题出现在某些设备上;不管是旧设备还是新设备。
例如,该应用在 Sony Xperia Z1、摩托罗拉 XT615、LG L1、LG L3、LG L5 等中运行良好。但是,在索尼 Xperia U、摩托罗拉 Moto E、三星 Galaxy 上,并没有像我预期的那样工作。
当对象在屏幕上移动时,您可以看到非流体行为。这就是我遇到的问题。这就像口吃效果,而不是流畅的。
我在论坛上读到,当我在世界上设置时间步长时,它可能是一个 FPS(每秒帧数)问题。因此,我使用的是固定时间步长方法,并使用“累加器”中的剩余时间对其进行插值。我读了这些文章:
http://gafferongames.com/game-physics/fix-your-timestep/
http://saltares.com/blog/games/fixing-your-timestep-in-libgdx-and-box2d/
学习了固定时间步长和插值方法,但是我觉得我的代码有一个看不到的fail。
这是我的代码:
public class MyGame extends ApplicationAdapter {
SpriteBatch batch;
Texture img;
Sprite sprite;
Body body;
Box2DDebugRenderer debugRenderer;
OrthographicCamera camera;
World world;
final float PixelsToMeters=100f;
float step = 1.0f / 60.0f ,alpha;
Vector2 currentPosition,lastPosition,position;
double currentTime,accumulator,lastAngle,currentAngle;
final float BODY_WIDTH=95f,BODY_HEIGHT=95f;
@Override
public void create () {
world= new World(new Vector2(0f,-9.8f),true);
batch = new SpriteBatch();
img = new Texture("circulo.png");
sprite=new Sprite(img);
//BODY DEFINITION
BodyDef bodydef=new BodyDef();
bodydef.type= BodyType.DynamicBody;
bodydef.position.set(-3.5f,-2.4f);
body=world.createBody(bodydef);
CircleShape shape=new CircleShape();
shape.setRadius((sprite.getWidth()/2)/PixelsToMeters);
FixtureDef fixturedef=new FixtureDef();
fixturedef.shape=shape;
fixturedef.density=0.1f;
fixturedef.restitution=1f;
fixturedef.friction=0.5f;
body.createFixture(fixturedef);
shape.dispose();
//SET SPRITE POSITION
sprite.setPosition(body.getPosition().x *PixelsToMeters - BODY_WIDTH/2,
body.getPosition().y * PixelsToMeters - BODY_HEIGHT/2);
//THROW CIRCLE
body.setLinearVelocity(3.5f,9.5f);
lastPosition=new Vector2();
position=new Vector2();
camera=new
OrthographicCamera(Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
}
@Override
public void render () {
camera.update();
double newTime = TimeUtils.millis() / 1000.0;
double frameTime = Math.min(newTime - currentTime, 0.25);
float deltaTime = (float)frameTime;
currentTime = newTime;
accumulator+=deltaTime;
while (accumulator >= step) {
//SAVE LAST BODY POSITION AND ANGLE
lastPosition.x=body.getPosition().x;
lastPosition.y=body.getPosition().y;
lastAngle=body.getAngle();
world.step(step, 8, 3);
accumulator -= step;
}
//SAVE CURRENT BODY POSITION AND ANGLE
currentPosition= new Vector2(body.getPosition().x,body.getPosition().y);
currentAngle=body.getAngle();
alpha=(float) (accumulator/step);
position.x = lastPosition.x + (currentPosition.x - lastPosition.x) * alpha;
position.y = lastPosition.y + (currentPosition.y - lastPosition.y) * alpha;
sprite.setPosition(position.x * PixelsToMeters - BODY_WIDTH/2, position.y * PixelsToMeters
-BODY_HEIGHT/2);
sprite.setRotation((float)Math.toDegrees(lastAngle+(currentAngle-lastAngle)*alpha));
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(sprite, sprite.getX(), sprite.getY(),
sprite.getOriginX(), sprite.getOriginY(),
sprite.getWidth(), sprite.getHeight(), sprite.getScaleX(),
sprite.getScaleY(), sprite.getRotation());
batch.end();
}
@Override
public void dispose() {
world.dispose();
batch.dispose();
img.dispose();
super.dispose();
}
}
【问题讨论】:
-
您是否尝试将精灵位置设置为身体的位置,而不是计算每帧的位置?可能是浮动问题,因为您在不同设备上的行为不同。
标签: java libgdx box2d interpolation fluid