为了能够让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作业的完成,代码还是要自己写啊(当然棋子矢量图可以引用