【问题标题】:How to retain the state of a activity that has a GLSurfaceView如何保留具有 GLSurfaceView 的活动的状态
【发布时间】:2011-11-23 03:03:27
【问题描述】:

我的问题是我们的游戏可以立即切换到菜单和设置模式,但是加载纹理需要 4-6 秒,初始化 GL 渲染模式最终我只是使用 6 个简单的纹理在游戏中创建了 6 个精灵。

请帮我回答两个问题: 1.如何在android os中预加载我们的资源以更快地启动我们的游戏? 2.为了使用一个技巧来创建activity之间的实例切换,我怎样才能保持我的activity与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();
   }
  });

【问题讨论】:

    标签: android glsurfaceview


    【解决方案1】:

    我避免了这个问题,而不是为我的游戏解决它:

    我使用“FrameLayout”作为主布局,“GLSurfaceView”作为其中的第一个布局(即在堆栈的底部),接下来是“菜单”视图组,以及不透明的“正在加载”屏幕顶部其中(设置为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 线程中加载纹理,这可能会阻塞 UI 线程(尽管不会使其崩溃),从而导致在加载大型纹理时无法响应用户输入。我自己的游戏在运行 android 2.1 的 ZTE Blade 上使用上述内容可能需要长达两秒钟的时间来加载一些大纹理 (1mb+),甚至在此期间圆形进度条也会停止旋转。

    我注意到finish() 用户单击退出按钮时的活动,但是当用户在未单击退出按钮的情况下离开应用程序时(例如,当他们接到来电或从通知栏中选择某些内容时),活动/app 仍然在后台运行。当它们将活动/应用程序带回堆栈顶部时(即用户重新打开它),您必须重新加载纹理。如果您在这种情况下不重新加载纹理,用户将只会加载空白而不是纹理

    如果您尝试将 android 传递给您的 Renderer 类的 onDraw 方法的 GL 句柄/对象保存为变量,以供纹理加载线程使用,那么它在 @ 之后就会脱离上下文987654330@方法返回,纹理加载失败。

    我假设是因为当用户离开应用程序时,android 会擦除所有图形数据/openGL 状态,以防其他应用程序想要使用它。因此,我假设您不能精确地做您想做的事情(在 android 操作系统或其他任何东西中预加载纹理)。虽然如果其他人知道得更好,我会很想听。

    编辑:

    This question 有一些关于加快纹理实际加载时间的好答案

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多