Box2D无法理解它的工作方式-libgdx

Box2D无法理解它的工作方式-libgdx,libgdx,box2d,meter,Libgdx,Box2d,Meter,我试图在libgdx中使用Box2D,但不幸的是,我似乎无法理解它的工作方式 下面是几个让我发疯的例子: .1。众所周知,Box2D与仪表一起工作。每个人都知道这一点。那么,我为什么要按像素计算结果呢?例如,如果我定义了一些实体定义,并将位置设置为0,1,它将在屏幕的左下角绘制相关的装置/精灵!我认为Box2D中的0,0点位于屏幕的中心 .2。我一直在努力理解和解决的另一个问题是形状、关节和其他东西的价值。让我们从形状开始:我定义了一个多边形形状,如下所示: shape.setAsBox(1,

我试图在libgdx中使用Box2D,但不幸的是,我似乎无法理解它的工作方式

下面是几个让我发疯的例子:

.1。众所周知,Box2D与仪表一起工作。每个人都知道这一点。那么,我为什么要按像素计算结果呢?例如,如果我定义了一些实体定义,并将位置设置为0,1,它将在屏幕的左下角绘制相关的装置/精灵!我认为Box2D中的0,0点位于屏幕的中心

.2。我一直在努力理解和解决的另一个问题是形状、关节和其他东西的价值。让我们从形状开始:我定义了一个多边形形状,如下所示:

shape.setAsBox(1, 2);
现在形状应该是2米宽4米高,但事实并非如此。我得到的是一个超小的形状

最后,关节的值。我定义了一个具有多边形形状和地面实体的实体。现在我用旋转关节将这两个固定在地面主体的中心,目的是创造一个在一定范围内旋转良好的弹射器

现在我还定义了一个鼠标关节,这样我就可以很好地来回拖动弹射器多边形形状,但似乎我需要将关节的最大力设置为一个巨大的值,这样我才能真正看到弹射器的移动/旋转!我不明白。所有这一切都应该由小的价值观来运作,而不是我必须设定的价值观

下面是我的基本代码,其中包含上述所有内容。请告诉我我做错了什么,我吓坏了:

GameScreen.java

package com.david.box2dpractice;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
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.ChainShape;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.physics.box2d.joints.RevoluteJointDef;
import com.badlogic.gdx.utils.Array;

public class GameScreen implements Screen{

    private Box2DDebugRenderer debugRenderer;
    private Texture texture;
    private Sprite sprite;
    private Sprite tempSprite;
    private SpriteBatch batch;
    private Body arm , ground;
    private World world;
    public OrthographicCamera camera;
    private RevoluteJointDef jointDef;
    private Array<Body> tempBodies;

    public GameScreen() {
        debugRenderer = new Box2DDebugRenderer();
        batch = new SpriteBatch();
        texture = new Texture(Gdx.files.internal("catapult_arm.png"));
        camera = new OrthographicCamera();
        camera.setToOrtho(false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        tempBodies = new Array<Body>();
    }
    @Override
    public void render(float delta) {
        // TODO Auto-generated method stub
        Gdx.gl.glClearColor(0, 0, 0, 0);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        batch.setProjectionMatrix(camera.combined);
        world.getBodies(tempBodies);
        batch.begin();
        for(Body body : tempBodies) {
            if(body.getUserData() != null && body.getUserData() instanceof Sprite) {
                tempSprite = (Sprite) body.getUserData();
                tempSprite.setPosition(body.getPosition().x-tempSprite.getWidth()/2, body.getPosition().y-tempSprite.getHeight()/2);
                tempSprite.setRotation((float) Math.toDegrees(body.getAngle()));
                tempSprite.draw(batch);
            }
        }
        batch.end();
        debugRenderer.render(world, camera.combined);
        world.step(1/60f, 6, 2);
    }

    @Override
    public void resize(int width, int height) {
        // TODO Auto-generated method stub
        Gdx.app.log("System", "resize() was invoked");
    }

    @Override
    public void show() {
        // TODO Auto-generated method stub
        Gdx.app.log("System", "show() was invoked");
        world = new World(new Vector2(0,0), true);
        sprite = new Sprite(texture);
        BodyDef bodyDef = new BodyDef();
        bodyDef.position.set(Gdx.graphics.getWidth()/2,Gdx.graphics.getHeight()/2+sprite.getHeight()/2);
        bodyDef.type = BodyType.DynamicBody;

        // The shape
        PolygonShape shape = new PolygonShape();
        shape.setAsBox(11, 91);

        // The fixture
        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = shape;
        fixtureDef.density = .10f;
        arm = world.createBody(bodyDef);
        arm.createFixture(fixtureDef);
        sprite.setOrigin(sprite.getWidth()/2, sprite.getHeight()/2);
        arm.setUserData(sprite);
        shape.dispose();

        bodyDef = new BodyDef();
        bodyDef.position.set(Gdx.graphics.getWidth()/2,Gdx.graphics.getHeight()/2);
        bodyDef.type = BodyType.StaticBody;

        ChainShape shape2 = new ChainShape();
        shape2.createChain(new Vector2[] {new Vector2(-20*Pixels_To_Meters,0),new Vector2(20*Pixels_To_Meters,0)});

        // The fixture
        fixtureDef.shape = shape2;
        fixtureDef.restitution = .65f;
        fixtureDef.friction = .75f;
        ground = world.createBody(bodyDef);
        ground.createFixture(fixtureDef);
        shape2.dispose();
        // joint
        jointDef = new RevoluteJointDef();
        jointDef.bodyA = arm;
        jointDef.bodyB = ground;
        jointDef.localAnchorB.set(ground.getLocalCenter());
        jointDef.localAnchorA.set(arm.getLocalCenter().x,arm.getLocalCenter().y-sprite.getHeight()/2);
        jointDef.enableLimit = true;
        jointDef.enableMotor = true;
        jointDef.motorSpeed = 15;
        jointDef.lowerAngle = (float) -Math.toRadians(75);
        jointDef.upperAngle = (float) -Math.toRadians(9);
        jointDef.maxMotorTorque = 4800;
        world.createJoint(jointDef);
        Gdx.input.setInputProcessor(new InputHandler(arm,ground,world,camera));
    }

    @Override
    public void hide() {
        // TODO Auto-generated method stub
        Gdx.app.log("System", "hide() was invoked");
        dispose();
    }

    @Override
    public void pause() {
        // TODO Auto-generated method stub
        Gdx.app.log("System", "pause() was invoked");
    }

    @Override
    public void resume() {
        // TODO Auto-generated method stub
        Gdx.app.log("System", "resume() was invoked");
    }

    @Override
    public void dispose() {
        // TODO Auto-generated method stub
        Gdx.app.log("System", "dispose() was invoked");
        texture.dispose();
        batch.dispose();
        world.dispose();
    }
}

如果你能帮我,我真的很感激你。谢谢

Box2D只是物理引擎,逻辑部分。它对视图没有任何作用,因此将米转换为像素是您的工作。 在Libgdx中,这可以通过使用相机来完成。 您已经准备好使用摄影机,但您给它的视口大小错误。 你告诉相机和游戏Gdx.graphics.getWidth、Gdx.graphics.getHeight一样大,你应该考虑你想在屏幕上显示多少米。 如果要显示宽度为80米,高度为45米的16/9,则需要按如下方式设置相机:

 camera = new OrthographicCamera();
 camera.setToOrtho(false, 80, 45);
因此,如果你的游戏分辨率为1600*900像素,每米将被转换为20像素。相机会为你做这件事,如果你使用的分辨率为800*450,每米将被转换为10像素

也不是Box 2DS P0/0不在屏幕中部,在屏幕上无处。它是在BOX2D世界的P0/0,它是你的工作,绘制它在中间或底部或你想要的任何地方。 同样,这是通过摄像机完成的。默认情况下,相机P0/0位于屏幕中部,但你可以移动相机,这样它就可以无处不在。p> 现在应该很清楚,您创建的形状不是超小的,只是没有放大。如果你从几百米远的地方看,一辆3米长的汽车似乎很小。如果你站在离它1米远的地方,你几乎无法一次看到整个汽车,因为它比你的视口大。 我不确定关节/力,但如果你用相机放大,你的问题可能会解决。但我也可能是错的,因为我从来没有用过box2D

一些教程:

这是一个FPR C++教程。但是通过阅读解释,您应该理解它,并且能够在java/libgdx中实现它。 ,本教程向您展示如何使用box2D和libgdx创建游戏。通过理解如何将box2D与Libgdx连接起来,它真的很有帮助。
Box2D只是物理引擎,逻辑部分。它对视图没有任何作用,因此将米转换为像素是您的工作。 在Libgdx中,这可以通过使用相机来完成。 您已经准备好使用摄影机,但您给它的视口大小错误。 你告诉相机和游戏Gdx.graphics.getWidth、Gdx.graphics.getHeight一样大,你应该考虑你想在屏幕上显示多少米。 如果要显示宽度为80米,高度为45米的16/9,则需要按如下方式设置相机:

 camera = new OrthographicCamera();
 camera.setToOrtho(false, 80, 45);
因此,如果你的游戏分辨率为1600*900像素,每米将被转换为20像素。相机会为你做这件事,如果你使用的分辨率为800*450,每米将被转换为10像素

也不是Box 2DS P0/0不在屏幕中部,在屏幕上无处。它是在BOX2D世界的P0/0,它是你的工作,绘制它在中间或底部或你想要的任何地方。 同样,这是通过摄像机完成的。默认情况下,相机P0/0位于屏幕中部,但你可以移动相机,这样它就可以无处不在。p> 现在应该很清楚,您创建的形状不是超小的,只是没有放大。如果你从几百米远的地方看,一辆3米长的汽车似乎很小。如果你站在离它1米远的地方,你几乎是乌纳 您可以一次看到整个汽车,因为它比您的视口大。 我不确定关节/力,但如果你用相机放大,你的问题可能会解决。但我也可能是错的,因为我从来没有用过box2D

一些教程:

这是一个FPR C++教程。但是通过阅读解释,您应该理解它,并且能够在java/libgdx中实现它。 ,本教程向您展示如何使用box2D和libgdx创建游戏。通过理解如何将box2D与Libgdx连接起来,它真的很有帮助。
非常有用的评论。你给了我一些有趣的见解。@DavidLasry我很长时间以来一直在考虑使用box2d,因此我阅读了很多教程。然而,我从来没有真正尝试过:P我编辑我的答案,并给你一些伟大的教程链接!非常有用的评论。你给了我一些有趣的见解。@DavidLasry我很长时间以来一直在考虑使用box2d,因此我阅读了很多教程。然而,我从来没有真正尝试过:P我编辑我的答案,并给你一些伟大的教程链接!