2017-11-10 191 views
0

我在Java中製作國際象棋,現在,當用戶點擊移動一個棋子時,我遇到更新棋盤的問題。我的遊戲邏輯遠未完成,我只是想讓GUI和mouseListener按照我希望他們第一的方式工作。我設計我的程序的方式是將各部分的位置全部存儲在8乘8的字符串矩陣中。 64由64個JPanel組成。每次用戶點擊移動一塊,String矩陣都應該更新,GUI應該讀取矩陣並進行相應的更新。目前,矩陣正在更新,但不是GUI。我不知道爲什麼會發生這種情況,我不知道如何解決這個問題,有人可以幫我嗎?這是我的代碼:爪哇國際象棋,如何更新板?

public class Chess extends JFrame implements MouseListener { 
    private static final long serialVersionUID = 1L; 

    private final BufferedImage whitePawnGUI = ImageIO.read(new File("img/WhitePawn.png")); 
    private final BufferedImage whiteKnightGUI = ImageIO.read(new File("img/WhiteKnight.png")); 
    private final BufferedImage whiteBishopGUI = ImageIO.read(new File("img/WhiteBishop.png")); 
    private final BufferedImage whiteRookGUI = ImageIO.read(new File("img/WhiteRook.png")); 
    private final BufferedImage whiteQueenGUI = ImageIO.read(new File("img/WhiteQueen.png")); 
    private final BufferedImage whiteKingGUI = ImageIO.read(new File("img/WhiteKing.png")); 
    private final BufferedImage blackPawnGUI = ImageIO.read(new File("img/BlackPawn.png")); 
    private final BufferedImage blackKnightGUI = ImageIO.read(new File("img/BlackKnight.png")); 
    private final BufferedImage blackBishopGUI = ImageIO.read(new File("img/BlackBishop.png")); 
    private final BufferedImage blackRookGUI = ImageIO.read(new File("img/BlackRook.png")); 
    private final BufferedImage blackQueenGUI = ImageIO.read(new File("img/BlackQueen.png")); 
    private final BufferedImage blackKingGUI = ImageIO.read(new File("img/BlackKing.png")); 

    private String[][] piecePositions = new String[8][8]; 
    private JPanel[][] boardTiles = new JPanel[8][8]; 
    private String lastSelected = ""; 
    private int lastSelectedRow = 0; 
    private int lastSelectedCol = 0; 

