爲了能夠讓Part3的棋局顯示更加直觀和美觀,我加入了棋盤的GUI設計,我們先來看一下效果圖吧
下面我就來分別介紹一下這兩個棋盤的製作過程
一、國際象棋
- 棋盤設計
國際象棋的棋盤是由黑白相間的方塊組成的,所以只需要用黑白兩色的JLabel塊填充即可,我們來看一下代碼
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 8; ++j) {
JLabel jLabel = new JLabel();
jLabel.setSize(n, n); //n是塊的大小,可以自己嘗試效果
jLabel.setLocation(j*n, i*n);
if ((i+j)%2 == 1) jLabel.setBackground(Color.WHITE);
else jLabel.setBackground(Color.GRAY); //灰色塊是考慮到避免與之後黑色的棋子衝突
jLabel.setOpaque(true);
jFrame.add(jLabel);
}
}
- 棋子設計
最開始試圖在網上直接白嫖別人的國際象棋棋子矢量圖,但是並沒有找到資源;於是被迫無奈自己作圖,請別人幫忙摳圖。這裏先把資源分享給大家:(雖然沒經過原作者同意)
https://pan.baidu.com/s/1RUBZ2aK7k8HmCwPQYeWKSw 密碼:ldd6
有了棋子,接下來的工作就十分簡單了
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 8; ++j) {
if (board[i][j]!=null) { //如果(i, j)上有棋子
Icon pic = new ImageIcon("src/P3/pic/"+board[i][j].getType()+".png");
JLabel PicLabel = new JLabel(pic);
PicLabel.setSize(n, n); //與之前的JLabel塊一致
PicLabel.setLocation(j*n, i*n); //注意JFrame上橫縱座標的邏輯是相反的
jFrame.add(PicLabel);
}
}
}
需要注意的一點是如果先畫棋盤後畫棋子的話,棋盤會直接把棋子覆蓋,這裏似乎又與我們平常的邏輯相反。所以正確的做法是先將棋子的JLabel加入JFrame中,再加入棋盤的JLabel。
二、圍棋
- 棋盤
圍棋棋盤是由橫縱各19條直線交叉後構成的,棋子就落在交叉後形成的361個交叉點上,所以棋盤的設計只需要在橫縱兩個方向上分別畫19條線段即可。不過需要注意的是圍棋棋盤有9個特殊的交叉點被我們稱爲星位,我們要在相應位置進行標註添加。下面我們來看代碼
JPanel jpanel = new JPanel() {
private static final long serialVersionUID = 1L;
@Override
public void paint(Graphics graphics) {
super.paint(graphics);
//爲棋盤設計背景顏色
graphics.setColor(new Color(255, 215, 0));
graphics.fillRect(0, 0, 675, 680);
//線段繪製
graphics.setColor(Color.BLACK);
for (int i = 0; i < 19; ++i) {
graphics.drawLine(20, 20+i*35, 650, 20+i*35);
graphics.drawLine(20+i*35, 20, 20+i*35, 650);
}
//棋盤中的9個星位
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j) {
graphics.fillOval(120+i*210, 120+j*210, 10, 10);
}
}
};
- 棋子
圍棋棋子相對於國際象棋的棋子來說就要簡單很多了,就是黑白兩色填充的圓,注意一下座標的計算就行了。
JPanel jpanel = new JPanel() {
private static final long serialVersionUID = 1L;
@Override
public void paint(Graphics graphics) {
super.paint(graphics);
for (int i = 0; i < 19; ++i)
for (int j = 0; j < 19; ++j) {
if (board[i][j] == null) continue;
if (board[i][j].getType().equals("1")) {
graphics.setColor(Color.BLACK);
graphics.fillOval(8+j*35, 8+i*35, 24, 24);
}
else {
graphics.setColor(Color.WHITE);
graphics.fillOval(8+j*35, 8+i*35, 24, 24);
}
}
}
};
JPanel比較符合我們正常的邏輯,後畫的區域覆蓋原有的區域,所以與國際象棋所用JLabel的畫法相反,我們先畫棋盤後畫棋子。
總結
棋盤的設計只是運用了一些Java中簡單的GUI語句,對於我這樣的小萌新來說還是很友好。不過經過簡單的製作後,效果顯著,能夠直觀的表示棋局狀態,還很美觀。如果有時間學習一下鼠標事件相應,可以脫離控制檯,在窗口上直接進行下棋操作就更好了。(咕咕咕
注:本次博客只供學習參考,如果涉及Lab2作業的完成,代碼還是要自己寫啊(當然棋子矢量圖可以引用