7

私はゲームの記憶を作っています。あなたが2枚のカードを選んだとき、それらが一致した場合、あなたはそれらを保持することができます。そうでない場合、あなたはそれらを元に戻します。その後、すでに選択したカードを覚えている場合は、次の2枚のカードをより正確に推測することができます。

私が抱えている問題は、repaint()すぐに塗り直さない方法に関係しています。

2枚目のカードを裏返すときは、結果に関係なく、両方のカードを表向きに裏返してから、捨てるか裏返しにする前に見せたいと思います。これを行うには、を呼び出しsleep()ます。

もちろんrepaint()、カードを裏返して少し待ってから、repaint()その値に基づいて、役立つ小さなJavaは1回だけ再描画します(Cが恋しいです!)。

基本的に、私は私がする前に更新を強制的に呼び出すことを望みsleep()ます。基本的に、ロジックとグラフィックスを分離するために2つのスレッドを作成するのが最善の方法であると述べている他のスレッドをいくつか読みました。その後、ロジックを作成しsleep()てGUIを更新し続けることができますが、私は1年目のCSコースの最初の学期にいます。高校では、コースのレベルを維持したいと思います(ただし、夏のWeb開発とCでのコーディングにかなりの時間を費やしました)。

StackOverflowの役立つ人々がコードを読むのが大好きだと知っているので、ここで私が以下で参照しているプログラムの一部を示します。クラスHitAreaはCardオブジェクトであり、cards[]配列には大量のHitArea'が含まれています(HitAreaクラスの名前を変更することはできません)。activeCard1activeCard2HitArea、ユーザーの2つの選択を追跡するために使用するインスタンスであり、空白のコンストラクターは予約済みの「非表示」ですが、HitArea後でnullに変更します。最後に、カードが正しい向きであるかどうかを決定cards.flip()するブール値を反転します。toggle

public void respond(HitArea choice)
{
    if(choice.inGame)
    {
        if(activeCard1.value == 0 && activeCard1.value == 0)
            activeCard1 = choice;
        else if((!(activeCard1.value == 0) && activeCard2.value == 0) && (activeCard1.id != choice.id))
        {
            activeCard2 = choice;
            check();
        }

    }
}
public void check()
{
    update();
    pause(250);
    if(activeCard2.value == activeCard1.value)
    {
        score += 2;
        activeCard1.inGame = false;
        activeCard2.inGame = false;
    }
    activeCard1.flip();
    activeCard2.flip();
    activeCard1 = new HitArea();
    activeCard2 = new HitArea();
}
public void pause(int milliseconds)
{
    try{
      Thread.currentThread().sleep(milliseconds);
    }
    catch(InterruptedException e){
        System.out.println("Exception: " + e);
    }
}

public void mousePressed(MouseEvent e)
{
    int x = e.getX();
    int y = e.getY();

    for (int i = 0; i < cardNum; i++)
        if(cards[i].boundsCheck( x, y ) )
        {
            repaint();
            cards[i].flip();
            respond(cards[i]);
        }
}

私のコードにいくつかの問題があることは間違いないので、遠慮なく指摘してください。私の基本的な構造は大丈夫だと思います。このプロジェクトでは複数のスレッドを作成したくありません(基本的なことを覚えておいてください)。

4

1 に答える 1

14

メインのSwingスレッドであるEDTでThread.sleep(...)を呼び出さないでください。これまで。代わりに、スイングタイマーを使用してください。

JLabelsを使用して画像を表示することを検討してください。そうすれば、ImageIconsを交換するだけでカードを「裏返す」ことができます。2番目のカードが裏返され、一致するものがない場合は、xxxxミリ秒の遅延で非反復Swingタイマーを開始し、タイマーのActionListenerのactionCommandメソッドで、両方のJLabelをデフォルトのImageIconに戻します。

javax.swing.Timerチュートリアルはここにあります:Swingタイマーの使用方法

編集:
g.drawStringの使用に関するコメントについて:JLabelのテキストを交換するだけなので、さらに簡単になりました。しかし、後で画像を表示するようにプログラムをアップグレードすることにした場合は、これを行うためのすべての設定ができています。

編集2:
新しいActionListenerクラスの作成に関する質問について:これには匿名の内部クラスを使用します。例えば:

  int delayTime = 2 * 1000;
  javax.swing.Timer myTimer = new Timer(delayTime, new ActionListener() {

     @Override
     public void actionPerformed(ActionEvent e) {
        // TODO: put in the code you want called in xxx mSecs.
     }
  });
  myTimer.setRepeats(false);
  myTimer.start();
于 2011-09-28T00:42:12.807 に答える