    public Chess() throws IOException { 
     setTitle("Chess"); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     setResizable(true); 
     setLayout(new BorderLayout()); 
     getContentPane().setBackground(Color.white); 

     // white pieces 
     piecePositions[6][0] = "wp"; 
     piecePositions[6][1] = "wp"; 
     piecePositions[6][2] = "wp"; 
     piecePositions[6][3] = "wp"; 
     piecePositions[6][4] = "wp"; 
     piecePositions[6][5] = "wp"; 
     piecePositions[6][6] = "wp"; 
     piecePositions[6][7] = "wp"; 

     piecePositions[7][1] = "wn"; 
     piecePositions[7][6] = "wn"; 

     piecePositions[7][2] = "wb"; 
     piecePositions[7][5] = "wb"; 

     piecePositions[7][0] = "wr"; 
     piecePositions[7][7] = "wr"; 

     piecePositions[7][3] = "wq"; 
     piecePositions[7][4] = "wk"; 

     // black pieces 
     piecePositions[1][0] = "bp"; 
     piecePositions[1][1] = "bp"; 
     piecePositions[1][2] = "bp"; 
     piecePositions[1][3] = "bp"; 
     piecePositions[1][4] = "bp"; 
     piecePositions[1][5] = "bp"; 
     piecePositions[1][6] = "bp"; 
     piecePositions[1][7] = "bp"; 

     piecePositions[0][1] = "bn"; 
     piecePositions[0][6] = "bn"; 

     piecePositions[0][2] = "bb"; 
     piecePositions[0][5] = "bb"; 

     piecePositions[0][0] = "br"; 
     piecePositions[0][7] = "br"; 

     piecePositions[0][3] = "bq"; 
     piecePositions[0][4] = "bk"; 

     System.out.println(printChessBoard(piecePositions)); 

     for (int row = 0; row < boardTiles.length; row++) { 
      for (int col = 0; col < boardTiles[row].length; col++) { 
       boardTiles[row][col] = new JPanel() { 
        private static final long serialVersionUID = 1L; 

        protected void paintComponent(Graphics g) { 
         super.paintComponent(g); 
         Graphics2D g2d = (Graphics2D) g; 
         g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
       } 
      }; 
      if (row % 2 == 0) { 
       if (col % 2 == 0) { 
        boardTiles[row][col].setBackground(new Color(240, 217, 181)); // light 
                        // brown 
       } else if (col % 2 != 0) { 
        boardTiles[row][col].setBackground(new Color(181, 136, 99)); // dark 
                        // brown 
       } 
      } else if (row % 2 != 0) { 
       if (col % 2 != 0) { 
        boardTiles[row][col].setBackground(new Color(240, 217, 181)); // light 
                        // brown 
       } else if (col % 2 == 0) { 
        boardTiles[row][col].setBackground(new Color(181, 136, 99)); // dark 
                        // brown 
       } 
      } 
      boardTiles[row][col].setLayout(new BorderLayout()); 
      final int tempRow = row; 
      final int tempCol = col; 
      boardTiles[row][col].addMouseListener(new MouseAdapter() { 
       public void mousePressed(MouseEvent e) { 
        System.out.println("row : " + tempRow + ", col: " + tempCol); 
        if (piecePositions[tempRow][tempCol] == "wp") { 
         System.out.println("White pawn"); 
         lastSelected = "wp"; 
        } else if (piecePositions[tempRow][tempCol] == "wn") { 
         System.out.println("White knight"); 
         lastSelected = "wn"; 
        } else if (piecePositions[tempRow][tempCol] == "wb") { 
         System.out.println("White bishop"); 
         lastSelected = "wb"; 
        } else if (piecePositions[tempRow][tempCol] == "wr") { 
         System.out.println("White rook"); 
         lastSelected = "wr"; 
        } else if (piecePositions[tempRow][tempCol] == "wq") { 
         System.out.println("White queen"); 
         lastSelected = "wq"; 
        } else if (piecePositions[tempRow][tempCol] == "wk") { 
         System.out.println("White king"); 
         lastSelected = "wk"; 
        } else if (piecePositions[tempRow][tempCol] == "bp") { 
         System.out.println("Black pawn"); 
         lastSelected = "bp"; 
        } else if (piecePositions[tempRow][tempCol] == "bn") { 
         System.out.println("Black knight"); 
         lastSelected = "bn"; 
        } else if (piecePositions[tempRow][tempCol] == "bb") { 
         System.out.println("Black bishop"); 
         lastSelected = "bb"; 
        } else if (piecePositions[tempRow][tempCol] == "br") { 
         System.out.println("Black rook"); 
         lastSelected = "br"; 
        } else if (piecePositions[tempRow][tempCol] == "bq") { 
         System.out.println("Black queen"); 
         lastSelected = "bq"; 
        } else if (piecePositions[tempRow][tempCol] == "bk") { 
         System.out.println("Black king"); 
         lastSelected = "bk"; 
        } else { 
         System.out.println("Blank tile"); 
         if (lastSelected != null) { 
          piecePositions[lastSelectedRow][lastSelectedCol] = null; 
          piecePositions[tempRow][tempCol] = lastSelected; 
         } 
        } 
        lastSelectedRow = tempRow; 
        lastSelectedCol = tempCol; 
        System.out.println(printChessBoard(piecePositions)); 
        boardTiles[tempRow][tempCol].setBackground(new Color(255, 255, 255, 127)); 
        boardTiles[tempRow][tempCol].repaint(); 
       } 
      }); 
      JLabel piecePicLabel = new JLabel(); 
      if (piecePositions[row][col] == "wp") { 
       piecePicLabel = new JLabel(new ImageIcon(whitePawnGUI)); 
      } else if (piecePositions[row][col] == "wn") { 
       piecePicLabel = new JLabel(new ImageIcon(whiteKnightGUI)); 
      } else if (piecePositions[row][col] == "wb") { 
       piecePicLabel = new JLabel(new ImageIcon(whiteBishopGUI)); 
      } else if (piecePositions[row][col] == "wr") { 
       piecePicLabel = new JLabel(new ImageIcon(whiteRookGUI)); 
      } else if (piecePositions[row][col] == "wq") { 
       piecePicLabel = new JLabel(new ImageIcon(whiteQueenGUI)); 
      } else if (piecePositions[row][col] == "wk") { 
       piecePicLabel = new JLabel(new ImageIcon(whiteKingGUI)); 
      } else if (piecePositions[row][col] == "bp") { 
       piecePicLabel = new JLabel(new ImageIcon(blackPawnGUI)); 
      } else if (piecePositions[row][col] == "bn") { 
       piecePicLabel = new JLabel(new ImageIcon(blackKnightGUI)); 
      } else if (piecePositions[row][col] == "bb") { 
       piecePicLabel = new JLabel(new ImageIcon(blackBishopGUI)); 
      } else if (piecePositions[row][col] == "br") { 
       piecePicLabel = new JLabel(new ImageIcon(blackRookGUI)); 
      } else if (piecePositions[row][col] == "bq") { 
       piecePicLabel = new JLabel(new ImageIcon(blackQueenGUI)); 
      } else if (piecePositions[row][col] == "bk") { 
       piecePicLabel = new JLabel(new ImageIcon(blackKingGUI)); 
      } 
      boardTiles[row][col].add(piecePicLabel); 
      boardTiles[row][col].repaint(); 
     } 
    } 

    JPanel basePanel = new JPanel() { 
     private static final long serialVersionUID = 1L; 

     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g; 
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

      // draw the board 
      g2d.drawRect(26, 0, 624, 624); 
      for (int i = 0; i < 8; i++) { 
       // numbers and letters labels 
       g2d.setColor(Color.white); 
       g2d.drawString("12345678".substring(i, i + 1), 10, i * 78 + 39); 
       g2d.drawString("abcdefgh".substring(i, i + 1), i * 78 + 39 + 20, 640); 
      } 
     } 
    }; 
    basePanel.setBackground(Color.black); 
    basePanel.setLayout(new GridLayout(8, 8)); 
    basePanel.setPreferredSize(new Dimension(650, 650)); 
    for (int row = 0; row < boardTiles.length; row++) { 
     for (int col = 0; col < boardTiles.length; col++) { 
      basePanel.add(boardTiles[row][col]); 
     } 
    } 

