問題描述
在嘗試使用 Box2D 編寫游戲時,我遇到了 Box2D 的問題.我為紋理和精靈的長度填充了像素數,以在其周圍創建一個框.一切都在正確的地方,但出于某種原因,一切都進展得很慢.通過查看互聯網,我發現如果您不將像素轉換為米,box2d 可能會將形狀處理為非常大的對象.這似乎是一切進展緩慢的合乎邏輯的原因.
When trying to program a game using Box2D, I ran into a problem with Box2D. I filled in pixel numbers for the lengths of the the textures and sprites to create a box around it. Everything was at the right place, but for some reason everything went very slowly. By looking on the internet I found out that if you didn't convert pixels to meters box2d might handle shapes as very large objects. this seemed to be a logical cause of everything moving slowly.
我在這個網站上發現了類似的問題,但答案似乎并沒有幫助.在大多數情況下,解決方案是制定使用比例因子將像素數轉換為米的方法.我試過了,但是所有東西都放錯了位置并且尺寸不對.這對我來說似乎是合乎邏輯的,因為數字發生了變化但具有相同的含義.
I found similar questions on this site, but the answers didn't really seem to help out. in most of the cases the solution was to make methods to convert the pixel numbers to meters using a scaling factor. I tried this out, but everything got misplaced and had wrong sizes. this seemed logical to me since the numbers where changed but had the same meaning.
我想知道是否有辦法使像素意味著更少的米,所以所有東西都應該在同一個地方以相同的(像素)大小,但意味著更少的米.如果您有其他您認為可能會有所幫助的方式,我也很想聽聽.
I was wondering if there is a way to make the pixels mean less meters, so everything whould be at the same place with the same (pixel) size, but mean less meters. If you have a different way which you think might help, I whould also like to hear it..
這是我用來創建相機的代碼
Here is the code i use to create the camera
width = Gdx.graphics.getWidth() / 5;
height = Gdx.graphics.getHeight() / 5;
camera = new OrthographicCamera(width, height);
camera.setToOrtho(false, 1628, 440);
camera.update();
這是我用來創建對象的方法:
This is the method I use to create an object:
public void Create(float X, float Y, float Width, float Height, float density, float friction, float restitution, World world){
//Method to create an item
width = Width;
height = Height;
polygonDef = new BodyDef();
polygonDef.type = BodyType.DynamicBody;
polygonDef.position.set(X + (Width / 2f), Y + (Height / 2f));
polygonBody = world.createBody(polygonDef);
polygonShape = new PolygonShape();
polygonShape.setAsBox(Width / 2f, Height / 2f);
polygonFixture = new FixtureDef();
polygonFixture.shape = polygonShape;
polygonFixture.density = density;
polygonFixture.friction = friction;
polygonFixture.restitution = restitution;
polygonBody.createFixture(polygonFixture);
}
要創建一個項目,在本例中是一個表格,我使用以下內容:
To create an item, in this case a table, I use the following:
Table = new Item();
Table.Create(372f, 60f, 152f, 96f, 1.0f, 0.2f, 0.2f, world);
使用以下方法在項目上繪制 Sprite:
The Sprites are drawn on the item by using the following method:
public void drawSprite(Sprite sprite){
polygonBody.setUserData(sprite);
Utils.batch.begin();
if(polygonBody.getUserData() instanceof Sprite){
Sprite Sprite = (Sprite) polygonBody.getUserData();
Sprite.setPosition(polygonBody.getPosition().x - Sprite.getWidth() / 2, polygonBody.getPosition().y - Sprite.getHeight() / 2);
Sprite.setRotation(polygonBody.getAngle() * MathUtils.radiansToDegrees);
Sprite.draw(Utils.batch);
}
Utils.batch.end();
}
精靈也有像素大小.
使用這種方法,它會在正確的位置顯示圖像,但一切都移動得很慢.我想知道如何或是否必須更改它以使對象正確移動和/或減少.提前致謝.
推薦答案
Box2D 完全獨立于您使用的圖形庫.它沒有任何精靈和紋理的概念.您在線閱讀的內容是正確的,您必須將像素轉換為米,因為 Box2D 使用米(距離的標準單位).
Box2D is an entirely independent of the graphics library that you use. It doesn't have any notion of sprites and textures. What you read online is correct, you'll have to convert pixels to metres, as Box2D works with metres(the standard unit for distance).
例如,如果您繪制了一個大小為 100x100 像素的精靈,那么這就是您希望用戶在屏幕上看到的精靈的大小.在現實世界中,對象的大小應該以米為單位,而不是以像素為單位——所以如果你說 1px = 1m,那么這會將精靈映射到一個巨大的 100x100 米對象.在 Box2D 中,大型世界對象會減慢計算速度.因此,您需要做的是將 100 像素映射到較小的米數,例如 1 米 - 因此 100x100px 的精靈將在 Box2D 世界中由 1x1 米對象表示.
For example, if you drew a sprite of size 100x100 pixels, that's the size of the sprite that you want the user to see on the screen. In real world the size of the object should be in metres and not in pixels - so if you say 1px = 1m, then that'll map the sprite to a gigantic 100x100 meter object. In Box2D, large world objects will slow down calculations. So what you need to do is map the 100 pixels to a smaller number of meters, say, 1 meter - thus 100x100px sprite will be represented in Box2D world by a 1x1 meter object.
Box2D 不適用于非常小的數字和非常大的數字.因此,請將其保持在 0.5 到 100 之間,以獲得良好的性能.
Box2D doesn't work well with very small numbers and very large numbers. So keep it in between, say between 0.5 and 100, to have good performance.
行.現在我明白你的問題了.不要編碼到像素.就這么簡單.我知道這需要一些時間才能理解(這對我來說).但是一旦你掌握了它的竅門,它就直截了當.而不是像素,使用一個單位,比如說,你稱之為米.所以我們決定我們的視口應該是 6mx5m.
Ok. Now I get your question. Don't code to pixels. Its as simple as that. I know it'll take some time to understand this(it took for me). But once you get the hang of it, its straight forward. Instead of pixels, use a unit, say, you call it meter. So we decide our viewport should be say 6mx5m.
所以初始化是
Constants.VIEWPORT_WIDTH = 6;
Constants.VIEWPORT_HEIGHT = 5;
...
void init() {
camera = new OrthographicCamera(Constants.VIEWPORT_WIDTH, Constants.VIEWPORT_HEIGHT);
camera.position.set(Constants.VIEWPORT_WIDTH/2, Constants.VIEWPORT_HEIGHT/2, 0);
camera.update();
}
一旦知道了實際的寬度和高度,就可以調用以下函數來保持縱橫比:
Once you know the actual width and height, you call the following function in order to maintain aspect ratio:
public void resize(int width, int height) {
camera.viewportHeight = (Constants.VIEWPORT_WIDTH / width) * height;
camera.update();
}
resize()
可以在您更改屏幕大小的任何時候調用(例如:當您更改屏幕方向時).resize()
取實際的寬度和高度(320x480 等),即像素值.
resize()
can be called anytime you change your screen size(eg: when you screen orientation changes). resize()
takes the actual width and height (320x480 etc), which is the pixel value.
現在您可以在這個 6x5 大小的新世界中指定精靈的大小、位置等.你可以忘記像素.填充屏幕的精靈的最小尺寸為 6x5.
Now you specify you sprite sizes, their positions etc. in this new world of size 6x5. You can forget pixels. The minimum size of the sprite that'll fill the screen will be 6x5.
您現在可以使用與 Box2D 相同的單位.由于新的尺寸會更小,這對 Box2D 來說不是問題.如果我沒記錯的話,Box2D 沒有任何單位.為方便起見,我們將其稱為儀表.
You can now use the same unit with Box2D. Since the new dimensions will be smaller, it won't be a problem for Box2D. If I remember correctly Box2D doesn't have any unit. We just call it meter for convenience sake.
現在您可能會問在哪里指定窗口的尺寸.這取決于平臺.以下代碼顯示了一個 320x480 窗口桌面游戲:
Now you might ask where you specify the dimensions of the window. It depends on the platform. Following code shows a 320x480 windowed desktop game:
public class Main {
public static void main(String[] args) {
LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();
cfg.title = "my-game";
cfg.useGL20 = false;
cfg.width = 480;
cfg.height = 320;
new LwjglApplication(new MyGame(), cfg);
}
}
我們的相機會智能地將 6x5 視口映射到 480x320.
Our camera will intelligently map the 6x5 viewport to 480x320.
這篇關于Libgdx Box2D 像素到米的轉換?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!