2

Android で作成したゲームを実行するために、onDraw() メソッドと onTouch() メソッドを含む GamePanel を使用しています。また、onDraw() と update() を繰り返し呼び出す GameThread クラスも使用しています。

私のアクティビティは GamePanel をインスタンス化し、私の GamePanel は GameThread をインスタンス化します。

私の onPause() は、スレッド run 内の while ループの条件を false に設定するだけです。私の onResume() はそれを true に設定するだけでしたが、アプリを再開しようとするたびに強制終了エラー (編集 #1 を参照) が発生しました。

問題を解決する代わりに、スレッドを再インスタンス化しました。

thread = new GameThread(getHolder(), this);

これで問題の一部が解決し、アプリを最小化して問題なく再度開くことができました。ただし、アプリを使用していて、電話をロックしてからロックを解除すると (画面のオンとオフを切り替えると)、スレッドが開始されませんでした。それはフリーズした状態の私のゲームです。

この問題に対する私の解決策が非常にファンキーであることはわかっています。このすべてを行うための、より受け入れられたクリーンな方法を学びたいと思っています。

コードは次のとおりです (関係ないと思われる行をいくつか省略しました)。

ゲーム アクティビティ:

void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    gamePanel = new MainGamePanel(this);
    setContentView(gamePanel);

}
protected void onPause() {
    super.onPause();
    gamePanel.shutDown();

}
protected void onResume() {
    super.onResume();
    gamePanel.startUp();
}

ゲームパネル

public MainGamePanel(Context context) {
    super(context);
    getHolder().addCallback(this);                  //adding the callback (this) to the surface  holder to intercept events
    thread = new GameThread(getHolder(), this);     // create the game loop thread
    setFocusable(true);                             // make the GamePanel focusable so it can handle events
}
public void startUp() {
    thread = new GameThread(getHolder(), this);
}

public void shutDown() {
    thread.setRunning(false);
}

ゲームスレッド

public GameThread(SurfaceHolder surfaceHolder, MainGamePanel gameView) {
    this.surfaceHolder = surfaceHolder;
    this.gameView = gameView;
    this.run = true;
}
public void setRunning(boolean run) {
    this.run = run;
}
public void run() {
    Canvas c;//
    while (run) {
        c = null;
        try {
            c = surfaceHolder.lockCanvas(null);
            synchronized (surfaceHolder) {                  
                gameView.update();
                gameView.onDraw(c);
            }
        } finally {
            if (c != null) {
                surfaceHolder.unlockCanvasAndPost(c);
            }
        }
    }
}

さらに情報が必要な場合や、質問をより明確にする方法がある場合はお知らせください (また、コードをわかりやすい方法で提示しましたか?)。

少しの助けが大いに役立ちます。何か提案があれば、事前に感謝します。

--編集#1--

これは、強制終了したときの私の丸太猫エラーでした。

12-23 14:01:34.288: E/AndroidRuntime(9484): java.lang.IllegalThreadStateException: Thread already started.

--編集#2--

私はあなたが言ったことを試し、私の run() メソッドを次のように変更しました:

@Override
public void run() {
    Canvas c;
    while (true) {
        if (run) {/* run game thread */
            c = null;
            try {
                c = surfaceHolder.lockCanvas(null);
                synchronized (surfaceHolder) {
                    gameView.update();
                    gameView.onDraw(c);
                }
            } finally {
                if (c != null) {
                    surfaceHolder.unlockCanvasAndPost(c);
                }
            }
        } else {
            try {
                Thread.sleep(100);
            } catch (Exception e) {
            }
        }
    }
}

電話をロックすると機能しましたが、アプリを最小化して再度開くと、黒い画面が表示され、数秒後に「MyApp が応答していません。閉じますか?」というポップアップが表示されました。どこに到達したかを確認したところ、onPause() と shutDown() に到達したように見えましたが、onResume(); には到達しませんでした。また、onPause() または shutDown() を呼び出した後に update() を呼び出すこともありますが、これは奇妙です。(LogCat から情報を入手)

4

0 に答える 0