0

我正在做一个项目,我在其中创建了一个简单的乒乓球游戏。如果玩家获胜,我希望弹出一个 JOptionPane 询问用户是想玩新游戏还是停止玩。当我添加 JOptionPane 时,该方法不会等待用户选择按钮,而是继续创建 JOptionPane 直到它返回堆栈溢出错误。控制它的代码是

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)
   {
   }
 }

这用于“公共类 GUI_Controller extends Canvas implements KeyListener, Runnable”

注意:注释部分是让用户至少看到一些东西的权宜之计。

4

2 回答 2

2

您看到的行为是因为您正在重载该paint(Graphics g)方法。

来自paint(Graphics g)JavaDoc

当应该绘制组件的内容时调用此方法;例如,当组件首次展示或损坏并需要维修时。

在您的情况下,可能发生的情况是对您JOptionPane.showOptionDialog()JDialog显示的Canvas调用会触发对 的另一个调用paint()。这反过来又会导致另一个呼叫JOptionPane.showOptionDialog()触发另一个呼叫paint(),依此类推......这将一直持续到您得到 a StackOverflowErroror OutOfMemoryError

在实践中,paint()被调用非常频繁,因此它应该非常有效。通常,只有您的自定义绘图应该在该paint()方法中完成。

其他逻辑应该存在于不同的方法中。您应该将评分和用户交互的逻辑移到paint()方法之外,只保留绘图。

编辑: 在没有看到更多代码的情况下,我无法为您提供与绘画不直接相关的逻辑移动位置的具体建议。查看Java Swing 教程中的Performing Custom Painting部分可能会有所帮助。

于 2013-03-21T15:01:16.203 回答
0

JOptionPane当前帧作为第一个参数而不是null.

于 2013-03-21T14:03:43.987 回答