-2

私はJavaで簡単なピカチュウゲームを書いています.JProgress Barでswing.Timerを使用しています.私のコードは次のようになります:

public static void TimeBarListener(final View scr){
    ActionListener updateProBar = new ActionListener() {
        @Override
            public void actionPerformed(ActionEvent actionEvent) {
            int val = scr.timeBar.getValue();
            if (val <= 0) {
                scr.gameOver();
                scr.timer = null;
                return;
            }
            scr.timeBar.setValue(--val);
        }
    };
    int t = n*400;
    scr.timer = new Timer(t, updateProBar);
}

ここでの「src」は、私が書いたゲームを表示するために JFrame を拡張するクラスで、「n」はレベル内のピカチュウのピースの数です。完全に機能しますが、「タイマー」を追加した後、多くの問題が発生しました。

  1. 変数「t」をレベルごとに変更しましたが、機能しないようです(値をテストしましたが、正しい値でしたが、「タイマー」が取得できなかったようです)。時間の経過が速すぎて、ピースをクリックすると速くなり、長く設定しても何も変わりませんでした.

  2. 「New Game」を2回クリックすると、さらに早くタイマーが切れました。しかし、プログラムを閉じてから再度実行すると、時間は正常に戻ります。

  3. 時間がなくなってもう一度「New Game」ボタンをクリックすると、1秒間表示されてから「ゲームオーバー画面」に戻ります。たまに動くのですが、「IndexArrayOutOfBounds」のエラーが出ます。

  4. 「一時停止」ボタンを使用したいのですが、これはタイマーを一時停止してから実行し続ける必要があることを意味します。とにかく私にできることはありますか?

私の問題はコードに基づいていると思います

            if (val <= 0) {
                scr.gameOver();
                scr.timer = null;
                return;
            }

タイマーが切れると、ゲームオーバー画面が表示されます。しかし、私はこれに不慣れで、自分がどのように機能するかを理解できないため、自分で解決策を考えることができないか、問題ではないかもしれません.

皆さんからの助けが得られることを願っています。どうもありがとう :)

4

1 に答える 1

2

あなたの問題は、正しいアーキテクチャ パターンを使用していないことです。ビジネス ロジックをプレゼンテーションから分離する必要があります。time_leftまた、コントローラー (つまり ) ではなく、変数 ( など) をモデルに格納する必要がありますActionListener。参照してください: Model View Controllerパターン。これは基本的なパターンであり、ほとんどの問題を解決します。

基本的な例

mvc

Editor.java - メインクラス

public class Editor {
    public static void main(String[] args) {
        Model model = new Model();
        View view = new View(model);
        new Controller(model, view);
    }
}

View.java

public class View extends JFrame {

    private Model model;
    private JButton btn;

    public View(Model model) {
        this.model = model;
        this.btn = new JButton("Test");
    }

    public void addViewControlListener(ActionListener al){
        btn.addActionListener(al);
    }
}

コントローラー.java

public class Controller {
    public Controller(Model model, View view) {
        view.addViewControlListener(new ViewControlListener(model, view));
    }
}

ViewControlListener.java - ActionListener を実装

public class ViewControlListener implements ActionListener {

    private Model model;
    private View view;

    public ViewControlListener(Model model, View view){
        this.model = model;
        this.view = view;
    }

    public void actionPerformed(ActionEvent e) {
        //update model
        //refresh view
    }

}

ご覧のとおり、Controller.javaリスナーを作成
してビュー内のコンポーネントに追加する 1 つの場所 ( ) があります。同じリスナーの複数のインスタンスを作成し、制御を失いました。

また、 my ActionListener( ViewControlListener.java) はモデルとビューのインスタンスを保持するため、モデルの変数を更新してビューを更新できます。

あなたの申請

次に、アプリケーションについてもう少し説明します。時間変数をデクリメントし、ビューを更新して実際の状態を表示するスレッド (実際にはアクション リスナーではない) が必要です (ただし、ゲームがアクティブな場合のみ)。

したがって、セッターとゲッターを使用してモデルleftTimeと変数を作成できます。isActive

private int leftTime;
private boolean isActive;

public int getLeftTime() {
    return leftTime;
}

public void setLeftTime(int leftTime) {
    this.leftTime = leftTime;
}

public void decLeftTime() {
    this.leftTime--;
}

public boolean isActive() {
    return isActive;
}

public void setActive(boolean isActive) {
    this.isActive = isActive;
}

そして、毎秒時間を減らしてビューを再描画するスレッドを作成します:

public class Timer extends Thread {

    private Model model;
    private View view;

    public Timer(Model model, View view) {
        this.model = model;
        this.view = view;
    }

    public void run() {
        while(true) { //could be better
            if(model.isActive()) {
                model.decLeftTime();
                view.repaint();
            }
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

次に、コントローラーでそのスレッドを作成して開始します。

public class Controller {
    public Controller(Model model, View view) {
        view.addViewControlListener(new ViewControlListener(model, view));
        ...
        Timer timer = new Timer(model, view);
        timer.start();
    }
}

ビューでは、モデルからの残り時間を示すコンポーネントを追加します。それだけです。

leftTimePSゲーム開始時の設定をお忘れなく。

于 2013-10-18T08:54:55.030 に答える