当前位置: 首页 > 知识库问答 >
问题:

Libgdx box2d body移动缓慢

祁高格
2023-03-14

这是一个使用box2d的非常简单的场景。我尝试了不同的视口和不同的屏幕尺寸。我不明白为什么尸体下落得很慢。实际上,我不太确定它是否慢,原因可能是视口设置等。这是主类:

public class Main extends Game {
LevelScreen levelScreen;

@Override
public void create () {
    levelScreen = new LevelScreen();
    setScreen(levelScreen);

}

@Override
public void render () {
    super.render();
}
}

和水平屏幕:

public class LevelScreen extends Stage implements Screen {

private Batch batch;
private Camera camera;
private Texture ballTexture;
private Sprite ball;
private Viewport viewport;
//com

private Vector3 point = new Vector3();

private World world;
private Box2DDebugRenderer box2DDebugRenderer;

private CircleShape circleShape;
private FixtureDef fixtureDef;
private BodyDef bodyDef;
private Body circleBody;

private static final float SCENE_WIDTH = 1080;
private static final float SCENE_HEIGHT = 1920f;


public LevelScreen() {
    super(new FitViewport(SCENE_WIDTH, SCENE_HEIGHT,  new OrthographicCamera(SCENE_WIDTH, SCENE_HEIGHT)));


    batch = getBatch();
    camera = getCamera();
    viewport = getViewport();

    world = new World(new Vector2(0,-9.8f), true);
    box2DDebugRenderer = new Box2DDebugRenderer();
    bodyDef = new BodyDef();
    bodyDef.type = BodyDef.BodyType.DynamicBody;
    bodyDef.position.set(600, 1000);

    ballTexture = new Texture("ball.png");
    ball = new Sprite(ballTexture);
    ball.setPosition(0,0);

    circleShape = new CircleShape();
    circleShape.setRadius(25f);

    fixtureDef = new FixtureDef();
    fixtureDef.shape = circleShape;
    fixtureDef.density = 0.5f;
    fixtureDef.friction = 0.4f;
    fixtureDef.restitution = 0.6f;

    circleBody = world.createBody(bodyDef);
    circleBody.createFixture(fixtureDef);

    box2DDebugRenderer = new Box2DDebugRenderer(
            true, /* draw bodies */
            false, /* don't draw joints */
            true, /* draw aabbs */
            true, /* draw inactive bodies */
            false, /* don't draw velocities */
            true /* draw contacts */);

    Gdx.input.setInputProcessor(this);


}

@Override
public void show() {
    System.out.println("show");
}

@Override
public void render(float delta) {
    Gdx.gl.glClearColor(1, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    batch.setProjectionMatrix(camera.combined);

    batch.begin();
    ball.draw(batch);

    batch.end();

    world.step(1 / 60f, 6, 2);
    ball.setPosition(circleBody.getPosition().x - 25f, circleBody.getPosition().y - 25f);
    box2DDebugRenderer.render(world, viewport.getCamera().combined);

}

@Override
public void resize(int width, int height) {
    viewport.update(width, height);
    System.out.println("resize");
}

@Override
public void pause() {
    System.out.println("pause");
}

@Override
public void resume() {
    System.out.println("resume");
}

@Override
public void hide() {
    System.out.println("hide");
}

@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
    viewport.getCamera().unproject(point.set(screenX, screenY, 0));
    return false;
}
}

共有2个答案

苏墨竹
2023-03-14

