2017-07-21 89 views
1

我是新來的Java 試圖使一個簡單的播放器與電腦「井字棋」使用搖擺遊戲。在代碼中,我使用paintComponent()方法繪製某些組件,並在播放器或電腦播放後調用repaint()方法。問題在於,遊戲在第三次(有時是第二次)後點擊鼠標凍結。在GameWindow class中,我創建了Map類的實例。問題與重繪()方法在Java中

public class GameWindow extends JFrame{ 

    private final int sizeX = 3; 
    private final int sizeY = 3; 

    public GameWindow(){ 

     setLocation(400,150); 
     setSize(406, 452); 
     setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     setResizable(false); 

     Map map = new Map(sizeX, sizeY); 
     add(map, BorderLayout.CENTER); 
     JPanel bottomPanel = new JPanel(); 
     bottomPanel.setLayout(new GridLayout(1, 2)); 
     add(bottomPanel, BorderLayout.SOUTH); 

     Button newGame = new Button("Новая игра"); 
     newGame.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("Начинаем новую игру"); 
      } 
     }); 
     Button exit = new Button("Выход"); 
     exit.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       System.exit(0); 
      } 
     }); 

     bottomPanel.add(newGame); 
     bottomPanel.add(exit); 

     setVisible(true); 
    } 
} 

這裏是在Map類鼠標點擊監聽器:

public class Map extends JPanel { 

private final int sizeX; 
private final int sizeY; 
private int cellWidth; 
private int cellHeight; 
private int cellX = -1; 
private int cellY = -1; 
private String lastPlayer = "nobody"; 

private String[][] table = new String[3][3]; 

public Map(int sizeX, int sizeY) { 

    this.sizeX = sizeX; 
    this.sizeY = sizeY; 
    setBackground(Color.WHITE); 

    for (int i = 0; i < table.length; i++) { 

     for (int j = 0; j < table.length; j++) { 

      table[i][j] = "empty"; 
     } 
    } 

    addMouseListener(new MouseAdapter() { 
     @Override 
     public void mouseReleased(MouseEvent e) { 
      super.mouseReleased(e); 

      cellX = e.getX()/cellWidth; 
      cellY = e.getY()/cellHeight; 

      if (!winOrDraw()) { 
       boolean playerProgress = playerProgress(); 
       if(playerProgress) { 
        botProgress(); 
       } 
      } 
     } 
    }); 
} 

無論在playerProgress()botProgress()方法我稱之爲repaint()方法,將新組件添加到屏幕上。我無法真正發現這個代碼中有什麼問題,以及爲什麼程序在實際調用repaint()方法後第一次凍結?

這裏是winOrDraw(),playerProgress()和botProgress()方法:

private boolean winOrDraw(){ 

    for (int i = 0; i < table.length; i++) { 

     if(table[i][0] == table[i][1] && table[i][1] == table[i][2] && !table[i][0].equals("empty")) return true; 
     else if(table[0][i] == table[1][i] && table[1][i] == table[2][i] && !table[0][i].equals("empty")) return true; 
     else if(table[0][0] == table[1][1] && table[1][1] == table[2][2] && !table[0][0].equals("empty")) return true; 
     else if(table[2][0] == table[1][1] && table[1][1] == table[0][2] && !table[2][0].equals("empty")) return true; 
    } 

    int i, j = 0; 
    for (i = 0; i < table.length; i++) { 

     for (j = 0; j < table.length; j++) { 

      if(table[i][j].equals("empty")) break; 
     } 
    } 
    if(i == table.length && j == table.length) { lastPlayer = "nobody"; return true; } 
    else return false; 
} 

private boolean playerProgress(){ 

    if(!table[cellY][cellX].equals("empty")){ 
     System.out.println("This cell is not empty"); 
     return false; 
    } else { 
     lastPlayer = table[cellY][cellX] = "player"; 
     repaint(); 
     return true; 
    } 
} 

private void botProgress(){ 

    do{ 
     if(winOrDraw()){ 

      switch (lastPlayer) { 
       case "player": 

        System.out.println("You won!"); 
        System.exit(0); 
       case "bot": 

        System.out.println("Bot won"); 
        System.exit(0); 
       default: 

        System.out.println("Draw"); 
        System.exit(0); 
      } 
     } 
     Random random = new Random(); 
     cellX = random.nextInt(2); 
     cellY = random.nextInt(2); 

     if(table[cellY][cellX].equals("empty")) { 

      lastPlayer = table[cellY][cellX] = "bot"; 
      break; 
     } 
    }while (!table[cellY][cellX].equals("empty")); 

    System.out.println("Bot's turn"); 
    repaint(); 
} 
+0

份額winOrDraw()和botProgress()方法 –

+0

@AndriiBugai我已經編輯我的問題,並添加這些方法 –

+1

爲了更好地幫助越早發佈適當[MCVE],我們需要知道什麼是'的paintComponent()' – Frakcool

回答

0

您直接將您的Swing組件到JFrame,AWT容器。你不應該那樣做。相反,你應該這樣做:

JPanel panel = new JPanel(); 
myFrame.setContentPane(panel); 

panel.setLayout(...) 
panel.add(...); 
panel.validate(); 

這應該解決您的問題。