我一直在尝试学习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的投影矩阵setProjectionMatrix
:
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
答案 0 :(得分:3)
想象一下,您有一台1200 x 800像素的设备。
现在您说您将在位置上分别有一个box2d矩形:100、100,尺寸:100,100
现在使用SpriteBatch(Box2dDebugRenderer)进行渲染时,您将看到一个1200 x 800单位大的世界。您必须尝试忘记以像素为单位思考。重要的是SpriteBatch始终绘制1200 x 800像素,但并不总是绘制1200 x 800像素,以后还会更多。
这就是您所看到的:
当我们现在使用相机时,我们会说只有600 x 400单位的世界。
我们创建一个尺寸为600 x 400 单位的相机!
camera = new OrthographicCamera(600, 400);
批次仍可绘制1200 x 800单位和1200 x 800像素
现在使用batch.setProjectionMatrix(camera.combined);
,为批处理分配一个矩阵以计算单位大小。有了这个矩阵,他就可以计算出要抽出1个单位的数量。
然后,SpriteBatch绘制600 x 400单位,但仍为1200 x 800像素。
然后您会看到:
因此,您可能会忘记以像素为单位思考,相机矩阵会为您进行从像素到单位的计算,而您可以专注于以单位进行思考。
接下来必须要以单位为单位进行思考的第二件事是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)
使用相机渲染事物时,应将精灵批次的投影矩阵设置为相机的组合视图。
世界与相机完全分开。世界既有正面的也有负面的坐标。相机是您对世界的看法,就像文字相机一样,它可以在太空中移动。当您移动游戏摄像机时,您只是在改变可以看到的世界的一部分。
所有物理学都是在相对于世界原点的像素级别上完成的(在您的情况下)。相机不会对其进行任何更改。