我是一名新手游戏开发者。我一直在尝试使用LibGDX和Box2D物理引擎开发游戏,但是当我导出我的Android应用程序时,它不能正常工作。
某些设备会出现此问题;如果它是旧设备或新设备并不重要。
例如,该应用程序在Sony Xperia Z1,Motorola 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/
学习固定时间步和插值方法,但我认为我的代码中有一个我无法看到的失败。
这是我的代码:
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();
}
}
答案 0 :(得分:0)
在使用box2d之前我遇到了这个问题,当物理步骤耗时超过1/60秒时,小口吃。
我也试过插值并阅读了很多关于它的文章而没有任何成功。
最后,我根本没有使用固定的时间步长(只是delta到世界步骤),所有这一切都顺利用box2d。
但如果您仍想使用固定步骤,我有一些建议:
Gdx.graphics.getDeltaTime()
,因为它为您提供了前n帧的平滑增量。world.step(deltaTime, 8, 3);
和accumulator -= deltaTime
。希望它有所帮助!