我的问题是我们的游戏可以立即切换到菜单和设置模式,但需要4-6秒来加载纹理,初始化GL渲染模式最终我只用了6个简单的纹理在游戏中创建了6个精灵。
请帮我回答两个问题: 1.如何在android操作系统中预加载我们的资源,以便更快地开始游戏? 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是安卓应用程序中两个正常的标准活动。
我正在使用此方法启动活动并在活动之间切换:
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();
}
});发布于 2011-11-22 23:21:23
我避免了这个问题,而不是为我的游戏解决它:
我使用'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线程中加载纹理,这可能会阻塞UI线程(尽管不会使其崩溃),导致在加载大型纹理时对用户输入没有响应。我自己的游戏在运行安卓2.1的中兴通讯刀片上使用上面的内容,加载一些大纹理(1mb+)可能需要两秒钟,甚至在这段时间内圆形进度条也会停止旋转。
我注意到,当用户单击quit按钮时,您会退出activity,但当用户没有单击quit按钮就离开应用程序时(例如,当他们收到来电或从通知栏中选择某些内容时),activity/应用程序仍然在后台运行。当它们将活动/应用程序带回堆栈顶部时,您必须重新加载纹理(即用户重新打开它)。如果在这种情况下不重新加载纹理,用户只会得到空白的加载,而不是纹理
如果您尝试将android传递给Renderer类的onDraw方法的GL句柄/对象另存为变量,以供纹理加载线程使用,则在onDraw方法返回且纹理加载失败后,它将脱离上下文。
我猜是因为当用户离开应用程序时,安卓清除了所有的图形数据/ openGL状态,以防其他应用程序想要使用它。因此,我假设你不能做你想要做的事情(在android操作系统中预加载纹理或其他东西)。不过,如果其他人知道得更清楚,我会很感兴趣的。
编辑:
关于加速纹理的实际加载时间,This question有一些很好的答案
https://stackoverflow.com/questions/2894743
复制相似问题