4

私の問題は、私たちのゲームがメニューと設定モードに即座に切り替えることができることですが、テクスチャをロードするのに 4 ~ 6 秒かかり、最終的に GL レンダリング モードを初期化することです。

2 つの質問に答えるのを手伝ってください。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 でゲームをレンダリングします。 .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 アプリケーションの 2 つの通常の標準アクティビティです。

このメソッドを使用して、アクティビティを開始および切り替えています。

  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();
   }
  });
4

1 に答える 1

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 以上) をロードするのに最大 2 秒かかる場合があり、この間、円形のプログレス バーでさえ回転を停止します。

ユーザーが終了ボタンをクリックしたときのアクティビティに気付きfinish()ましたが、ユーザーが終了ボタンをクリックせずにアプリを離れた場合 (たとえば、電話がかかってきたときや通知バーから何かを選択したときなど)、アクティビティ/アプリは引き続きバックグラウンド。アクティビティ/アプリをスタックの一番上に戻すとき (つまり、ユーザーが再び開いたとき) に、テクスチャを再ロードする必要があります。このようなシナリオでテクスチャを再ロードしない場合、ユーザーはテクスチャの代わりに空白のロードを取得します。

RendererAndroid がクラスのメソッドに渡す GL ハンドル/オブジェクトを変数として保存しようとすると、onDrawたとえば、テクスチャをロードするスレッドで使用するために、onDrawメソッドが戻ってテクスチャのロードが失敗した後にコンテキストから外れます。

他のアプリがそれを使用したい場合に備えて、ユーザーがアプリを離れると、Androidがすべてのグラフィックデータ/ openGL状態を消去するためだと思います。したがって、あなたが目指していることを正確に行うことはできないと思います(Android OSなどにテクスチャをプリロードします)。他の誰かがもっとよく知っているなら、私は聞くことに興味があります.

編集:

この質問には、テクスチャの実際のロード時間の高速化に関するいくつかの良い答えがあります

于 2011-11-22T15:21:23.290 に答える