Как сохранить состояние действия, которое имеет GLSurfaceView - PullRequest
4 голосов
/ 24 мая 2010

Моя проблема в том, что наша игра может мгновенно переключаться в режим меню и настройки, но для загрузки текстуры потребуется 4-6 секунд, режим рендеринга init GL, в конце концов, я просто использовал 6 простых текстур для создания 6 спрайтов в игре.

Пожалуйста, помогите мне ответить на два вопроса: 1. Как я могу предварительно загрузить наши активы в Android OS, чтобы быстрее начать нашу игру? 2. Чтобы использовать трюк для создания экземпляра переключения между действиями, как я могу сохранить свою активность с состоянием GLSurfaceView?

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

Игра использует 3 вида деятельности, как вы можете видеть в следующей конфигурации:

 <application android:label="@string/app_name"
  android:icon="@drawable/icon" android:allowBackup="true">
  <activity android:name=".Menu" android:screenOrientation="portrait" 
  android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
  android:launchMode="singleTop">
   <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
   </intent-filter>

  </activity>
  <activity android:name=".ReTouch" android:screenOrientation="portrait" />

  <activity android:name=".Preference" android:screenOrientation="portrait" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />

 </application>

Мой класс .ReTouch - это класс, который расширен от RokonActivity (я использую движок rokon для своей игры), этот движок создаст GLSurefaceView для рендеринга моей игры в OpenGL ES. Вы можете получить исходный код RokonAcitivity здесь: http://code.google.com/p/rokon/source/browse/tags/release/1.1.1/src/com/stickycoding/Rokon/RokonActivity.java

 public class ReTouch extends RokonActivity {
 public static final int REPLAY_DELAY_INTERVAL = 1000;
 private ReTouchGameBoard reTouchGame;

и .Menu, .Preference - два нормальных стандартных действия в приложении для Android.

Я использую этот метод для запуска и переключения между действиями:

  playButton.setOnClickListener(new OnClickListener() {

   public void onClick(View v) {
    soundPool.play(soundId, 1, 1, 1, 0, 1);
    startActivity(new Intent(Menu.this, ReTouch.class));
   }
  });
  settingButton.setOnClickListener(new OnClickListener() {

   public void onClick(View v) {
    soundPool.play(soundId, 1, 1, 1, 0, 1);
    startActivity(new Intent(Menu.this, Preference.class));
   }
  });
  quitButton.setOnClickListener(new OnClickListener() {

   public void onClick(View v) {
    soundPool.play(soundId, 1, 1, 1, 0, 1);
    finish();
   }
  });

1 Ответ

1 голос
/ 22 ноября 2011

Я избежал этой проблемы, а не решил ее для своей игры:

Я использую «FrameLayout» в качестве основного макета, с «GLSurfaceView» в качестве первого макета внутри (т. Е. В нижней части стека), следующей группой представления «menu» и непрозрачной верхней части экрана «loading» из этого (установите на match_parent, чтобы заполнить экран):

<FrameLayout 
    android:id="@+id/graphics_frameLayout1" 
    android:layout_width="fill_parent" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_height="fill_parent">
    <android.opengl.GLSurfaceView 
        android:id="@+id/graphics_glsurfaceview1" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent">
    </android.opengl.GLSurfaceView>
    <LinearLayout
        android:id="@+id/menu_linearLayout1"
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent"
        android:visiblility="gone"
        android:background="#000000">// opaque background
        // menus etc be here
    </LinearLayout>
    <LinearLayout       
        android:layout_height="fill_parent" 
        android:id="@+id/loading_linearLayout1" 
        android:layout_width="fill_parent" 
        android:orientation="vertical"
        android:background="#000000">// opaque background
        <ProgressBar 
            style="?android:attr/progressBarStyleLarge" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:id="@+id/loading_progressBar1">
        </ProgressBar>
        <TextView 
            android:layout_width="wrap_content" 
            android:id="@+id/loading_textView1" 
            android:layout_height="wrap_content" 
            android:text="Loading...">
        </TextView>
    </LinearLayout>
</FrameLayout>

Когда загрузка закончилась, я установил загрузочную группу просмотра как невидимую или пропавшую, а меню просмотра - в видимую. После того, как пользователь выбрал опцию запуска игры, я запускаю игровую логическую цепочку и снова открываю меню

У меня есть иерархия действий (ReTouchMenuActivity extends ReTouchActivity, затем в новом файле ReTouchActivity extends RokonActivity), так что я не получаю всю игру в одном неуправляемом файле

Я загружаю другие ресурсы в отдельные потоки (например, данные вершин для 3D-моделей), а затем загружаю их в вершины, координаты текстуры и т. Д. Непосредственно перед рисованием массивов (т.е. gl.glVertexPointer(3, GL10.GL_FLOAT, 0, meshVertices);

Настоящая проблема заключается в том, что вам необходимо загрузить текстуры в потоке GL, который может блокировать поток пользовательского интерфейса (хотя и не прерывая его), что приводит к отсутствию реакции на ввод данных пользователем при загрузке больших текстур. Моя собственная игра с использованием вышеупомянутого на ZTE Blade под управлением Android 2.1 может занять до двух секунд, чтобы загрузить некоторые большие текстуры (1 Мб +), и даже круговой индикатор выполнения перестает вращаться в течение этого времени.

Я заметил, что вы finish() активность, когда пользователь нажимает кнопку выхода, но когда пользователь покидает приложение, не нажимая кнопку выхода (например, когда он получает входящий звонок или выбирает что-то на панели уведомлений), действие / приложение по-прежнему работает в фоновом режиме. Вы должны повторно загрузить текстуры, когда они возвращают активность / приложение обратно на вершину стека (то есть пользователь открывает его заново). Если вы не перезагрузите текстуры в таком сценарии, пользователь просто получит загрузку пустых вместо текстур

Если вы попытаетесь сохранить в качестве переменной дескриптор / объект GL, который android передает в ваш метод Renderer class 'onDraw, например, для использования потоком загрузки текстуры, то он выходит из контекста после onDraw метод возвращается и загрузка текстуры завершается неудачно.

Я полагаю, это потому, что android стирает все графические данные / состояние openGL, когда пользователь покидает приложение, если другие приложения захотят его использовать. Поэтому я предполагаю, что вы не можете делать именно то, что вы хотите (предварительно загрузить текстуры в Android OS или что-то еще). Хотя, если кто-то знает лучше, мне было бы интересно услышать.

Edit:

В этом вопросе есть несколько хороших ответов о том, как ускорить фактическое время загрузки текстур

...