0%

java学习笔记--五子棋(1)

Java学习笔记–五子棋(1)

实现棋盘的绘制,五子棋的刷新

知识准备

实现绘制棋盘和棋子,要用到两个类,一个是JFrame,是用来生成窗体的,下面是常用方法:

1
2
3
4
5
6
7
8
9
10
11
 JFrame()  //创建一个无标题的窗口。

JFrame(String s) //创建标题为s的窗口。

public voidsetBounds(int a,int b,int width,int height) //设置窗口的初始位置是(a,b),即距屏幕左面a个像素,距屏幕上方b个像素,窗口的宽是width,高是height。

public void setSize(int width,int height) //设置窗口的大小。
public void setLocation(int x,int y) //设置窗口的位置,默认位置是(0,0)。
public void setVisible(boolean b) //设置窗口是否可见,窗口默认是不可见的。
public voidsetResizable(boolean b) //设置窗口是否可调整大小,默认可调整大小。
public voiddispose() //撤销当前窗口,并释放当前窗口所使用的资源。

接下来是鼠标监听器方法MouseListener,听名字就知道用途了,下面是常用方法:

1
2
3
4
5
public void   MouseClicked (MouseEvent e)    //鼠标点击(单或双)
public void MousePressed (MouseEvent e) //鼠标按下
public void MouseReleased(MouseEvent e) //鼠标松开
public void MouseEntered (MouseEvent e) //鼠标进入(某组件区域)
public void MouseExited (MouseEvent e) //鼠标离开(某组件区域)

绘制窗体

首先我们写一个继承自JFrame类的子类, 注意如果编译器没有自动导包的话,要加:

1
import javax.swing.*;

然后写建立窗体的方法:

1
2
3
4
5
6
7
8
9
public void initfunc(){
this.setTitle("五子棋-ver0.1");
this.setSize(1000, 1000);
this.setResizable(true);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(3);
this.getContentPane().setBackground(new Color(217, 207, 175));
this.setVisible(true);
}

这样我们就有了一个窗体,但是如果只设置窗体,窗体里面是没有任何内容的,我们还要重写paint函数,paint是JFrame类里的一个方法,这个方法是不用调用的,只需要在里面写上super.paint(g)即可。

1
2
3
4
@Override
public void paint(Graphics g){
super.paint(g);
}

五子棋

接下来我们划线,划线方法:

1
2
3
4
5
6
7
8
public void chessfunc(Graphics g){
for (int i = 0; i < 19; i++) {
g.drawLine(50, 50 + i * 50, 50 + 18 * 50, 50 + i * 50);
}
for (int i = 0; i < 19; i++) {
g.drawLine(50 + i * 50, 50, 50 + i * 50, 50 + 18 * 50);
}
}

这个50的间距是自定的,由于参考教程就是50,这里也是50比较方便。向paint中添加调用本方法的代码

五子棋划线

这样棋盘就绘制好了。

绘制棋子

棋子的绘制需要用到repaint方法,这个方法是写在鼠标监听类里的,首先这个子类要这么写:

1
class MyMouseListener implements MouseListener

然后编译器会把上文一堆方法自动补全,我们要用到的办法就只有mousePressed和mouseReleased,
一个用来监听绘制棋子,一个用来防止改变已有棋子的颜色,首先是mousePressed方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Override
public void mousePressed(MouseEvent e) {
int y = e.getX();
int x = e.getY();
int cow = y / 50;
int col = x / 50;
if(x - 50 * col < 50 / 2){
if(y - 50 * cow < 50 / 2){
cow--;
}
col--;
}
else {
if(y - 50 * cow < 50 / 2)
{
cow--;
}
}
if (main.chess[cow][col].color == 2)
{
main.chess[cow][col].color = chesscol;
}
else
{
chesscol = 1 - chesscol;
}
main.repaint();
}

这里要讲的是教程里很巧妙的办法,我们再点击棋盘落子的时候,几乎不可能精准的点到两条线交汇的地点,所以我们要把这个点附近的所有点都近似到这个点上,具体的办法就是把一个正方形分成4份,每一份对应一个角,这样就解决了点的不精准的问题,具体的代码如上。

上面出现的数组是一个存储棋子的数组,具体如下:

1
2
3
4
5
6
7
8
9
10
11
public class chess {
int x;
int y;
int color; // '0'代表黑色,'1'代表白色,'2'代表还没有落子
chess(int row, int col)
{
x = row * 50 + 50;
y = col * 50 + 50;
color = 2;
}
}

chesscol意思是棋子的颜色,0为白色,1为黑色。可以看到上面的代码,如果我们点到了有棋子的地方,他就会执行chesscol = 1 - chesscol,这样等于交换了棋子的颜色,所以我们为了不改变颜色,我们在mouseReleased里再次改变颜色即可。

1
2
3
4
@Override
public void mouseReleased(MouseEvent e) {
chesscol = 1 - chesscol;
}

在代码里,有main.chess[][]; main.repaint();这里的main通过

1
2
3
4
5
private initUI main;

MyMouseListener(initUI main){
this.main = main;
}

传入

接下来完UI类,首先传入鼠标监听器,然后建立棋盘数组。

1
2
MyMouseListener mml = new MyMouseListener(this);
protected chess[][] chess = new chess[19][19];

在绘制窗体方法中加入初始化棋盘代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void initfunc(){
for (int i = 0; i < 19; i++) {
for (int j = 0; j < 19; j++) {
chess[i][j] = new chess(i, j);
}
}
this.setTitle("五子棋-ver0.1");
this.setSize(1000, 1000);
this.setResizable(true);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(3);
this.getContentPane().setBackground(new Color(217, 207, 175));
this.setVisible(true);
this.addMouseListener(mml);
}

修改绘制棋盘棋子方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
for (int i = 0; i < 19; i++) {
for (int j = 0; j < 19; j++) {
switch (chess[i][j].color){
case 0:
g.setColor(Color.BLACK);
g.fillOval(chess[i][j].x - 20, chess[i][j].y - 20, 40, 40);
break;
case 1:
g.setColor(Color.WHITE);
g.fillOval(chess[i][j].x - 20, chess[i][j].y - 20, 40, 40);
break;
}
}
}

然后写主类:

1
2
3
4
5
6
public class mainmethod {
public static void main(String[] args) {
initUI UI = new initUI();
UI.initfunc();
}
}

这样就实现了棋子的刷新:

五子棋棋子

后续在研究下this.addMouseListener(mml);,mouseListener还没有理解,加深下理解在学习自动判定胜负功能。

参考资料

https://blog.csdn.net/abc1498880402/article/details/80714862 JAVA JFrame常用方法

https://blog.csdn.net/zp357252539/article/details/80086343 【Java】鼠标监听器MouseListener、MouseMotionListener和MouseWheelListener的使用

https://blog.csdn.net/thdgth/article/details/87636030?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param Java程序设计:五子棋