您应该为box2d使用小型摄像机,因为box2d在0-10的值下工作得更好。这是你的水平屏幕类。试试看。

    public class LevelScreen extends Stage implements Screen {

         private Batch batch;
         private Camera camera;
         private Texture ballTexture;
         private Sprite ball;
         private Viewport viewport;


         private Vector3 point = new Vector3();

private World world;
private Box2DDebugRenderer box2DDebugRenderer;

private CircleShape circleShape;
private FixtureDef fixtureDef;
private BodyDef bodyDef;
private Body circleBody;

private static final float SCENE_WIDTH = 28;
private static final float SCENE_HEIGHT = 48f;


public LevelScreen() {
    super(new FitViewport(SCENE_WIDTH, SCENE_HEIGHT,  new OrthographicCamera(SCENE_WIDTH, SCENE_HEIGHT)));


    batch = getBatch();
    camera = getCamera();
    viewport = getViewport();

    world = new World(new Vector2(0,-9.8f), true);
    box2DDebugRenderer = new Box2DDebugRenderer();
    bodyDef = new BodyDef();
    bodyDef.type = BodyDef.BodyType.DynamicBody;
    bodyDef.position.set(10, 28);

    ballTexture = new Texture("ball.png");
    ball = new Sprite(ballTexture);
    ball.setPosition(0,0);

    circleShape = new CircleShape();
    circleShape.setRadius(1f);

    fixtureDef = new FixtureDef();
    fixtureDef.shape = circleShape;
    fixtureDef.density = 0.5f;
    fixtureDef.friction = 0.4f;
    fixtureDef.restitution = 0.6f;

    circleBody = world.createBody(bodyDef);
    circleBody.createFixture(fixtureDef);

    box2DDebugRenderer = new Box2DDebugRenderer(
            true, /* draw bodies */
            false, /* don't draw joints */
            true, /* draw aabbs */
            true, /* draw inactive bodies */
            false, /* don't draw velocities */
            true /* draw contacts */);

    Gdx.input.setInputProcessor(this);


}

@Override
public void show() {
    System.out.println("show");
}

@Override
public void render(float delta) {
    Gdx.gl.glClearColor(1, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    batch.setProjectionMatrix(camera.combined);

    batch.begin();
    ball.draw(batch);

    batch.end();

    world.step(1 / 60f, 6, 2);
    ball.setPosition(circleBody.getPosition().x - 25f, circleBody.getPosition().y - 25f);
    box2DDebugRenderer.render(world, viewport.getCamera().combined);

}

@Override
public void resize(int width, int height) {
    viewport.update(width, height);
    System.out.println("resize");
}

@Override
public void pause() {
    System.out.println("pause");
}

@Override
public void resume() {
    System.out.println("resume");
}

@Override
public void hide() {
    System.out.println("hide");
}

@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
    viewport.getCamera().unproject(point.set(screenX, screenY, 0));
    return false;
}
}
江飞白
2023-03-14

好吧,我似乎不能通过一个简单的评论让你理解。让我们按代码进行尝试:

屏幕

public class TestScreen implements Screen {
    SpriteBatch batch;
    OrthographicCamera camera;

    World world;
    Box2DDebugRenderer dr;

    Ball ball;


    public TestScreen() {
        batch = new SpriteBatch();
        camera = new OrthographicCamera(1.6f, 1f); // <---- Very small camera so it passes by fast since less surface is being shown

        world = new World(new Vector2(0, -9.8f), true);

        ball = new Ball(.11f, world); // <---- Create ball and pass in the diameter

        //Try playing with the value of camera let's say we have a ball the size of planet earth:
        //ball = new Ball(6371, world);

        //Now zoom out the screen so we can see our planet sized ball
        //camera = new OrthographicCamera(16000, 10000);

        //Believe me, our planet ball falls as fast as the little soccer ball.       //But since you zoomed out each pixel represents so much more distance.


        dr = new Box2DDebugRenderer(true, false, false, false, false, false);
    }

    @Override
    public void show() {

    }

    @Override
    public void render (float delta) {
        Gdx.gl.glClearColor(.1f, .1f, .14f, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        batch.setProjectionMatrix(camera.combined);

        world.step(Gdx.graphics.getDeltaTime(), 6, 2);

        batch.begin();
        ball.draw(batch);
        batch.end();

        dr.render(world, camera.combined);

    }
 //... Other mandatory screen methods
}

Ball.java

public class Ball {

    private float radius;

    private CircleShape shape;
    private FixtureDef fixtureDef;
    private BodyDef bodyDef;
    private Body circleBody;

    private Texture ballTexture;

    public Ball(float radius, World world) {
        this.radius = radius;

        ballTexture = new Texture("sprites/soccerball.png");

        bodyDef = new BodyDef();
        bodyDef.type = BodyDef.BodyType.DynamicBody;
        bodyDef.position.set(0, 0);

        shape = new CircleShape();
        shape.setRadius(radius);

        fixtureDef = new FixtureDef();
        fixtureDef.shape = shape;
        fixtureDef.density = 0.5f;
        fixtureDef.friction = 0.4f;
        fixtureDef.restitution = 0.6f;

        circleBody = world.createBody(bodyDef);
        circleBody.createFixture(fixtureDef);
    }

