Java课程设计--象棋--齐鲁工业大学
目录
1.项目简介
2.项目采用技术
3.功能需求分析
4.项目亮点
5.项目功能架构图和UML类图
6.主要功能截图
7.团队成员负责模块(表格形式)
8.项目git地址
9.团队成员git提交截图
10.项目总结
正文
1.项目简介
主要研究基于JAVA技术的中国象棋游戏的分析与设计,对中国象棋游戏特殊的行棋规则给予了细致的分析与理解,设计出了一种实时可行的行棋规则,从移动范围、移动方向和穿越障碍几个方面重新描述行棋规则,基于Java 技术通过计算机模拟实现了中国象棋特殊的行棋规则算法,设计出了一种可行的方法,使每个棋子的行棋路线都严格遵循本身的行棋规则,游戏的实战对弈得以实现。
2.项目采用技术
(1)GUI(javaswing)
(2)线程
(3)抛出异常和异常处理
3.功能需求分析
1.使用鼠标对棋子进行控制,让棋子按规则运动。
2.棋子移动可以周期性闪烁来突出棋子移动。
3.初始场景棋子按照规则摆放,每次落子没有时间限制。
4.可以进行人人对战,按照规则判断胜负。
4.项目亮点
1.棋子移动的闪烁处理
2.棋子的行走规则及吃子判断
3.判断游戏的胜利规则
4.绘制制作棋盘界面和棋子
5.项目功能架构图和UML类图
6.主要功能截图
public ChessMainFrame(String Title){ //改变系统默认字体 Font font = new Font("宋体", Font.PLAIN, 12);//(宋体,普通,12pt) java.util.Enumeration keys = UIManager.getDefaults().keys();//得到一个枚举对象keys,其中包含所有的属性键 while (keys.hasMoreElements()) {//使用keys.hasMoreElements()方法检查枚举对象中是否还有下一个元素,如果有则使用 Object key = keys.nextElement();//keys.nextElement()方法获得下一个键,并赋值给Object类型的key变量 Object value = UIManager.get(key);//UIManager.get(key)方法获取指定键的界面属性值,即获取该属性键对应的UIManager的值,保存在Object类型中的value中 if (value instanceof javax.swing.plaf.FontUIResource) {//判断获取到的值是否是 FontUIResource 类型,如果是,则表明这个属性键是字体相关的属性键。FontUIResource 是 Swing 中一个专门用于表示字体的类。 UIManager.put(key, font);//替换为新字体 font。这是通过调用UIManager.put(key, font)方法实现的。 } } //得到窗口的内容面板 pane = this.getContentPane();//得到窗口的内容面板 pane.setLayout(null);//绝对布局,防止组界面的位置和形状随着窗口的变化而变化 //创建工具栏 toolbars = new JToolBar(); text = new JLabel("欢迎使用象棋对弈系统"); //当鼠标放上显示信息 text.setToolTipText("信息提示");//setToolTip~鼠标悬停出现的内容 restart = new JButton(" 新 游 戏 "); restart.setToolTipText("重新开始新的一局"); exit = new JButton(" 退 出 "); exit.setToolTipText("退出象棋程序程序"); //把组件添加到工具栏 toolbars.setLayout(new GridLayout(1,3));//工具栏采用三格布局,1排分三格 toolbars.add(restart); toolbars.add(exit); toolbars.add(text); toolbars.setBounds(0,0,558,30);//设置像素,组件左上角在容器的坐标和组件的大小 pane.add(toolbars);//将工具栏添加到内容面板 //添加棋子标签(调用绝对布局以后,先添加的在上方,所以需要先添加棋子再添加棋盘) drawChessMan();//调用方法 //注册按扭监听 restart.addActionListener(this); exit.addActionListener(this); //注册棋子移动监听 for (int i=0;i<32;i++){ pane.add(play[i]); play[i].addMouseListener(this); } //添加棋盘标签 pane.add(checkerboard = new JLabel(new ImageIcon("E:\\idea java\\chess\\src\\image\\QQ图片20230612203821.jpg"))); checkerboard.setBounds(0,30,558,620); checkerboard.addMouseListener(this); //窗体居中 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); this.setLocation((screenSize.width / 2 - 279 ,(screenSize.height ) / 2 - 335); //设置 this.setIconImage(new ImageIcon("E:\\idea java\\chess\\src\\image\\QQ图片20230612203206.jpg").getImage());//给程序一个小图标 this.setResizable(false);//让窗体不能改变大小 this.setTitle(Title); this.setSize(558,670);//当前窗口大小,棋盘620,工具栏30,标题栏20 this.setVisible(true);//当前窗口可见 }
public void drawChessMan(){ //流程控制 int i,k; //图标 Icon in; //黑色棋子 //车 in = new ImageIcon("E:\\idea java\\chess\\src\\image\\黑车.gif"); for (i=0,k=24;i<2;i++,k+=456){ play[i] = new JLabel(in); play[i].setBounds(k,56,55,55); play[i].setName("车1"); } //马 ...........
boolean chessManClick;
int chessPlayClick=2;
public void mouseClicked(MouseEvent me){
// System.out.println("Mouse");
//当前坐标
int Ex=0,Ey=0;
//启动线程
if (tmain == null){
tmain = new Thread(this);
tmain.start();
}
//单击棋盘(移动棋子)
if (me.getSource().equals(checkerboard)){//判断点击的为棋盘
//该红棋走棋的时候
if (chessPlayClick == 2 && play[Man].getName().charAt(1) == '2'){
Ex = play[Man].getX();
Ey = play[Man].getY();
//移动卒、兵
if (Man > 15 && Man < 26){
rule.armsRule(Man, play[Man],me);
}
//移动车
.................
else{
//第一次单击棋子(闪烁棋子)
if (!chessManClick){
for (int i=0;i<32;i++){
//被单击的棋子
if (me.getSource().equals(play[i])){//判断点击的为棋子
//告诉线程让该棋子闪烁
Man=i;
//开始闪烁
chessManClick=true;
break;
}
}//for
}//if
//第二次单击棋子(吃棋子)
else if (chessManClick){
//当前没有操作(停止闪烁)
chessManClick=false;
for (i=0;i<32;i++){
//找到被吃的棋子
if (me.getSource().equals(play[i])){
//该红棋吃棋的时候
if (chessPlayClick == 2 && play[Man].getName().charAt(1) == '2'){
Ex = play[Man].getX();
Ey = play[Man].getY();
//卒、兵吃规则
if (Man > 15 && Man < 26){
rule.armsRule(play[Man], play[i]);
}
//炮吃规则
.........
int chessPlayClick=2;//红二黑一 //控制棋子闪烁的线程 Thread tmain;//线程变量 //把第一次的单击棋子给线程响应 public void run(){ while (true){ //单击棋子第一下开始闪烁 if (chessManClick){ play[Man].setVisible(false);//设置不可见 //时间控制 try{ tmain.sleep(200); } catch(Exception e){ } play[Man].setVisible(true);//可见 } //闪烁当前提示信息 以免用户看不见 else { text.setVisible(false); //时间控制 try{ tmain.sleep(250); } catch(Exception e){ } text.setVisible(true); } try{ tmain.sleep(350); } catch (Exception e){ } } }//
卒子的移动规则
/**卒子的移动规则*/
public void armsRule(int Man,JLabel play,MouseEvent me){
//黑卒向下
if (Man < 21){
//向下移动、得到终点的坐标模糊成合法的坐标
if ((me.getY()-play.getY()) > 27 && (me.getY()-play.getY()) < 86 && (me.getX()-play.getX()) < 55 && (me.getX()-play.getX()) > 0){
play.setBounds(play.getX(),play.getY()+57,55,55);
}
//向右移动、得到终点的坐标模糊成合法的坐标、必须过河
else if (play.getY() > 284 && (me.getX() - play.getX()) >= 57 && (me.getX() - play.getX()) <= 112){
play.setBounds(play.getX()+57,play.getY(),55,55);
}
//向左移动、得到终点的坐标模糊成合法的坐标、必须过河
else if (play.getY() > 284 && (play.getX() - me.getX()) >= 2 && (play.getX() - me.getX()) <=58){
//模糊坐标
play.setBounds(play.getX()-57,play.getY(),55,55);
}
}
//红卒向上
else{
//向上移动、得到终点的坐标模糊成合法的坐标
if ((me.getX()-play.getX()) >= 0 && (me.getX()-play.getX()) <= 55 && (play.getY()-me.getY()) >27 && play.getY()-me.getY() < 86){
play.setBounds(play.getX(),play.getY()-57,55,55);
}
//向右移动、得到终点的坐标模糊成合法的坐标、必须过河
else if (play.getY() <= 341 && (me.getX() - play.getX()) >= 57 && (me.getX() - play.getX()) <= 112){
play.setBounds(play.getX()+57,play.getY(),55,55);
}
//向左移动、得到终点的坐标模糊成合法的坐标、必须过河
else if (play.getY() <= 341 && (play.getX() - me.getX()) >= 3 && (play.getX() - me.getX()) <=58){
play.setBounds(play.getX()-57,play.getY(),55,55);
}
}
}//卒移动结束
卒子的吃子规则
/**卒吃棋规则*/ public void armsRule(JLabel play1,JLabel play2){ //向右走 if (( play2.getX() - play1.getX()) <= 112 && (play2.getX() - play1.getX()) >= 57 && (play1.getY() - play2.getY()) < 57 && (play1.getY() - play2.getY()) > 0 && play2.isVisible() && play1.getName().charAt(1)!=play2.getName().charAt(1)){ //黑棋要过河才能右吃棋 if (play1.getName().charAt(1) == '1' && play1.getY() > 284 && play1.getName().charAt(1) != play2.getName().charAt(1)){ play2.setVisible(false); //把对方的位置给自己 play1.setBounds(play2.getX(),play2.getY(),55,55); } //红棋要过河才左能吃棋 else if (play1.getName().charAt(1) == '2' && play1.getY() < 341 && play1.getName().charAt(1) != play2.getName().charAt(1)){ play2.setVisible(false); //把对方的位置给自己 play1.setBounds(play2.getX(),play2.getY(),55,55); } } //向左走 else if ((play1.getX() - play2.getX()) <= 112 && (play1.getX() - play2.getX()) >= 57 && (play1.getY() - play2.getY()) < 57 && (play1.getY() - play2.getY()) > 0 && play2.isVisible() && play1.getName().charAt(1)!=play2.getName().charAt(1)){ //黑棋要过河才能左吃棋 if (play1.getName().charAt(1) == '1' && play1.getY() > 284 && play1.getName().charAt(1) != play2.getName().charAt(1)){ play2.setVisible(false); //把对方的位置给自己 play1.setBounds(play2.getX(),play2.getY(),55,55); } //红棋要过河才能右吃棋 else if (play1.getName().charAt(1) == '2' && play1.getY() < 341 && play1.getName().charAt(1) != play2.getName().charAt(1)){ play2.setVisible(false); //把对方的位置给自己 play1.setBounds(play2.getX(),play2.getY(),55,55); } } //向上走 else if (play1.getX() - play2.getX() >= -57 && play1.getX() - play2.getX() <= 57 && play1.getY() - play2.getY() >= -112 && play1.getY() - play2.getY() <= 112){ //黑棋不能向上吃棋 if (play1.getName().charAt(1) == '1' && play1.getY() < play2.getY() && play1.getName().charAt(1) != play2.getName().charAt(1)){ play2.setVisible(false); //把对方的位置给自己 play1.setBounds(play2.getX(),play2.getY(),55,55); } //红棋不能向下吃棋 else if (play1.getName().charAt(1) == '2' && play1.getY() > play2.getY() && play1.getName().charAt(1) != play2.getName().charAt(1)){ play2.setVisible(false); //把对方的位置给自己 play1.setBounds(play2.getX(),play2.getY(),55,55); } } }//卒吃结束
7.团队成员负责模块(表格形式)
姓名 | 负责部分 |
刘金省(组长) | 代码编写(棋子的吃子规则)、将项目打包成.exe |
李俊杰 | 代码编写(棋子的移动规则)、博客的编写 |
邓鸿斐 | 代码编写(框架、界面设计)、git上传 |
8.项目git地址
https://github.com/d1942547868/Chess#chess
9.团队成员git提交截图
10.项目总结
在实现这个项目的过程中,遇到了不少困难,比如象棋的棋子的类型的设计,不知道应该用什么方法去解决这个问题,所以我们只能去搜索网上的设计。通过这次课程设计使我们明白了自己知识还比较欠缺,只是学习书本知识还是远远不够的,自己不会的东西还有太多,学习需要自己长期的积累,在以后的学习、工作中都应该不断的学习,将课本的理论知识与生活中的实践知识相结合,不断提高自己文化知识和实践能力。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具