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.项目总结

 

  在实现这个项目的过程中,遇到了不少困难,比如象棋的棋子的类型的设计,不知道应该用什么方法去解决这个问题,所以我们只能去搜索网上的设计。通过这次课程设计使我们明白了自己知识还比较欠缺,只是学习书本知识还是远远不够的,自己不会的东西还有太多,学习需要自己长期的积累,在以后的学习、工作中都应该不断的学习,将课本的理论知识与生活中的实践知识相结合,不断提高自己文化知识和实践能力。

posted @   面朝大海,春暖花开。  阅读(131)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示