0

私はピンポンの簡単なゲームを作成するプロジェクトに取り組んでいます。プレーヤーが勝った場合、ユーザーが新しいゲームをプレイするか、プレイを停止するかを尋ねる JOptionPane ポップアップが表示されることを望みます。JOptionPane を追加すると、メソッドはユーザーがボタンを選択するのを待たずに、スタック オーバーフロー エラーが返されるまで JOptionPanes を作成し続けます。それを制御するコードは

int rightMinLeft = Right_Player_Score.getNumber()-Left_Player_Score.getNumber();
boolean rightWon = Right_Player_Score.getNumber() > 20 && rightMinLeft > 1;
if(rightWon)
{
  Object[] options = {"New Game", "Finish"};
  int i = JOptionPane.showOptionDialog(null, "Right Player has won", "Game Over", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
  if(i == 0)
  {
    reset();
  }
  else
  {
    GameOver = true;
  }
}
else if(Left_Player_Score.getNumber() > 20 && Left_Player_Score.getNumber()-Right_Player_Score.getNumber()>1)
{
  Object[] options = {"New Game", "Finish"};
  int i = JOptionPane.showOptionDialog(null, "Right Player has won", "Game Over", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
  if(i == 0)
  {
    reset();
  }
  else
  {
    GameOver = true;
  }
}

助言がありますか?

編集:完全な方法は次のとおりです。

public void update(Graphics window)
 {
  paint(window);
 }

 public void paint(Graphics window)
 {
   try{
   if(pause)
   {
     Right_Player_Score.draw("Right Player Score", window, 600, 20);
     Left_Player_Score.draw("Left Player Score", window,  0, 20);
     leftPaddle.draw(window);
     rightPaddle.draw(window);
     if(U.LELatch(keys[4]))
     {
       pause = false;
     }
   }
   else
   {
     ball.moveAndDraw(window);
     leftPaddle.draw(window);
     Right_Player_Score.draw("Right Player Score", window, Color.WHITE, 600, 20);
    Left_Player_Score.draw("Left Player Score", window,  Color.WHITE, 0, 20);
    int LeftPaddleBottom = leftPaddle.getY()+(leftPaddle.getHeight());
    int RightPaddleBottom = rightPaddle.getY()+(rightPaddle.getHeight());
    int LeftPaddleTop = leftPaddle.getY();
    int RightPaddleTop = rightPaddle.getY();
    boolean inRangeLeft = ball.getY() > LeftPaddleTop && ball.getY() < LeftPaddleBottom;
    boolean inRangeRight = ball.getY() > RightPaddleTop && ball.getY() < RightPaddleBottom;
    if(ball.getX()<=10)
    {
     ball.setXSpeed(-ball.getXSpeed());
     Right_Player_Score.increment();
    }
    else if(ball.getX()>=790)
    {
      ball.setXSpeed(-ball.getXSpeed());
      Left_Player_Score.increment();
    }
    else if((inRangeLeft && ball.getX()<=leftPaddle.getX()+leftPaddle.getWidth()))
    {
      ball.setXSpeed(-ball.getXSpeed());
      numTimes ++;
    }
    else if(inRangeRight && ball.getX()>=rightPaddle.getX())
    {
      ball.setXSpeed(-ball.getXSpeed());
      numTimes ++;
    }

    if(!(ball.getY()>=10 && ball.getY()<=450))
    {
     ball.setYSpeed(-ball.getYSpeed());
    }

    if(keys[0] == true)
    {
     leftPaddle.moveUpAndDraw(window);
    }
    else if(keys[1] == true)
    {
     leftPaddle.moveDownAndDraw(window);
    }
    else
    {
      leftPaddle.draw(window);
    }
    if(keys[2] == true)
    {
      rightPaddle.moveUpAndDraw(window);
    }
    else if(keys[3] == true)
    {
      rightPaddle.moveDownAndDraw(window);
    }
    else
    {
      rightPaddle.draw(window);
    }
    int rightMinLeft = Right_Player_Score.getNumber()-Left_Player_Score.getNumber();
    boolean rightWon = Right_Player_Score.getNumber() > 20 && rightMinLeft > 1;
    if(rightWon)
    {
      Object[] options = {"New Game", "Finish"};
      int i = JOptionPane.showOptionDialog(frame, "Right Player has won", "Game Over", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
      //window.setColor(Color.BLACK);
      //window.drawString("Right Player has won",200,400);
      //Thread.currentThread().sleep(2000);
      //int i = 1;
      if(i == 0)
      {
        reset();
      }
      else
      {
        GameOver = true;
      }
    }
    else if(Left_Player_Score.getNumber() > 20 && Left_Player_Score.getNumber()-Right_Player_Score.getNumber()>1)
    {
      Object[] options = {"New Game", "Finish"};
      int i = JOptionPane.showOptionDialog(frame, "Left Player has won", "Game Over", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
      //window.setColor(Color.BLACK);
      //window.drawString("Left Player has won",200,400);
      //Thread.currentThread().sleep(2000);
      //int i = 1;
      if(i == 0)
      {
        reset();
      }
      else
      {
        GameOver = true;
      }
    }
    Right_Player_Score.draw("Right Player Score", window, 600, 20);
    Left_Player_Score.draw("Left Player Score", window, 0, 20);
    if(numTimes == 10)
    {
      numTimes = 0;
      if(ball.getXSpeed() == Math.abs(ball.getXSpeed()))
      {
        ball.setXSpeed(ball.getXSpeed() + 1);
      }
      else
      {
        ball.setXSpeed(ball.getXSpeed() - 1);
      }
      if(ball.getXSpeed()>MAXSPEED)
      {
        ball.setXSpeed(MAXSPEED);
      }
    }
    pause = U.LELatch(keys[4]);
   }
   }
   catch(Exception e)
   {
   }
 }

これは、「public class GUI_Controller extends Canvas implement KeyListener, Runnable」で使用されます

注: コメント部分は、ユーザーに少なくとも何かを見てもらうための一時的な方法です。

4

2 に答える 2

2

表示されている動作は、paint(Graphics g)メソッドをオーバーロードしているためです。

paint(Graphics g)JavaDocから

このメソッドは、コンポーネントのコンテンツを描画する必要があるときに呼び出されます。コンポーネントが最初に表示されたとき、または損傷して修理が必要なときなど。

あなたの場合、発生している可能性があるのは、 への別の呼び出しをトリガーするあなたの上に表示されるJOptionPane.showOptionDialog()結果への呼び出しです。これにより、別の呼び出しが別の呼び出しをトリガーするなどの原因になります...これは、またはを取得するまで続きます。JDialogCanvaspaint()JOptionPane.showOptionDialog()paint()StackOverflowErrorOutOfMemoryError

実際にpaint()は、非常に頻繁に呼び出されるため、非常に効率的です。通常、カスタム描画のみをpaint()メソッドで実行する必要があります。

他のロジックは、別のメソッドに存在する必要があります。スコアリングとユーザー インタラクションのロジックをpaint()メソッドの外に移動し、描画だけをそのままにしておく必要があります。

編集: コードをもっと見ないと、描画に直接関係のないロジックをどこに移動するかについて具体的な推奨事項を示すことはできません。カスタム ペインティングの実行に関するJava Swing チュートリアルセクションを確認すると役立つ場合があります。

于 2013-03-21T15:01:16.203 に答える
0

JOptionPaneの代わりに現在のフレームを最初のパラメーターとして指定すると役立つ場合がありますnull

于 2013-03-21T14:03:43.987 に答える