1

我有两个使用 java swing 的游戏板按钮监听器。

最初创建俄罗斯方块网格,然后在每个按钮侦听器中添加功能。

我在我的 Play.java 中像这样设置电路板:

final TetrisGame g = new TetrisGame(11,1);
final BoardGraphics graphics = new BoardGraphics(TetrisBoard.BOARD_WIDTH, 40, g);

然后在同一个 Play.java 中创建按钮侦听器:

graphics.btnStart.addActionListener(new ActionListener()
        {
           public void actionPerformed(ActionEvent e)
           {
              Action arc = p.getAction(g);
              g.update(arc);
              graphics.colours.clear();
              graphics.setColor(g.getBoard().getGrid());
              while (arc instanceof Store){
                  arc = p.getAction(g);
                  g.update(arc);
                  graphics.colours.clear();
                  graphics.setColor(g.getBoard().getGrid());
              }

             graphics.tiles.redraw();
             System.out.println();
             System.out.println(g.toString());
             System.out.println();
           }

        });


        graphics.btnAuto.addActionListener(new ActionListener()
        {
           public void actionPerformed(ActionEvent e)
           {

               while (!g.gameEnded()){
                  Action arc = p.getAction(g);
                  g.update(arc);
                  graphics.colours.clear();
                  graphics.setColor(g.getBoard().getGrid());
                  while (arc instanceof Store){
                      arc = p.getAction(g);
                      g.update(arc);
                      //graphics.colours.clear();
                      graphics.setColor(g.getBoard().getGrid());
                  }
                  graphics.tiles.redraw();
                  System.out.println();
                  System.out.println(g.toString());
                  System.out.println();
                  /*try {
                    Thread.sleep(1000);
                } catch (InterruptedException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }*/

               }

           }

        });

btnStart 完美运行,按下一次,根据 AI 代理给出的下一步动作绘制俄罗斯方块。

我希望 btnAuto 播放每个动作,而不需要用户按 btnStart 来生成动作直到结束。然而,我的 btnAuto 并没有在网格上绘制任何东西,而是游戏的最终状态,完成状态。

谁能明白为什么在while循环中生成每次移动后这可能不会重新绘制网格?

4

1 回答 1

3

您的 while 循环在 Swing 事件线程上被调用,因此阻止线程执行其必要的操作,包括呈现 GUI 和与用户交互:

while (!g.gameEnded()){
  Action arc = p.getAction(g);

  // ....

}

我会在这里使用Swing Timer而不是while (true)循环。另一种选择是使用后台线程,但由于您所需要的只是一个非常简单的游戏循环,并且不需要在后台运行一些长时间的运行,我认为第二个选项会更复杂而没有额外的好处。

顺便说一句,我很好奇您是如何进行绘图的,以及如何让您的 Graphics 对象用于绘图。你不是在调用getGraphics()一个组件,是吗?


编辑 您在评论中的状态:

我目前有一个带有扩展 JPanel 的嵌套类的类。网格的绘制和getGraphics()在嵌套类中完成。父类创建组件并设置GUI的整体布局

不要通过调用getGraphics()GUI 组件来获取 Graphics 对象,因为获取的 Graphics 对象不会持久存在。要看到是这样,只需最小化然后恢复您的应用程序,并告诉我执行此操作后您的图形会发生什么。您应该在 JPanel 的 paintComponent 覆盖中完成所有绘图。一种选择是调用getGraphics()BufferedImage 并使用它绘制到 BufferedImage,然后在 paintComponent 覆盖中显示 BufferedImage。如果您使用第二种技术,请不要忘记在使用完 BufferedImage 的 Graphics 对象后处理它,以免占用系统资源。

于 2013-05-19T04:50:52.630 回答