Java Swing五子棋项目
一、项目简介
本项目为Java Swing五子棋项目,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。
包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。
项目都经过严格调试,eclipse 确保可以运行!
该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值
二、技术实现
后端:java,面向对象,swing编程和ImageIO类。
运行环境及开发工具:jdk,idea或者eclipse
三、功能描述
Java五子棋项目
该项目主要使用到了swing编程和ImageIO类。
- 游戏开始:清空棋盘,重新绘图
- 游戏设置:设置倒计时
- 游戏说明:说明游戏规则
- 认输:某一方放弃游戏,另一方直接获胜
- 引入背景音乐功能:可以引入音频文件
- 关于:显示程序的作者、版本等
- 退出:结束程序
##五子棋游戏的功能##
- 用户点击鼠标时,将棋子渲染到相应的位置;
- 自动判断游戏是否结束。
- 对游戏时间进行设置,判断是否超出规定时间。
实现步骤
- 渲染游戏界面(swing)。新建一个类
FiveCheeseFrame
继承JFrame
并实现MouseListener
接口。在构造方法中初始化界面(大小、位置等)。 - 在鼠标事件的
mouseClick()
方法中响应相关事件。 - 为了实现倒计时,需要单独引入一个线程。
该游戏的难点:
1.如何让游戏界面居中显示?
获取屏幕的宽高和游戏的宽高。设置显示位置为屏幕的宽高减去游戏的宽高除以2就行了。
// 取得屏幕的宽高
int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
System.out.println("屏幕的尺寸是:" + screenWidth + "*" + screenHeight);
// 设置游戏界面居中显示,jf是自定义的窗体类,继承自JFrame
jf.setLocation((screenWidth - WIDTH) / 2, (screenHeight - HEIGHT) / 2);
2.在鼠标点击的位置显示棋子?
MouseEvent的getX()
和getY()
方法可以获得点击的位置。黑子可以用实心的黑圆表示,白字可以用空心黑圆+实心白圆表示。Graphics
类的drawOval()
和fillOval()
方法。
3.之前下过的棋子的位置如何保存?
通过19*19的二维数组allChess
保存每个交叉点的状态(黑子(填充1)、白子(填充2)、无子(填充0))。
4.在窗口中绘制网格和图像
Graphics类,类似画笔,可以在窗口中绘制文字和图像。通过覆写JFrame中的paint()
方法来使用,通过repaint()
方法(表示重新执行一次paint方法)来调用。
Graphics g;
BufferedImage image;
try {image = ImageIO.read(new File("images/title.jpg")); //解决窗体透明问题只需要在窗体中绘制一张图片,在此基础上绘制其他g.drawImage(image, 20, 40,this);
} catch (IOException e) {e.printStackTrace();
}
5.如何让棋子对齐到十字线?
棋盘绘制完成后,实际上就建立了如下的一个坐标轴为0~18的坐标系坐标系。
对于每一个鼠标点击的点,我们可以取离鼠标点击位置最近的点。关键就是得到0~18的整数。将大坐标转换为小坐标。
思考:
每个单元格是25*25像素,我们惠子棋盘的时候采用的是for循环。
for (int i = 0; i < 19; i++) {g.drawLine(15, 70 + 25 * i, 465, 70 + 25 * i); // 绘制横线g.drawLine(15 + 25 * i, 70, 15 + 25 * i, 520);// 绘制竖线
}
我们通过鼠标监听器得到点击位置的坐标,然后分别减去起始位置,再除以25,就可以得到一个0~18的数,然后通过这个数字,就可以让其精确对准棋盘。
x = e.getX(); // 得到鼠标的点击位置
y = e.getY();x = (x - 15) / 25; // 得到最近的十字点,可以先得到0~18的整数,然后通过这个整数乘以每行的间距完成
y = (y - 70) / 25;
6.如何判断游戏胜负?
依据:五子棋的游戏规则:是否有同一种颜色的棋子连成5个。判断当前棋子周围是否有5个连续一样棋子——一共需要判断4种情况:水平方向、垂直方向和两条对角线的方向。其中每一种情况又需要判断两次,例如水平方向需要从左向右和从右向左进行判断。
首先得到当前的棋子的颜色color即二维数组allCheese[x][y]
。
水平方向:y坐标不变,x坐标每次增加1或者减去1.
// 横向判断
int i = 1;
while (color==allChess[x+i][y]) { // 向右判断count++;i++;
}
i = 1; // i归位,特别注意这里
while (color == allChess[x-i][y]) { // 向左判断count++;i++;
}
if (count >= 5) {flag = true; // flag表示是否有5子相连
}
同理,垂直方向仅仅是x坐标不变,y的坐标每次加1,减1。和上面的算法几乎一样
左上-右下方向:如果判断方向是“左上—>右下”,则x和y的坐标每次都加1;如果从右下判断到左上,则x和y的坐标每次加1,这里同样要注意变量i要复位。
// 左下-右上判断
int i3 = 1;
int count3 = 1;
while (color==allChess[x+i3][y-i3]) { // 左下--->右上---> allChess[x+i3][y-i3]count3++;i3++;
}
i3 = 1; // i3归位
while (color == allChess[x-i3][y+i3]) { // 右上--->左下---> allChess[x-i3][y+i3]count3++;i3++;
}
if (count3 >= 5) {flag = true;
}
右上-左下方向的判断和左上-右下的判断类似,只是x,y的变化是异号的。
思考
上面的4个方向的算法大体类似,我们可以将其抽象为一个方法。观察到以上4方向上的算法的不同之处就是x坐标和y轴的变化率,同时它们都需要判断当前棋子的颜色color
,得到当前相同棋子相连的最大数count
,将算法加以抽象得到如下的方法:
/*** 得到相同的棋子连接的数量,由上面的4次判断抽象出来的* @param xChange:x的变化* @param yChange:y的变化* @param color:当前棋子状态(黑?白)* @return*/
private int checkCount(int xChange,int yChange,int color){int count = 1;int tempX = xChange, tempY = yChange; // 保存传过来的xChange和yChange,复位的时候需要用到// 首先要检查数组下标是否越界while (x + xChange >= 0 && x + xChange <= 18 && y + yChange >= 0 && y + yChange <= 18 && color == allChess[x + xChange][y + yChange]) {count++;if (xChange != 0) {xChange++;}if (yChange != 0) {if (yChange > 0) {yChange++;}else {yChange--;}}}xChange = tempX; // 复位yChange = tempY;// 首先要检查数组下标是否越界while (x - xChange >= 0 && x - xChange <= 18 && y - yChange >= 0 && y - yChange <= 18 && color == allChess[x - xChange][y - yChange]) {count++;if (xChange != 0) {xChange++;}if (yChange != 0) {if (yChange > 0) {yChange++;}else {yChange--;}}}return count;
}
得到棋子数只需要这样调用以上的方法:
/* 判断4个方向上的棋子数,判断的顺序不重要 */
count = checkCount(1, 0, color); // 横向的棋子数
if (count >= 5) {flag = true;
}else {count = checkCount(0, 1, color); // 纵向的棋子数if (count >= 5) {flag = true;}else {count = checkCount(1, -1, color); // 左下-右上的棋子数if (count >= 5) {flag = true;}else{count = checkCount(1, 1, color); // 左上-右下的棋子数if (count >= 5) {flag = true;}}}
}
7. 如何设置倒计时##
让窗体类实现Runnable
接口,在构造方法中启动线程,并将其挂起。因为游戏刚刚启动的时候并不需要倒计时,只需要用户点击设置游戏时间之后倒计时才开始生效。声明两个全局变量blackTime
和whiteTime
分别保存黑方和白方额度剩余时间(初始值为0)。用户点击”游戏设置“按钮后,将时间赋值给这两个变量,重新开始游戏(清空棋盘),并将挂起的线程恢复(resume()
方法)。在run()
方法中首先判断是否有时间的限制,再进一步判断,当前棋子的状态,给对应的时间每隔1秒减去1,当时间变为0的时候,给用户提示,显示输赢信息,并设置不能够再次下棋。需要将时间同步显示到界面。
8.背景音乐的控制
新引入一个背景音乐的线程,在主界面渲染(窗体的构造方法中)的时候启动线程。引入一个全局变量布尔控制背景音乐的开关,当用户点击音乐的时候改变状态,并将背景音乐挂起或者恢复。
四、界面截图
五、源码地址
https://download.csdn.net/download/weixin_43860634/87364581
Java Swing五子棋项目相关推荐
- 基于Java+Swing+Mysql项目信息管理系统
基于Java+Swing+Mysql项目信息管理系统 一.系统介绍 二.功能展示 1.主页 2.新增项目信息 3.删除项目信息 三.数据库 四.其他系统实现 五.获取源码 一.系统介绍 该系统实现了查 ...
- Java Swing五子棋
项目地址:https://github.com/ListeningRift/gobang 之前用python的pygame这样一个专门用于游戏制作的游戏框架写了一个扫雷,这回事用Java Swing库 ...
- java swing mysql项目_java swing mysql 实现的家庭收支管理系统项目源码
大家好,今天给大家演示一下一款由Java swing mysql实现的简单的家庭收支情况管理系统,也可以叫个人消费情况记录软件,功能比较紧凑简单,数据库采用的是mysql,非常适合Java初学者和学生 ...
- Java Swing 小项目:模拟时钟/指针时钟 + 数字日期时钟 的实现
原文链接:https://xiets.blog.csdn.net/article/details/130685267 版权声明:原创文章禁止转载 Java Swing 图形界面开发(目录) 使用 Ja ...
- Java Swing 小项目:二维码生成器(支持添加 LOGO 图片、前景背景颜色)
原文链接:https://xiets.blog.csdn.net/article/details/130652535 版权声明:原创文章禁止转载 Java Swing 图形界面开发(目录) 使用 Ja ...
- Java swing + socket 写的一个五子棋网络对战游戏
自从开始接触Swing以来,就喜欢写写各种管理系统,写多了就萌生了一种类似于实时在线对战的游戏,经过一番构思后就开始着手设计这个网络对战版本的五子棋了. 游戏代码包含两部分,常规的C/S模式(C代表客 ...
- java做五子棋 视频_java swing实现五子棋小游戏项目源码附带视频指导运行教程...
<p> <span style="color:#555555;font-family:"font-size:16px;background-color:#FFFF ...
- java swing人机对战五子棋(含背景音乐)
一.项目简介 本项目是一套基于java swing的人机对战五子棋系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者. 包含:项目源码.数据库脚本等,该项目附带全部源码可 ...
- 使用java swing制作人机五子棋
使用java swing制作人机五子棋 背景 算法原理 棋盘分值更新范围 更新分值方法 判断分值方法 局势分数权重 设计模式 战局类Battle AI类 Integration UI设计 窗口类UIi ...
最新文章
- 2007年你必须学习的10项.NET技术
- java获取当前系统时间毫秒_java 获取当前系统时间简写 | 学步园
- UOJ #579. 树上的颜色
- 如何将iPhone应用程序从应用程序库移动到主屏幕
- 【WC2014】时空穿梭【组合数】【莫比乌斯反演】【整除分块】【暴力多项式】
- js 当前日期增加自然月
- 专题开发十二:JEECG微云快速开发平台-基础用户权限
- 35 SD配置-销售凭证设置-定义项目类别组
- 认识一下Android 事件分发机制
- angularjs路由监听,uirouter感知路由变化,解决uirouter路由监听不生效的问题
- Go语言:数组练习—从一个整数数组中获取最大整数,最小整数,总数以及平均值
- 超级硬盘数据恢复软件 4.6.5.0注冊码破解版
- 【Java+JSP+MySql】12306购票系统(二)数据库
- 计算机操作系统pv操作讲解,计算机操作系统PV操作例题
- java打印sscil码_2018最新发布 |SSCI收录语言学学科期刊目录
- 转载:TD之父李世鹤:TD即将安乐死
- 用友系统服务器架构,用友ERP-U总体架构.DOC
- 【BBF系列协议】TR104 VoIP CPE的配置参数
- 此计算机没有Intel处理器,而加速Android仿真器需要该处理器
- 极链AI云丨图像转换代表作CycleGAN快速复现
热门文章
- c语言中常量有何作用,正确的C语言常量是什么?
- 关于 npm 安装angular报错‘code EEXIST‘,ERR path C:\Users\Administrator\AppData\Roaming\npm\node_modules
- Xamarin Android安装教程(2016最新亲测安装版)
- Nikon Capture NX2.2.6下载及破解方法
- 快速创建ROS2 packages
- 【Cartographer参数详解,调参,降低计算量调优笔记记录】
- Tableau 符号地图、连续面积图、圆视图、仪表板
- Oracle 实用技巧之不知道密码情况下 dblink 的迁移
- Unity 灯光设置——灯光类型
- 谈谈MySQL如何选择float, double, decimal