此游戏可以适用实训课作业等,功能都已完善,如果导入发现内容显示的位置不合适需要自行调节,时间功能需要在代码里面取消注释才会一直跳动不然是偶尔刷新。
目录
一、实现功能
1、有良好的UI界面,用户体验良好
2、学习如何绘制棋子,鼠标点击即下棋
3、判断输赢
4、点击开始游戏可以清空棋盘,重新开始
5、悔棋功能
6、玩家认输,可以结束游戏,了解如何判断黑还是白认输
7、利用二维数组存储位置,0为空、1为黑、2为白
8、有求和的功能
一、棋盘
棋盘采用15x15的格式来布置
二、开发环境
我所使用的是IntelliJ IDEA 2023.3.4版本开发软件,使用的JDK版本是22。
其项目构成如下图:
二、窗体设计
1、窗体
窗体大小可自己按照喜欢的大小去调节,其中width和height取的是屏幕的宽度和高度。
public GameForm(){
this.addMouseListener(this);//鼠标监听器
this.setTitle("五子棋");//窗体名称
this.setSize(1334,750);//窗体大小
this.setLocation((width - 1334)/2,(height-750)/2);//保持窗体居中位置
this.setResizable(false);//设置窗体不可自由更换大小
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置窗体关闭后程序停止运行
this.addMouseListener(this);
this.setVisible(true);//显示窗体
}
2、屏幕的大小
取得屏幕的大小
int width = Toolkit.getDefaultToolkit().getScreenSize().width;//取得屏幕的宽度
int height = Toolkit.getDefaultToolkit().getScreenSize().height;//取得屏幕的高度
三、棋盘背景图和绘制棋盘棋子
1、背景导入
背景图素材我会放到最后
public void paint(Graphics g){
//绘制的东西太多会导致屏闪,所以使用双缓冲技术,防止屏闪
BufferedImage bi = new BufferedImage(1334,750,BufferedImage.TYPE_INT_ARGB);//先缓冲到内存的图片上,在给到BufferedImage再通过Graphics显示
Graphics g2 = bi.createGraphics();
//使用try包围将背景图存入内存里
try {
bgImage = ImageIO.read(new File("这里复制自己存放背景图的绝对路径,也就是文件夹路径"));
} catch (IOException e) {
throw new RuntimeException(e);
}
//背景图
g.drawImage(bgImage,0,5,this);
}
2、棋盘横轴和纵轴绘制
/*
绘制棋盘框架
*/
//Y轴X轴
for (int i = 0;i<15;i++){
g2.drawLine(324,44 + 47 * i,981,44 + 47 * i);
g2.drawLine(324 + 47 * i,44,324 + 47 * i,701);
}
//棋盘上的五个点位,从左到右
g2.fillOval(456,175,20,20);
g2.fillOval(456,552,20,20);
g2.fillOval(643,364,20,20);
g2.fillOval(831,176,20,20);
g2.fillOval(832,552,20,20);
3、棋子绘制
这里的47是我每个格子的间隔,324是行的起点位置,其中23是间隔数的一半,也就是棋子的大小
for (int i = 0;i<15;i++){//行
for (int j = 0; j<15;j++){//列
if (allChess[i][j] == 1) {
//黑子
int tempX = i * 47 + 324 + 47;
int tempY = j * 47 + 44 + 47;
g.fillOval(tempX-23,tempY-23,46,46);
}
if (allChess[i] [j] == 2) {
//白子
int tempX = i * 47 + 324 + 47;
int tempY = j * 47 + 44 + 47;
g.setColor(Color.WHITE);
g.fillOval(tempX-23,tempY-23,46,46);
g.setColor(Color.BLACK);
g.drawOval(tempX-23,tempY-23,46,46);
}
}
}
四、棋子坐标存储和按钮的设计
1、存储棋子的坐标
我采用的是二维数组来存棋子坐标,然后再用一个一维数组来存储当时棋子所在的位置用来设计悔棋功能。
//用二维数组保存下过的全部棋子坐标
int[][]allChess = new int[15][15];//15x15的棋盘布局,以0为空1\2为有标准来判断
int [] lastPiece = new int[2];
2、按钮的设计
我这里的按钮并不是组件,而是采用坐标。坐标可以用一个鼠标事件和屏幕的宽和高来取得。
/*
四个游戏内按钮
*/
if (e.getX() >= 1105 && e.getX() <=1295 && e.getY() >= 97 && e.getY() <= 154){
int result = JOptionPane.showConfirmDialog(this,"是否重新开始游戏?");
if(result == 0){
//现在可以重新开始游戏,将数组数据全部清零
for (int i = 0;i<15;i++){
for (int j = 0;j<15;j++){
allChess[i][j] = 0;
}
}
//将显示的信息恢复到最初始状态
message = "黑方先行";
isBlack = true;
canPlay = true;
this.repaint();//重新绘制窗体
}
}
if (e.getX() >= 1105 && e.getX() <=1295 && e.getY() >= 303 && e.getY() <= 401){
int result = JOptionPane.showConfirmDialog(this,"是否同意对方悔棋?");
if (result == 0){
int x_last = lastPiece[0];
int y_last = lastPiece[1];
int color1 = allChess[x_last][y_last];