Джиттер эффекта параллакса в libGDX - PullRequest
0 голосов
/ 23 января 2020

В основном я использую этот класс ParallaxCamera , чтобы создать эффект в моей игре, но при движении слои "покачиваются". Это особенно заметно, когда камера движется медленно.

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

Я думаю, что проблемы могут быть следующими:

  • слои движутся с разной скоростью, что означает, что они движутся в разное время

  • округление для отображения заставляет слои принимать несколько разные позиции в каждом кадре при перемещении камеры

Спасибо за любую помощь

1 Ответ

0 голосов
/ 28 января 2020

Для пиксельной графики с низким разрешением я использовал эту стратегию. Я рисую в небольшой FrameBuffer с разрешением 1: 1, а затем рисую это на экране. Это должно позаботиться о дрожании.

Если ваша Стадия также с тем же разрешением, то вы должны использовать немного хака, чтобы правильно обрабатывать ввод. Тот, который я использовал, чтобы использовать StretchViewport, но я вручную вычисляю ширину и высоту мира, чтобы не растягивать мир, поэтому я в основном выполняю те же вычисления, что и ExtendViewport за кулисами. Вы также должны округлить до целого числа для ширины и высоты. Вы должны сделать это в resize и применить ширину и высоту, используя viewport.setWorldWidth() и setWorldHeight(). Так что в этом случае не имеет значения, какой размер мира вы дадите конструктору, так как он будет изменен в update().

Когда вы вызываете update в окне просмотра в resize, вам нужно сделайте это в контексте FrameBuffer, к которому вы рисуете. В противном случае он испортит размеры буфера кадров экрана.

public void resize(int width, int height) {

    int worldWidth = Math.round((float)WORLD_HEIGHT / (float)height * (float)width);
    viewport.setWorldWidth(worldWidth);
    viewport.setWorldHeight(worldHeight);
    frameBuffer.begin();
    viewport.update(width, height, true); // the actual screen dimensions
    frameBuffer.end();

}

Вы можете посмотреть примеры использования FrameBuffer в LibGDX. Вы должны сделать все свои игровые рисунки в промежутке между frameBuffer.begin() и end(), а затем вывести буфер цвета frameBuffer на экран следующим образом:

stage.act();
frameBuffer.begin();
//Draw game
stage.draw();
frameBuffer.end();
spriteBatch.setProjectionMatrix(spriteBatch.getProjectionMatrix().idt());
spriteBatch.begin();
spriteBatch.draw(frameBuffer.getColorBufferTexture(), -1, 1, 2, -2);
spriteBatch.end();

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

...