3

ゲーム スレッド (SurfaceView と保持/同期) を wait/notifyAll にすることで、ゲームを一時停止/再開できます。これはすべて、ゲーム内の一時停止ボタンを使用してうまく動作します。

ただし、ホーム/戻るボタンをクリックするとゲームを一時停止できますが、アイコンをクリックしてゲームを再開すると、応答しないゲーム画面が表示されます。

OnResume() メソッドにログを記録しましたが、LogCat には何も出力されません! ゲーム画面をクリックすると、ゲーム アクティビティで「強制終了」または「待機」のエラー ダイアログが表示されます。

アプリケーションが一時停止後にハングアップしたかのように応答しない画面が表示されるのはなぜですか? inGame の一時停止/再開ボタンと同じ方法で物理ボタンを処理するにはどうすればよいですか?

ここに、操作のログキャットビューがあります。onResume SOP が onPause と同様に印刷されていないことがわかります。

LogCat ビュー

編集: 一時停止/再開ボタンと onPause/onResume 関数によって呼び出されるコード (「これ」はスレッド クラス自体)

protected void setPause(){
        synchronized (this) {
            isPaused = true;
                }
    }

    protected void setResume(){
        synchronized (this) {
            isPaused = false;
            this.notifyAll();
        }
    }

ゲームループコード:

synchronized (this) {
            while (running) {
                if (isPaused) {
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                } else {
                    Canvas c = null;

                    try {
                        c = view.getHolder().lockCanvas();
                        synchronized (view.getHolder()) {
                            view.onDraw(c);
                        }
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } 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) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }

これは、サーフェスビューから呼び出す方法です:

public void surfaceCreated(SurfaceHolder holder) {

                // start the game loop
                System.out.println("Starting Game Loop @@@@@@@@@");
                if(isPaused){
                    System.out.println("GamePaused");
                    gameLoopThread.setResume();
                }
                else{
                    System.out.println("Game Starting");
                    gameLoopThread.setRunning(true);
                }
                gameLoopThread.start();

            }

編集 2: 一時停止ボタンを使用してゲームを一時停止し、携帯電話を自動的にロックすると...再開後、問題なく正常にプレイできます。ログによると、この場合、表面の破壊が呼び出されていないことがわかります。

4

1 に答える 1

1

の後onResumeSurfaceViewが再び作成されますが、以前のすべてのデータが失われます ( に必要なすべての情報onDraw)。surfaceDestroyed以前にデータを保存し、それをonCreateサーフェスビューにリロードする必要があります

于 2012-10-02T09:05:21.887 に答える