我正在尝试开发一款游戏SurfaceView
。问题是当我想摧毁thread
用方法surfaceDestroyed()
应用程序停止于thread.join()
,但如果不这样做
绘制画布(canvas.drawColor(Color.GREEN);
) 在里面onDraw()
方法一切正常。
我该如何绘制画布并调用thread.join()
??
(我从互联网上测试了许多示例游戏,它们都有相同的问题,例如,当您点击返回按钮时,您会得到一个FATAL EXCEPTION
因为thread
仍在运行)
这是尽可能简单的代码。
谢谢
public class GameView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder holder;
private GameLoopThread gameLoopThread;
public GameView(Context context) {
super(context);
holder = getHolder();
holder.addCallback(this);
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
if (gameLoopThread == null) {
gameLoopThread = new GameLoopThread(this);
gameLoopThread.setRunning(true);
gameLoopThread.start();
Log.e("thread", "iniciado");
}
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
gameLoopThread.setRunning(false);
boolean retry = true;
while (retry) {
try {
gameLoopThread.join();
retry = false;
} catch (InterruptedException e) {
}
}
Log.e("thread", "finalizado");
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.GREEN);
}
public static class GameLoopThread extends Thread {
private static final int FPS = 20;
private GameView view;
private boolean running;
public GameLoopThread(GameViwe gameView) {
this.view = gameView;
}
public void setRunning(boolean run) {
running = run;
}
@Override
public void run() {
long ticksPS = 1000 / FPS;
long startTime;
long sleepTime;
while (running) {
Canvas c = null;
startTime = System.currentTimeMillis();
try {
c = view.getHolder().lockCanvas();
synchronized (view.getHolder()) {
view.onDraw(c);
}
} finally {
if (c != null) {
view.getHolder().unlockCanvasAndPost(c);
}
}
sleepTime = ticksPS - (System.currentTimeMillis() - startTime);
try {
if (sleepTime > 0)
sleep(sleepTime);
else
sleep(10);
} catch (Exception e) {
}
}
}
}
}
所以我针对这个问题给出的解决方案是更改它所说的位置:
try {
c = view.getHolder().lockCanvas();
synchronized (view.getHolder()) {
view.onDraw(c);
}
} finally {
if (c != null) {
view.getHolder().unlockCanvasAndPost(c);
}
}
在 GameLoopThread 类的 run() 方法上:
try {
c = view.getHolder().lockCanvas();
synchronized (view.getHolder()) {
if(c != null)
view.onDraw(c);
}
} finally {
if (c != null) {
view.getHolder().unlockCanvasAndPost(c);
}
}
为了完成此活动并调用另一个活动,我添加了一个名为 GameOver 的方法,该方法效果很好:
private void GameOver() {
gameLoopThread.setRunning(false);
Context c = getContext();
c.startActivity(intent); //intent must be declared
((Activity) Pruebas.this.getContext()).finish();
}
我希望这可以帮助别人。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)