    getContentPane().add(basePanel); 
    pack(); 
    setLocationRelativeTo(null); 
    setVisible(true); 
} 

public static void main(String[] args) { 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      try { 
       new Chess(); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 
     } 
    }); 
} 

這裏是輸出的圖片:

Picture of chessboard

Picture of output to console

每個在棋盤64瓦的是一個JPanel,並且圖像因爲這些作品放在每個JPanel中。正如你所看到的,當我嘗試移動棋子時,它會移動到矩陣中,但不在GUI中。我該如何解決?

+0

繪製廣場的方式與您最初設置板子的方式相同。 – stark

+0

現在您將每個方塊初始化爲帶有起始圖標的JPanel,但您從不更新它們。您需要爲每個方塊提供一個paintComponent方法實現,根據數組中的字符串檢測要使用的圖像。 JPanels需要檢查每次繪製時是否應該更改圖標。 – SpacePrez

+0

創建自己的類,它從JLabel擴展並根據棋盤狀態繪製圖標。你的類需要重寫paintComponent()。或者更新你的主棋盤paintComponent()來簡單地遍歷每個tile並用正確的圖像調用.setIcon(...)。 – SpacePrez

回答

2

當您在矩陣中執行移動時,您也不會在圖形板(JPanel[][])中實際執行移動。

尤其如此:

// ... 
} else { 
    System.out.println("Blank tile"); 
    if (lastSelected != null) { 
     piecePositions[lastSelectedRow][lastSelectedCol] = null; 
     piecePositions[tempRow][tempCol] = lastSelected; 
     // 
     // HERE you miss something I guess <<<<<<<<<<<<<<<<<<<<< 
     // Do something with boardTiles... 
    } 
} 
// ... 

重要的東西也:從不使用==!=比較字符串或者你可能會遇到麻煩的時候(會惡性)。相反,如果你是害怕與null使用以下建設:

if("bn".equals(piecePositions[row][col])) { 
     // you avoid NullPointerException that way 
    } 

更importanly我們會認爲這是一些沙箱代碼..否則,它缺少了一堆東西:

  • 待辦事項對象 - 面向程序設計定義至少Board,PieceMove類。它會讓你的生活如此美好。
  • 同時嘗試並能夠區分GUI代碼和普通代碼。您可以通過這種方式輕鬆調試您的應用程序,通常它必須可以在單元測試和控制檯輸入/輸出的情況下進行測試。
  • 清理你的代碼,製作方法,開心。