2014-09-28 2 views
3

При попытке запрограммировать игру с помощью Box2D у меня возникла проблема с Box2D. Я заполнил номера пикселей для длин текстур и спрайтов, чтобы создать вокруг него прямоугольник. Все было в нужном месте, но почему-то все шло очень медленно. Посмотрев в Интернете, я обнаружил, что если вы не конвертировали пиксели в метры, box2d мог бы обрабатывать фигуры как очень большие объекты. это казалось логичной причиной всего, что двигалось медленно.Libgdx Box2D для преобразования пикселов в метры?

Я нашел похожие вопросы на этом сайте, но ответы действительно не помогли. в большинстве случаев решение заключалось в том, чтобы сделать методы для преобразования чисел пикселей в счетчики с использованием коэффициента масштабирования. Я попробовал это, но все стало неуместным и имело неправильные размеры. это казалось логичным для меня, поскольку числа, которые изменились, но имели тот же смысл.

Мне было интересно, есть ли способ сделать пиксели меньше метров, поэтому все, что должно быть в одном месте с тем же (пиксельным) размером, но означает меньше метров. Если у вас есть другой путь, который вы думаете, может помочь, я whould также хотел бы услышать ..

Вот код, я использую для создания камеры перед

 width = Gdx.graphics.getWidth()/5; 
     height = Gdx.graphics.getHeight()/5; 

     camera = new OrthographicCamera(width, height); 
     camera.setToOrtho(false, 1628, 440); 
     camera.update(); 

Это метод я использую для создать объект:

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); 
} 

Чтобы создать элемент, в данном случае таблицы, я использую следующее:

Table = new Item(); 
    Table.Create(372f, 60f, 152f, 96f, 1.0f, 0.2f, 0.2f, world); 

спрайтов нарисованы по этому пункту, используя следующий метод:

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(); 
} 

Спрайты также имеют размеры в пикселях.

Используя эти методы, он отображает изображения в нужных местах, но все движется медленно. Мне было интересно, как или если мне нужно изменить это, чтобы объекты двигались правильно и/или меньше. Заранее спасибо.

ответ

7

Box2D полностью независим от используемой графической библиотеки. В нем нет понятия спрайтов и текстур. То, что вы читаете в Интернете, правильно, вам придется конвертировать пиксели в метры, так как Box2D работает с метрами (стандартная единица для расстояния).

Например, если вы нарисовали спрайт размером 100x100 пикселей, это размер спрайта, который вы хотите видеть на экране. В реальном мире размер объекта должен быть в метрах, а не в пикселях, поэтому, если вы скажете 1px = 1m, тогда это сопоставит спрайт с гигантским объектом 100x100 метров. В Box2D крупные объекты мира замедляют вычисления. Итак, вам нужно отобразить 100 пикселей на меньшее количество метров, скажем, 1 метр, поэтому спрайт 100x100px будет представлен в мире Box2D объектом 1x1 метр.

Box2D не работает хорошо с очень маленькими числами и очень большими числами. Поэтому держите его между ними, скажем, от 0,5 до 100, чтобы иметь хорошую производительность.

EDIT: Ok. Теперь я задаюсь вопросом. Не кодируйте пиксели. Это так просто. Я знаю, что потребуется некоторое время, чтобы понять это (это потребовалось для меня). Но как только вы получите это, прямо вперед. Вместо пикселей используйте устройство, скажем, вы называете его метром. Итак, мы решили, что наш видовое окно должно быть указано 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(); 
} 

После того, как вы знаете, фактическую ширину и высоту, вызовите следующую функцию для того, чтобы сохранить пропорции:

public void resize(int width, int height) { 
     camera.viewportHeight = (Constants.VIEWPORT_WIDTH/width) * height; 
     camera.update(); 
} 

resize() можно назвать в любое время изменить ваш размер экрана (например: при изменении ориентации экрана). resize() принимает фактическую ширину и высоту (320x480 и т. Д.), Что является значением пикселя.

Теперь вы указываете размеры спрайта, их позиции и т. Д. В этом новом мире размером 6x5. Вы можете забыть пиксели. Минимальный размер спрайта, который заполнит экран, будет 6x5.

Теперь вы можете использовать тот же блок с Box2D. Поскольку новые размеры будут меньше, это не будет проблемой для Box2D. Если я правильно помню, Box2D не имеет какой-либо единицы. Мы просто называем это метром для удобства.

Теперь вы можете спросить, где указаны размеры окна. Это зависит от платформы. Следующий код показывает, 320х480 оконные настольные игры в:

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); 
    } 
} 

Нашей камера автоматически отображать 6х5 видовой экран для 480x320.

+0

Спасибо, поэтому, если я захочу сделать это, как мне нужно отображать пиксели на другое количество метров, как мне это сделать? (Я включил кодирование, используемое для создания элемента, и нарисовал спрайт на нем в вопросе). – dragonfly

+0

отредактировал мой ответ. – sinu

+0

Спасибо, я уже нашел способ сделать его правильным, но мне пришлось преобразовать расположение спрайтов на весь экран, чтобы все выглядело в нужном месте, но фактическое симуляция была в нижнем левый угол. Это, кажется, лучшая идея, хотя – dragonfly