Android 基于SurfaceView和线程策略的游戏开发编程
我正在使用SurfaceView和渲染线程开发一个基于LunarLander等结构的游戏 然而,我面临许多问题,在这里我想指出所有这些问题。我希望任何想开发一款游戏的人都不需要再和他们斗争了。任何对这种结构有更好了解的人都可以分享他们的经验,因为我对安卓系统还是新手,并且渴望学习:) [1] 函数Android 基于SurfaceView和线程策略的游戏开发编程,android,multithreading,android-activity,surfaceview,Android,Multithreading,Android Activity,Surfaceview,我正在使用SurfaceView和渲染线程开发一个基于LunarLander等结构的游戏 然而,我面临许多问题,在这里我想指出所有这些问题。我希望任何想开发一款游戏的人都不需要再和他们斗争了。任何对这种结构有更好了解的人都可以分享他们的经验,因为我对安卓系统还是新手,并且渴望学习:) [1] 函数thread.start()不应被多次调用 许多文章提到在创建曲面时创建线程,以便在活动暂停后使用以下方法再次渲染: public void surfaceCreated(SurfaceHolder h
thread.start()
不应被多次调用
许多文章提到在创建曲面时创建线程,以便在活动暂停后使用以下方法再次渲染:
public void surfaceCreated(SurfaceHolder holder) {
// start the thread here so that we don't busy-wait in run()
// waiting for the surface to be created
if (thread.getState() == Thread.State.TERMINATED)
{
thread = new LunarThread(getHolder(), getContext(), getHandler());
}
thread.setRunning(true);
thread.start();
}
您可以看到,如果线程没有终止并且函数被调用,活动就会崩溃
[2] 如果您按下“电源”或“红色电话”按钮,或者电话闲置几分钟,活动将处于onPause()
状态,但线程仍在运行。这是一种非常糟糕的做法,因此我需要找到一种方法让线程停止,并在onResume()时重新开始
[3] 如果屏幕锁定为纵向/横向,并且您的游戏粘贴到另一个方向,则屏幕锁定会迫使您“定向”一次。这意味着再次开始活动。我仍然找不到解决办法。(正如我在中提到的)
以下是我修复这些问题的代码:
超线程
public class UIThread extends Activity
{
private gameView gameview;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
gameview = (gameView) findViewById(R.id.gameview);
}
protected void onPause()
{
super.onPause();
Log.v("MY_ACTIVITY", "onPause");
gameview.terminateThread();
System.gc();
}
protected void onResume()
{
super.onResume();
Log.v("MY_ACTIVITY", "onResume");
if (gameview.surfaceCreated == true)
{
gameview.createThread(gameview.getHolder());
}
}
}
游戏视图
public class gameView extends SurfaceView implements SurfaceHolder.Callback
{
boolean surfaceCreated;
class gameThread extends Thread{}
public gameView(Context context, AttributeSet attrs)
{
super(context, attrs);context.getResources();
Log.v("MY_ACTIVITY", "gameView");
surfaceCreated = false;
}
public void createThread (SurfaceHolder holder)
{
thread = new gameThread(holder);
thread.run = true;
thread.start();
}
public void terminateThread ()
{
thread.run = false;
try
{
thread.join();
}
catch (InterruptedException e)
{
Log.e("FUNCTION", "terminateThread corrupts");
}
}
public void surfaceCreated(SurfaceHolder holder)
{
Log.v("MY_ACTIVITY", "surfaceCreated");
if (surfaceCreated == false)
{
createThread(holder);
surfaceCreated = true;
}
}
public void surfaceDestroyed(SurfaceHolder holder)
{
Log.v("MY_ACTIVITY", "surfaceDestroyed");
surfaceCreated = false;
}
}
显示
<activity android:name=".UIThread"
android:screenOrientation="landscape"
android:configChanges="orientation">
我使用onResume()
而不是surfaceCreated()
来创建新线程。我设置了一个布尔值surfaceCreated
,知道onResume()
来自第一次创建应用程序,或者来自“屏幕关闭”情况
因此,每次调用onPause()
时,线程都会死亡。这似乎是一个很好的做法。让线程停止然后再次恢复的另一种方法是同步对象并调用wait/notify。但我不知道它是否更好
有没有更好的方法来控制渲染线程?我一直在处理相同的问题。我正在学习Android上的游戏开发,并且我的第一个项目也是基于月球着陆器的例子。我发现Chris Pruett创建的项目在线程管理方面实现了更好的方法。不过,这都是关于使用notify和wait方法的。我不知道它是否比你的解决方案好。解决方案在这里
public void surfaceCreated(SurfaceHolder holder){
if (plot_thread.getState() == Thread.State.TERMINATED) {
plot_thread = new WaveformPlotThread(getHolder(), this);
plot_thread.setRunning(true);
plot_thread.start();
}
else {
plot_thread.setRunning(true);
plot_thread.start();
}
}
我希望能有所帮助
@Override
public void surfaceCreated(SurfaceHolder holder) {
//if it is the first time the thread starts
if(thread.getState() == Thread.State.NEW){
thread.setRunning(true);//riga originale
thread.start();//riga originale
}
//after a pause it starts the thread again
else
if (thread.getState() == Thread.State.TERMINATED){
thread = new MainThread(getHolder(), this);
thread.setRunning(true);
thread.start(); // Start a new thread
}
}
还有这个
@Override
protected void onPause() {
Log.d(TAG, "Pausing...");
MainThread.running=false;//this is the value for stop the loop in the run()
super.onPause();
}
可能相关:Boris非常感谢您的回答,它很简单&经过长时间的搜索后仍能正常工作。我使用了此代码。我在一些设备中的问题是表面需要时间来创建;一会儿。有什么解决办法吗?