Как создать экран загрузки в libgdx?

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

Поэтому мне нужно показать/отобразить еще один класс Screen под названием LoadingScreen, чтобы потратить некоторое время и одновременно прочитать мои файлы и выполнить инициализацию процесса для моего GameScreen, а после инициализации завершено изменение экрана, вызвав setScreen(gameScreen).

Мне нужно использовать поток для выполнения этой параллельной работы, теперь проблема в том, что если я использую поток для чтения файлов и инициализации; При переключении на GameScreen openGl дает мне эту ошибку:

javax.media.opengl.GLException: Error: no OpenGL buffer object appears to be bound to target 0x8892
at com.sun.opengl.impl.GLBufferSizeTracker.setBufferSize(GLBufferSizeTracker.java:118)

Мне известно, что оба потока не используют графические ресурсы одновременно.

Я обнаружил, что проблема возникает с помощью Mesh es. Инициализация Mesh в потоке инициализации и рендеринг в основном потоке вызывает эту ошибку. Но я не знаю, как его решить.

Есть ли у вас идеи решить эту проблему?

Ответ 1

Как указано в комментариях, AssetManager - это способ загрузки большинства ресурсов libGDX (аудио, текстуры и т.д.) асинхронно, показывая всплеск или экран загрузки.

Для других операций должно быть достаточно выполнения их в фоновом потоке (или с использованием одного из других компонентов выполнения фоновых задач Android или Java). Чтобы вызвать подпрограммы libGDX, такие как setScreen или другие, которые должны быть выполнены в потоке рендеринга libGDX, используйте Gdx.app.postRunnable, например:

Gdx.app.postRunnable(new Runnable() {
     @Override
     public void run() {
         // Do something on the main thread
         myGame.setScreen(postSplashGameScreen);
     }
  });

В зависимости от видимости myGame и postSplashGameScreen может быть проще создать Runnable в другом контексте, а затем передать его в фоновый поток, который будет опубликован после его завершения.

Ответ 2

Мой рабочий процесс использует действия в моем методе экрана загрузки:

@Override
public void show() {
    stage.addAction(Actions.sequence(Actions.delay(0.5f), action_loading_assets_and_other_stuff, Actions.delay(0.5f), action_setScreen));
}

Actions.delay(0.5f) делает волшебную игру незамерзающей

Ответ 3

Задержка действия сделала это и для меня. Я просто устанавливаю реакцию задержки с 0.2f и выполняемое действие на этапе в методе show() экрана загрузки. Теперь метод рендеринга экранов загрузки называется несколько раз, в то время как 0,2-секундная задержка, которая рисует экран, и я могу приступить к выполнению действия в действии.