    public void draw(SpriteBatch batch)
    {
        batch.draw(ballTexture, circleBody.getPosition().x - radius, circleBody.getPosition().y - radius,
                radius * 2, radius * 2); // <---- draw the size you give it in the physics engine
    }
}

让我们从你做错了什么开始:

你给了世界9.8个单位的重力。这些不是像素,也不是距离,也不是任何东西。当你决定这些是米(代表地球上的引力)时,它们才是米,你应该保持这个比例。

接下来,制作一个半径为25米的球,并将摄像机缩小到1920米高的区域。在现实生活中,物体从2公里处掉落到地面需要一段时间。因此,由于你在现实世界中使用的是每秒9.8米的速度,因此在你的应用程序中启动也需要一些时间。

所以你要做的是缩小规模。足球的半径只有11cm,所以我创建了一个半径为0.11m的球。但你将无法看到,因为它将只是一个像素的一小部分与你的相机缩小到目前为止。因此,将相机放大(因为它是正交的,所以只需设置其视口尺寸)。

关于将球画成正确大小的后续问题,只需使用前面给出的半径即可。正如你所看到的,对于球来说,摄像机vp非常小,球也非常小。对于行星大小的例子,摄像机被放大了很远,行星的大小与我们自己的地球相当。然而我只是根据球的半径来画,一切都会好起来的。

希望你能理解,也许你必须停止想太多,因为这个概念很简单。

 类似资料:
  • 我正在开发适用于Android和Ios的应用程序。我需要禁用键盘缓存,并且只找到了在这种情况下没有用的本机解决方案。所以问题是有没有办法使用cordova或ionic为两个操作系统实现这一点? 离子: Ionic CLI:5.4.6 Ionic框架:@Ionic/angular 4.11.5@angular devkit/build angular:0.803.19@angular devkit/

  • 为了全面兼容和保持 Cocos Creator 2D 缓动系统的使用体验,在v1.1版本 Cocos Creator 3D 移植了所有的 Cocos Creator 2D 功能实现。 注:action已经被废弃了,请使用tween; 注:在v1.0.3版本开始将不再依赖tween.js,如果使用了tween.js的相关特性,请注意及时适配; 注:在v1.0.4版本开始,to和by的可选属性中增加了

  • 在普通模式中,您可以使用以下方式移动光标     k(上)   h(左)     l(右)   j(下)     您可以使用其它更有效率的方式移动光标 表 24.1.    向前 向后 单词 w b 单词,包括特殊符号 W B 单词词尾 e   单词词尾,包括特殊符号 E     行 0 $ 行首文字(不包括空格) ^     页 H L 页面中部 M 在其它模式中,您可以使用方向键移动光标,不过

  • 我是Twilio的新手,我需要一些关于特定场景的帮助。一段时间以来,我一直试图为这个问题找到解决办法,但一直未能如愿。 我想使用一个移动(a)的Twilio号码打电话给移动(B)的另一个用户。我想这样做的方式,其中呼叫是由Twilio号码发起的,而不是由(a)的电话号码发起的。 换句话说,(A)从移动台拨Twilio号码,Twilio依次拨(B)并将(B)与(A)连接。 我已经将(A)拨打的Twi

  • 介绍如何获取移动云的API密钥 如何获取移动云的 API 密钥? 登录移动云控制台,在所有产品中搜索“AK管理”,进入AccessKey管理页面。 在AccessKey管理页面创建密钥或查看已有密钥的Access key和Secret key。 管理移动云资源,需要云账号具备哪些权限 权限策略 策略说明 Admin 管理员角色

  • Blockly的主工作区可以使用三种不同的方法移动:滚动条,鼠标或鼠标滚轮。 移动设置由作为《Blockly配置》部分的对象定义 。下面是一个例子: var workspace = Blockly.inject('blocklyDiv', {move:{ scrollbars: true, drag: true, wheel: false}