2017-02-07 5 views
0

私はアンドロイド用のゲームを作っています。ゲームを終了してもう一度やり直すと、スレッドに問題が発生しています。私はMainActivityのonPause関数のスレッドを中断し、notifyを使ってgamepanelのstart関数のスレッドを再開しようとしています。それはいつか動作しますが、実際にゲームを一時停止していません。Androidスレッドのアクティビティライフサイクル

スレッドを一時停止している間にアクティビティライフサイクルを実装する適切な方法は何ですか?特に、ユーザーが離れている間にゲーム更新機能を呼び出すべきでないゲームスレッド。 surfaceViewを拡張

public class MainActivity extends Activity { 

private GamePanel gamepanel; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
    //removes title 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    //full screen 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 

    gamepanel = new GamePanel(this); 

    setContentView(gamepanel); 

    SoundHandler.setContext(this); 

} 

@Override 
protected void onPause() { 
    super.onPause(); 
    gamepanel.getThread().interrupt(); 

} 

@Override 
protected void onStop() { 
    super.onStop(); 
} 


@Override 
protected void onRestart() { 
    super.onRestart(); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
} 


@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    boolean retry = true; 
    while (retry) { 
     try { 
      gamepanel.getThread().setRunning(false); 
      gamepanel.getThread().join(); 

     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     retry = false; 
    } 
} 
} 

GamePanelの:

@Override 
public void surfaceDestroyed (SurfaceHolder holder){} 

/**create surface. 
* 
* @param holder 
*/ 
@Override 
public void surfaceCreated (SurfaceHolder holder){ 
    //we can safely start the game loop 
    System.out.println("CREATING SURFACE"); 
    loadingscreen = false; 
    start(); 
} 

public void start() { 
    if(!mGameIsRunning) { 
     thread.start(); 
     thread.setRunning(true); 
     mGameIsRunning = true; 
    } else { 
     thread.onResume(); 
    } 
} 

Threadクラス

public class MainThread extends Thread { 
private SurfaceHolder surfaceHolder; 
private GamePanel gamePanel; 
public boolean running = false; 
public static Canvas canvas; 
private long startTime; 
private long fps = 1/30; 

public MainThread(SurfaceHolder surfaceHolder, GamePanel gamePanel) { 
    super(); 
    this.surfaceHolder = surfaceHolder; 
    this.gamePanel = gamePanel; 
    startTime = System.nanoTime(); 
} 

@Override 
public void run() 
{ 
    while(running) { 
     if((System.nanoTime() - startTime)/1000000000> fps) { 
      canvas = null; 
      //try locking the canvas for pixel editing 
      try { 
       canvas = surfaceHolder.lockCanvas(); 
       synchronized (surfaceHolder) { 

        this.gamePanel.update(); 
        this.gamePanel.draw(canvas); 
        this.gamePanel.checkSpeed(); 

       } 
      } catch (Exception e) { 
      } finally { 
       if (canvas != null) { 
        try { 
         surfaceHolder.unlockCanvasAndPost(canvas); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
       } 
      } 

     } 
    } 

    gamePanel.surfaceDestroyed(surfaceHolder); 
} 

public void onResume(){ 
    synchronized(this){ 
     this.notify(); 
    } 
} 

public void setRunning(boolean b) 
{ 
    running=b; 
} 
public boolean getRunning(){ 
    return running; 
} 
} 
+0

ゲームスレッドが必要でしたか? – weston

+0

onPauseのスレッドに参加し、onResumeに新しいスレッドを作成することで修正しました。 – henkaap

+0

答えを投稿してください。あなたが私のボードに乗っていこうと思っています。 – weston

答えて

0

あなたはsynchronizeprivate volatile boolean running;を使用することができますboolean running周りにメモリバリアがありません。その後、あなたはどこかでそれを止めるためにsetRunning(false)に電話する必要があります。これらの理由はおそらくあなたのスレッドが終了していない理由です。

しかし、とにかく別のスレッドでゲームをレンダリングすることは意味がありません。とにかく(例えば1/60秒以上)超高速レンダリングを&で更新できない場合は、それをスレッドに移動することは役に立ちません。

関連する問題