Libgdx Box2d body 坠落时失去速度
Libgdx Box2d body losing speed while falling
我是 Box2d 的新手,我正在尝试制作一个简单的程序让 body 掉落时在其上绘制精灵。当我 运行 我的程序时,一切正常,除了 body 的速度一直在下降,但仍在加速下降。例如,速度为 0、-10、-20、-30、-40、-50、-60、-20、-30、-40、-50……等等。很可能我做错了什么,因为我对此很陌生。感谢您的帮助!
package com.davejones.spritetest;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
public class SpriteTest extends ApplicationAdapter {
private SpriteBatch batch;
private World world;
private BodyDef bodyDef;
private Body body;
private Texture texture;
private Sprite sprite;
private OrthographicCamera camera;
private Box2DDebugRenderer debugRenderer;
@Override
public void create () {
debugRenderer = new Box2DDebugRenderer();
debugRenderer.setDrawBodies(false);
camera = new OrthographicCamera();
batch = new SpriteBatch();
texture = new Texture("badlogic.jpg");
sprite = new Sprite(texture);
sprite.setPosition(Gdx.graphics.getWidth() / 2 - sprite.getWidth() / 2, Gdx.graphics.getHeight() / 2);
world = new World(new Vector2(0, -10), true);
bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set(sprite.getX(), sprite.getY());
body = world.createBody(bodyDef);
PolygonShape shape = new PolygonShape();
shape.setAsBox(sprite.getWidth()/2, sprite.getHeight()/2);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = 1f;
Fixture fixture = body.createFixture(fixtureDef);
shape.dispose();
}
@Override
public void resize(int width, int height) {
super.resize(width, height);
float cameraWidth = Gdx.graphics.getWidth();
float cameraHeight = Gdx.graphics.getHeight();
camera.setToOrtho(false, cameraWidth, cameraHeight);
camera.position.set(Gdx.graphics.getWidth() / 2 - sprite.getWidth() / 2, Gdx.graphics.getHeight() / 2 - sprite.getHeight() / 2, 0);
}
@Override
public void render () {
world.step(Gdx.graphics.getDeltaTime(), 8, 3);
sprite.setPosition(body.getPosition().x, body.getPosition().y);
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(sprite, sprite.getX(), sprite.getY());
batch.end();
System.out.println(body.getLinearVelocity().y);
camera.update();
debugRenderer.render(world, camera.combined);
}
@Override
public void dispose () {
batch.dispose();
texture.dispose();
world.dispose();
debugRenderer.dispose();
}
}
Box2d 最适用于 0.1 到 10 之间的值,因为超过这些大小的值开始失去精度。每个 Box2D 单位应该代表 1 米,因此您的对象是 256 米 x 256 米,这是巨大的。再加上 Box2D 对物体的最大速度限制为每步 2 米,这意味着您的 256 米方形物体以 60 FPS 的速度以每秒 120 米的速度下落,超过 250 mph。
这通常通过在屏幕单位和 box2d 单位之间使用某种形式的转换来解决。使用常数值将 256 转换为 0.1 到 10 的范围,或者使用相机矩阵在屏幕上渲染更大的对象。
我已将您的示例更新为使用视口。这不会解决 Box2D 最大速度的问题,但它应该有助于通过使用与 Box2D 设计为最适合使用的单位相匹配的较小对象来减少影响。
package com.mygdx.gtest;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.utils.viewport.ExtendViewport;
public class Test extends ApplicationAdapter {
private SpriteBatch batch;
private World world;
private BodyDef bodyDef;
private Body body;
private Texture texture;
private Sprite sprite;
private Box2DDebugRenderer debugRenderer;
private ExtendViewport viewport;
@Override
public void create() {
debugRenderer = new Box2DDebugRenderer(true,true,true,true, true, true);
viewport = new ExtendViewport(64,48); // adding viewport so we can use multiple resolutions easily
viewport.getCamera().position.set(32, 24, 0); // set cam position to make 0,0 bottom left corner
batch = new SpriteBatch();
batch.setProjectionMatrix(viewport.getCamera().combined); // tell the batch how things should be rendered
texture = new Texture("badlogic.jpg");
sprite = new Sprite(texture);
sprite.setSize(10,10); // set the size of the sprite in box2d units (10 meters x 10 meters)
// not needed as position is set in update method
//sprite.setPosition(Gdx.graphics.getWidth() / 2 - sprite.getWidth() / 2, Gdx.graphics.getHeight() / 2);
world = new World(new Vector2(0, -10), true);
bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set(32 , 47);
body = world.createBody(bodyDef);
PolygonShape shape = new PolygonShape();
shape.setAsBox(5,5);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = 1f;
Fixture fixture = body.createFixture(fixtureDef);
shape.dispose();
}
@Override
public void resize(int width, int height) {
viewport.update(width, height);
}
@Override
public void render() {
world.step(Gdx.graphics.getDeltaTime(), 8, 3);
sprite.setPosition(body.getPosition().x - (sprite.getWidth()/2), body.getPosition().y -(sprite.getHeight()/2));
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(viewport.getCamera().combined); // tell the batch how things should be rendered incase of resized window
batch.begin();
batch.draw(sprite, sprite.getX(), sprite.getY(),sprite.getWidth(),sprite.getHeight());
batch.end();
System.out.println(body.getLinearVelocity().y);
debugRenderer.render(world, viewport.getCamera().combined);
}
@Override
public void dispose() {
batch.dispose();
texture.dispose();
world.dispose();
debugRenderer.dispose();
}
}
我是 Box2d 的新手,我正在尝试制作一个简单的程序让 body 掉落时在其上绘制精灵。当我 运行 我的程序时,一切正常,除了 body 的速度一直在下降,但仍在加速下降。例如,速度为 0、-10、-20、-30、-40、-50、-60、-20、-30、-40、-50……等等。很可能我做错了什么,因为我对此很陌生。感谢您的帮助!
package com.davejones.spritetest;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
public class SpriteTest extends ApplicationAdapter {
private SpriteBatch batch;
private World world;
private BodyDef bodyDef;
private Body body;
private Texture texture;
private Sprite sprite;
private OrthographicCamera camera;
private Box2DDebugRenderer debugRenderer;
@Override
public void create () {
debugRenderer = new Box2DDebugRenderer();
debugRenderer.setDrawBodies(false);
camera = new OrthographicCamera();
batch = new SpriteBatch();
texture = new Texture("badlogic.jpg");
sprite = new Sprite(texture);
sprite.setPosition(Gdx.graphics.getWidth() / 2 - sprite.getWidth() / 2, Gdx.graphics.getHeight() / 2);
world = new World(new Vector2(0, -10), true);
bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set(sprite.getX(), sprite.getY());
body = world.createBody(bodyDef);
PolygonShape shape = new PolygonShape();
shape.setAsBox(sprite.getWidth()/2, sprite.getHeight()/2);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = 1f;
Fixture fixture = body.createFixture(fixtureDef);
shape.dispose();
}
@Override
public void resize(int width, int height) {
super.resize(width, height);
float cameraWidth = Gdx.graphics.getWidth();
float cameraHeight = Gdx.graphics.getHeight();
camera.setToOrtho(false, cameraWidth, cameraHeight);
camera.position.set(Gdx.graphics.getWidth() / 2 - sprite.getWidth() / 2, Gdx.graphics.getHeight() / 2 - sprite.getHeight() / 2, 0);
}
@Override
public void render () {
world.step(Gdx.graphics.getDeltaTime(), 8, 3);
sprite.setPosition(body.getPosition().x, body.getPosition().y);
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(sprite, sprite.getX(), sprite.getY());
batch.end();
System.out.println(body.getLinearVelocity().y);
camera.update();
debugRenderer.render(world, camera.combined);
}
@Override
public void dispose () {
batch.dispose();
texture.dispose();
world.dispose();
debugRenderer.dispose();
}
}
Box2d 最适用于 0.1 到 10 之间的值,因为超过这些大小的值开始失去精度。每个 Box2D 单位应该代表 1 米,因此您的对象是 256 米 x 256 米,这是巨大的。再加上 Box2D 对物体的最大速度限制为每步 2 米,这意味着您的 256 米方形物体以 60 FPS 的速度以每秒 120 米的速度下落,超过 250 mph。
这通常通过在屏幕单位和 box2d 单位之间使用某种形式的转换来解决。使用常数值将 256 转换为 0.1 到 10 的范围,或者使用相机矩阵在屏幕上渲染更大的对象。
我已将您的示例更新为使用视口。这不会解决 Box2D 最大速度的问题,但它应该有助于通过使用与 Box2D 设计为最适合使用的单位相匹配的较小对象来减少影响。
package com.mygdx.gtest;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.utils.viewport.ExtendViewport;
public class Test extends ApplicationAdapter {
private SpriteBatch batch;
private World world;
private BodyDef bodyDef;
private Body body;
private Texture texture;
private Sprite sprite;
private Box2DDebugRenderer debugRenderer;
private ExtendViewport viewport;
@Override
public void create() {
debugRenderer = new Box2DDebugRenderer(true,true,true,true, true, true);
viewport = new ExtendViewport(64,48); // adding viewport so we can use multiple resolutions easily
viewport.getCamera().position.set(32, 24, 0); // set cam position to make 0,0 bottom left corner
batch = new SpriteBatch();
batch.setProjectionMatrix(viewport.getCamera().combined); // tell the batch how things should be rendered
texture = new Texture("badlogic.jpg");
sprite = new Sprite(texture);
sprite.setSize(10,10); // set the size of the sprite in box2d units (10 meters x 10 meters)
// not needed as position is set in update method
//sprite.setPosition(Gdx.graphics.getWidth() / 2 - sprite.getWidth() / 2, Gdx.graphics.getHeight() / 2);
world = new World(new Vector2(0, -10), true);
bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set(32 , 47);
body = world.createBody(bodyDef);
PolygonShape shape = new PolygonShape();
shape.setAsBox(5,5);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = 1f;
Fixture fixture = body.createFixture(fixtureDef);
shape.dispose();
}
@Override
public void resize(int width, int height) {
viewport.update(width, height);
}
@Override
public void render() {
world.step(Gdx.graphics.getDeltaTime(), 8, 3);
sprite.setPosition(body.getPosition().x - (sprite.getWidth()/2), body.getPosition().y -(sprite.getHeight()/2));
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(viewport.getCamera().combined); // tell the batch how things should be rendered incase of resized window
batch.begin();
batch.draw(sprite, sprite.getX(), sprite.getY(),sprite.getWidth(),sprite.getHeight());
batch.end();
System.out.println(body.getLinearVelocity().y);
debugRenderer.render(world, viewport.getCamera().combined);
}
@Override
public void dispose() {
batch.dispose();
texture.dispose();
world.dispose();
debugRenderer.dispose();
}
}