Libgdx的世界单位

时间:2018-08-23 20:09:19

标签: java libgdx

我一直在尝试学习libgdx,但是现在我对那里的世界单位有些困惑,我什至不知道我应该问什么确切的问题。

无论如何,我一直在阅读此示例游戏代码here 据我了解,SpriteBatch会在没有相机的情况下渲染与设备分辨率有关的所有内容,因此会渲染像素,但是当我们制作相机时,将其设置为“大小”,位置,然后使用batch.setProjectionMatrix(camera.combined),批处理将像素转换为单位,然后知道要渲染的位置,但是在此游戏中,Rectangle个对象之间以及当您使用Rectangle设置此rect.set(x, y, 1, 1);的位置时存在碰撞检测,其中{ {1}}和x是世界单位而不是像素,如果没有像{{ 1}},让我们知道现在我们是在以单位而不是像素为单位工作,然后在末尾有这个y,是否也以单位为单位?如果是这样,那么Rectangle如何知道这些单位应该多大(例如游戏中的比例为1/16)x

我什至不知道这个问题是否真的有意义,但这就是我的意思,我真的在这里迷路了

编辑:好的,我知道单元现在是如何工作的,但是碰撞仍然使我有些困惑,在下面的示例中,我创建了这个

y

一切都很好,设置了ShapeRenderer的投影矩阵setProjectionMatrixenter image description here

之后,1, 1);圆应该位于

但是,我仍然不了解如何检查该圆上的碰撞,当我在render方法中执行此操作并按圆时,什么也没发生,就像我没有得到该日志,我认为那是因为圆不知道世界比例(没有renderer = new OrthogonalTiledMapRenderer(map, 1 / 16f);.这样的东西)并渲染坐标,而​​实际圆“认为”它的位置不匹配。如何检查该圆上的碰撞?

// onCreate
    mapSprite = new Sprite(new Texture(Gdx.files.internal("space.png")));
            planetTexture = new Texture(Gdx.files.internal("planet.png"));
            shapeRenderer = new ShapeRenderer();


           //Planet(X,Y,Radius)
        planet = new Planet(20, 30, 7);
        planet2 = new Planet(70, 50, 8);
        circle = new Circle(planet.getPosition().x + planet.radius, planet.getPosition().y + planet.radius, planet.radius);
        circle2 = new Circle(planet2.getPosition().x + planet2.radius, planet2.getPosition().y + planet2.radius, planet2.radius);


        mapSprite.setPosition(0,0);
        mapSprite.setSize(133, 100);

        stateTime = 0;

        camera = new OrthographicCamera();
        camera.setToOrtho(false, 133, 100);

        camera.position.set(133 /2, 100 /2, 0);
        camera.update();

        batch = new SpriteBatch();
...
// Render Method

batch.setProjectionMatrix(camera.combined);
        batch.begin();
        mapSprite.draw(batch);
        batch.draw(planetTexture, planet.getPosition().x, planet.getPosition().y, planet.radius * 2, planet.radius * 2);
        batch.draw(planetTexture, planet2.getPosition().x, planet2.getPosition().y, planet2.radius * 2, planet2.radius * 2);

        batch.end();

        shapeRenderer.setProjectionMatrix(camera.combined);
        shapeRenderer.setColor(Color.RED);
        shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);

        shapeRenderer.circle(circle.x, circle.y, circle.radius + 1);
        shapeRenderer.end();

EDIT2:我现在明白了,一切正常,只是我没有在触摸坐标上使用ShapeRenderer

2 个答案:

答案 0 :(得分:3)

想象一下,您有一台1200 x 800像素的设备。

现在您说您将在位置上分别有一个box2d矩形:100、100,尺寸:100,100

现在使用SpriteBatch(Box2dDebugRenderer)进行渲染时,您将看到一个1200 x 800单位大的世界。您必须尝试忘记以像素为单位思考。重要的是SpriteBatch始终绘制1200 x 800像素,但并不总是绘制1200 x 800像素,以后还会更多。

这就是您所看到的:

enter image description here

当我们现在使用相机时,我们会说只有600 x 400单位的世界。
我们创建一个尺寸为600 x 400 单位的相机!

camera = new OrthographicCamera(600, 400);

enter image description here

批次仍可绘制1200 x 800单位和1200 x 800像素

现在使用batch.setProjectionMatrix(camera.combined);,为批处理分配一个矩阵以计算单位大小。有了这个矩阵,他就可以计算出要抽出1个单位的数量。
然后,SpriteBatch绘制600 x 400单位,但仍为1200 x 800像素。
然后您会看到:

enter image description here

因此,您可能会忘记以像素为单位思考,相机矩阵会为您进行从像素到单位的计算,而您可以专注于以单位进行思考。

接下来必须要以单位为单位进行思考的第二件事是box2D以米为单位进行计算。因此,矩形的尺寸为100 x 100米,底部上方100米。因此,根据g = 9,81m / s的重力,矩形的下落速度并没有您预期的那么快。

SpriteBatch始终绘制1200 x 800像素,否则您只会在屏幕的一半看到游戏。但是使用摄像机矩阵,批次可以知道他必须绘制1个像素的像素数,因此您可以在1200 x 800像素的屏幕上看到600 x 400单位的世界。

注意:1个单位并不总是等于1米。例如,在太空飞船游戏中,两艘船之间有5公里。因此,请不要创建10000 x 10000单位的世界,因为Box2d不会计算该世界。
然后,您可以说1个单位= 100米,因此您的世界为100 x 100个单位。 现在,您必须记住,当船舶的速度应达到200 m / s时,必须设置body.setLinearVelocity(2,0),因为1个单位= 100米。

所以请始终以单位为单位!

编辑:
有时我们不会绕过像素,例如Gdx.input
Gdx.input返回像素位置。
现在,我们的相机有两种方法可以将像素的pos转换为单位的pos,反之亦然。

float x = Gdx.input.getX();
float y = Gdx.input.getY();
camera.unproject(new Vector3(x, y, 0));//this converts a Vector3 position of pixels to a Vector3 position of units
camera.project(new Vector3(10,10,0));//this converts a Vector3 position of units to a Vector3 position of pixels

希望我能帮助您

答案 1 :(得分:0)

使用相机渲染事物时,应将精灵批次的投影矩阵设置为相机的组合视图。

世界与相机完全分开。世界既有正面的也有负面的坐标。相机是您对世界的看法,就像文字相机一样,它可以在太空中移动。当您移动游戏摄像机时,您只是在改变可以看到的世界的一部分。

所有物理学都是在相对于世界原点的像素级别上完成的(在您的情况下)。相机不会对其进行任何更改。