Как создать экран загрузки в 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-секундная задержка, которая рисует экран, и я могу приступить к выполнению действия в действии.