2017-11-10 144 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代码和普通代码。您可以通过这种方式轻松调试您的应用程序,通常它必须可以在单元测试和控制台输入/输出的情况下进行测试。
  • 清理你的代码,制作方法,开心。