我正在开发一个在自己的线程中运行的简单游戏。当我启动应用程序时,一切都很好。初始化线程,并从线程执行update()和render()函数,这很棒。
如果我退出应用程序,则会暂停该主题。当我再次启动应用程序时,该线程恢复正常。 (执行更新和渲染功能)。再次,这太棒了!
问题是,我按下电源按钮来睡觉设备。当我从这个状态恢复应用程序时,render()函数似乎工作正常;在我按下按钮之前,它正在绘制所有元素(背景,精灵等)。但是:精灵不再是动画!经过一些跟踪和故障排除后,我发现虽然"运行" flag设置为TRUE,好像是" RUN"功能不再运行! (另一方面,我很困惑为什么RENDER函数有效,但UPDATE函数没有,除非应用程序从其他方法渲染对象?无论如何......)
我从两个可能的角度来解决这个问题;我要么在Android操作我的线程的方式中遗漏了某些东西,要么这与对象中的成员变量已被重置的事实有关...
有人可以查看我在下面发布的基本代码,并就如何改进线程操作提出建议吗?我是一个聪明的人,我已经阅读了很多关于这个主题的不同来源的文章,现在比以往任何时候都更加困惑!我在这里走在正确的轨道上,还是有更聪明的方式做到这一点?我真的需要一个单独的游戏线程,还是可以使用设备的主线程来运行它?
感谢您的反馈!
public class GameThread extends Thread {
private boolean running=false;
private SurfaceHolder surfaceHolder;
private GameView gameView;
public GameThread(SurfaceHolder surfaceHolder, GameView gameView){
super();
this.surfaceHolder = surfaceHolder;
this.gameView = gameView;
}
@Override
public void run(){
Canvas canvas;
// THIS ONLY RUNS ONCE!
// WHEN I TURN THE POWER OFF AND BACK ON, THE RUN() METHOD DOES NOT RUN!
// ODDLY ENOUGH, IF I WERE TO EXIT THE APP, AND GO BACK IN, IT WORKS FINE!
// THE running FLAG SEEMS TO CHANGE PROPERLY WHEN PAUSING OR RESUMING (SEE gameView, BELOW).
while (running){
canvas = null;
try {
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder){
gameView.update();
gameView.render(canvas);
}
} finally {
if (canvas!=null)
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
public void setRunning(boolean running){
this.running = running;
}
}
public class GameView extends SurfaceView implements SurfaceHolder.Callback {
private GameThread thread;
private GameScreen gameScreen;
public GameView(Context context) {
super(context);
gameScreen = new GameScreen(context);
setFocusable(true);
thread = new GameThread(getHolder(), this);
getHolder().addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
thread = new GameThread(getHolder(), this);
thread.setRunning(true);
thread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
while (retry){
try {
thread.join();
retry = false;
} catch (InterruptedException e){
// Do nothing; continue trying
}
}
}
public void render(Canvas canvas){
gameScreen.draw(canvas);
}
public void update(){
gameScreen.update();
}
@Override
public boolean onTouchEvent(MotionEvent event){
gameScreen.touch(event);
}
public void resume(){
// TODO: Resume events go here
thread.setRunning(true);
}
public void pause(){
// TODO: Pause events go here
thread.setRunning(false);
}
}
public class GameScreen {
public GameScreen(Context context){
// Initialize private variables here
}
public void draw(Canvas canvas){
// Draw events go here
}
public void update(){
// Update events go here
}
public void touch(MotionEvent event){
// Touch events go here
}
}
答案 0 :(得分:0)
在尝试发布画布之前,需要执行update()方法。仍然不确定为什么会这样,但它现在按预期工作。
Canvas canvas = null;
while (running){
gameView.update();
try {
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder){
gameView.render(canvas);
}
} finally {
if (canvas!=null)
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}