2013-06-03 5 views
-1

В следующем примере коды причинял мне некоторые горя в проекте я делаю:Хотя петля кажется, перерыв живописи кода

Вот моя проблема ...

результатов Этого кода в виде сетки квадратов втягивается в окне, наряду с цветной формой, начиная с верхней частью этой сетки:

  MainWindow mainAppWindow = mainAppWindow = new MainWindow("TETRIS"); 
      mainAppWindow.setExtendedState(Frame.MAXIMIZED_BOTH); 
      mainAppWindow.setVisible(true); 

      TetriminoFactory blockBuilder = mainAppWindow.getGameBoard().getBlockFactory(); 
      mainAppWindow.getGameBoard().setActiveTetrimino(blockBuilder.createTetrimino()); 
      Tetrimino activeTetrimino = mainAppWindow.getGameBoard().getActiveTetrimino(); 

После этого, у меня есть время цикл, который должен переместить форму вниз по экрану на определенное расстояние каждую секунды. Это движение должно быть представлено на окне:

while((activeTetrimino.getLowermostPiece().getLoc().getYPos()/MiscConsts.TETRIS_UNIT) <= mainAppWindow.getGameBoard().getLowermostRowIndex()) 
     { 
      if(activeTetrimino.checkForNeighbouringBlock().equals(Collision.BLOCK_BELOW_ME)) 
      { 
       if(!activeTetrimino.setSecuredState(true)) 
       { 
        activeTetrimino = blockBuilder.createTetrimino(); 
       } 
      } 
       activeTetrimino.moveTetrimino(0, MiscConsts.TETRIS_UNIT); 
       mainAppWindow.canvas.repaint(); 

      try { 
     Thread.sleep(MiscConsts.TIME_BETWEEN_ADVANCEMENTS); 
       } catch (InterruptedException e) { 
       System.out.println("ERROR - InterruptedException thrown in operate(). Terminating."); 
       e.printStackTrace(); 
       System.exit(1000); 
      } 
     } 

В этот момент я столкнулся с проблемой. Кажется, что цикл отменяет весь предыдущий рисунок, и получается пустой экран. Если я прокомментирую цикл, сетка рисуется вместе с формой, но, конечно, движение не происходит. Я не уверен, что здесь происходит, но я подозреваю, что это связано с нитями или чем-то еще. Или, возможно, просто в то время как петли анти-качели: P

ПОЛНОЙ ВЫПИСКА:

public static void main(String[] args) 
     { 
      theApp = new Tetris(); 

     SwingUtilities.invokeLater(new Runnable() 
             { 
              public void run() 
              { 
               theApp.createGUI();  // Call GUI creator 
              } 
             }); 
    } 

    public void createGUI() 
    { 
     MainWindow mainAppWindow = mainAppWindow = new MainWindow("TETRIS"); 
     mainAppWindow.setExtendedState(Frame.MAXIMIZED_BOTH); 
     mainAppWindow.setVisible(true); 

     TetriminoFactory blockBuilder = mainAppWindow.getGameBoard().getBlockFactory(); 
     // NEEDS WORK??? 
     mainAppWindow.getGameBoard().setActiveTetrimino(blockBuilder.createTetrimino()); 

     Tetrimino activeTetrimino = mainAppWindow.getGameBoard().getActiveTetrimino(); 


     while((activeTetrimino.getLowermostPiece().getLoc().getYPos()/MiscConsts.TETRIS_UNIT) <= mainAppWindow.getGameBoard().getLowermostRowIndex()) 
    { 
     if(activeTetrimino.checkForNeighbouringBlock().equals(Collision.BLOCK_BELOW_ME)) 
     { 
      if(!activeTetrimino.setSecuredState(true)) 
      { 
       activeTetrimino = blockBuilder.createTetrimino(); 
      } 
     } 
      activeTetrimino.moveTetrimino(0, MiscConsts.TETRIS_UNIT); 
      mainAppWindow.canvas.repaint(); 

     try { 
    Thread.sleep(MiscConsts.TIME_BETWEEN_ADVANCEMENTS); 
      } catch (InterruptedException e) { 
      System.out.println("ERROR - InterruptedException thrown in operate(). Terminating."); 
      e.printStackTrace(); 
      System.exit(1000); 
     } 
    } 
    } 
+0

Возможный дубликат [В то время как петля делает белый экран апплета и не отвечает] (http://stackoverflow.com/questions/16369264/while-loop-makes-applet-white-screen-and-unresponsive) среди множества других –

ответ

1

Похоже, что вы пытаетесь выполнить вам цикл в контексте событий Диспетчерской тему.

EDT несет ответственность за, среди прочего, обработку запросов на перерисовку. Это означает, что если вы делаете что-то, что блокирует этот поток, он не может перерисовать экран до тех пор, пока он не завершит его блокировку.

Это объясняет часть вашей проблемы.

Посмотрите на Concurrency in Swing для получения более подробной информации.

Вероятно, самым простым решением было бы заменить while взгляд с javax.swing.Timer вместо

К примеру ...

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class TestBrick { 

    public static void main(String[] args) { 
     new TestBrick(); 
    } 

    public TestBrick() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private int yPos = 0; 

     public TestPane() { 
      Timer timer = new Timer(40, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        yPos++; 
        if (yPos + 10 > getHeight()) { 
         yPos = 0; 
        } 
        repaint(); 
       } 
      }); 
      timer.setRepeats(true); 
      timer.setCoalesce(true); 
      timer.start(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      int width = getWidth(); 
      int xPos = (width - 10)/2; 
      g.drawRect(xPos, yPos, 10, 10); 
     }  
    }   
} 
+0

Cheers для ответов ребята, я попробую ваши предложения :) –

1

Вы звоните Thread.sleep на тему событий отправки или EDT для краткости.

EDT - это то, где качание выполняет всю свою работу. Если вы положите его на спящий режим, то Swing не будет рисовать или обрабатывать любые пользовательские данные.

Одним из решений было бы взять тело вашего цикла while и поместить его в SwingTimer, который будет работать каждую секунду.

Другим, гораздо более сложным решением было бы использовать холст awt, который имеет свой собственный контекст рисования и может быть нарисован в другом потоке и запустить ваш цикл в этом потоке. Посмотрите на статью Gamedev's на статью Active Rendering in Java, если вы хотите использовать подход холста.

+0

Я нахожу активный рендеринг менее сложным, как только вы изучите шаблон, необходимый для запуска холста. Жаль, что люди ныряют прямо в качели, когда начинают изучать java для игрового программирования. – arynaq

+0

Да, я согласен с тобой. Как только вы получаете активный рендеринг, это делает игру намного проще в Java. –

Смежные вопросы