HIT 软件构造lab2 P3总结分享--象棋围棋的可视化实现

本文详细介绍使用Java Swing实现象棋和围棋棋盘可视化的过程,包括棋盘布局、棋子放置与移动,以及棋盘更新的技术细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

lab2的P3部分相比于前两P,更有点软件的味道,在这一部分里面,我们需要自己设计ADT,并使用这些ADT作出一个棋类游戏的软件(没有加入行棋规则,但有基础的吃,移动,拿走等回合制)。我们不再像前两部分一样仅仅只是设计了一个或者两个比较简单的ADT,这一部分最有考验的地方应该就是如何去设计这些ADT,并且将其组装起来。

任务很明确,ADT在实验指导书上都有给出来,很明显我们需要做两个棋盘,一个是象棋的,一个是围棋的,由于象棋和围棋的行棋规则并不完全相同,我们还要区分不同的下棋规则。然后就是需要实验各个具体的ADT,关于ADT设计的方面我确实没有太多的可以分享的,每个人都有自己的方式和想法,那我就着重讲一下如何去建立可视化的棋盘。

预备知识

首先我们要了解一定的GUI的知识,java中GUI实现大体分为两种,我使用的一种是java Swing图形开发,这里给大家推荐一位大神做的十分详细的关于Swing图形界面开发的目录:Java Swing 图形界面开发,里面各种各样的知识都有,我就是靠这个活下来的[doge][doge]

象棋的可视化

我们先来分析一下象棋棋盘的特征,长宽高什么的就不说了,比较显著的特征就是它的棋的落子地方是一个个颜色交替的方块,重点是方块,所以在Swing布局里头有一个特别合适的布局就是网格布局,简直是完美契合象棋棋盘,网格布局,顾名思义就是整个页面被分割成大小均匀的网格,所以我们在建立可视化界面的时候,对JPanel的布局可以选择网格布局(GridLayout)

private JPanel panel = new JPanel(new GridLayout(8, 8));

我选择对每一个都加入一个组件(JLabel),我们可以建立一个二维数组,对应棋盘的坐标

private JLabel[][] labels = new JLabel[8][8];

接下来就是初始化棋盘,我们首先要对棋盘进行上色,就是对组件的背景设置颜色,颜色是黑白间隔的

//创建棋盘
  for (int i = 0; i < m; i++) {
   for (int j = 0; j < m; j++) {
    labels[i][j] = new JLabel();
    if ((i + j + 7) % 2 == 0) {
     labels[i][j].setBackground(Color.black);
    }
    else {
     labels[i][j].setBackground(Color.white);
     labels[i][j].setOpaque(true);
    }
    labels[i][j].setBorder(BorderFactory.createLineBorder(Color.BLACK));
    panel.add(labels[i][j]);
   }
  }

然后就是摆放棋子,我建立了一个函数,专门放棋子的,其实就是等于在相应位置上的组件中插入图片,首先要先准备好各个棋子的图片,这个我也是在网上找的,大家也可以上网找找。我们在给定的位置插入图片就行。插入图片就需要用到Image的功能,代码如下:

ImageIcon image = null;
image = new ImageIcon("picture/P1.png");//导入图片
Image imgImage = image.getImage();//创建Image
imgImage = imgImage.getScaledInstance(100, 100, Image.SCALE_DEFAULT);//设置图片参数
image.setImage(imgImage);//设置图片
labels[piece.getPosition().x()][piece.getPosition().y()].setIcon(image);//将image插入到对应组件中

下面是演示效果:
在这里插入图片描述
怎么移动棋子呢?其实也很简单,我之前使用二维数组也是为了能偷个懒,我们直接更新对应组件的图片就行了。

//变化棋子位置,直接清空旧位置的棋子图片,然后在新位置重新添加
  labels[x1][y1].setIcon(null);
  GUIchess(piece);//这个是我自己写的函数,专门更新棋子的,方法是上述插入图片的方法

围棋的可视化

围棋的格子虽然也是一块一块的,但是围棋和象棋棋子落点是不一样的,象棋是落在格子里面,而围棋是落在交叉线上,所以如果简单的使用网格布局的话,其实达不到比较好的效果,那么我们可以选择另一种方式,就是我们仔细研究JPanel,发现它其实是有画布的,也就是有一个paint函数,这个函数是用来对整个面板进行绘制的,默认情况下是什么也没有,那么我们可以在这个画板上加上线条,把整个围棋棋盘在上面画出来。想仔细了解paint函数重写的小伙伴可以移步到我上面发的链接java Swing中,里面有十分详细的使用教程和例子。
既然棋盘可以画,那么棋子自然也可以画,就是画一个圆,然后对这个圆的位置稍作调整,并且对圆的颜色进行填充。我这里选择的是比较笨重的方法,直接遍历整个棋盘,对整个棋盘的棋子进行更新,因为我们其实不知道围棋一次提子会提多少个,所以就选择直接遍历整个棋盘了。

panel = new JPanel() {
   private static final long serialVersionUID = 1L;
   @Override
   public void paint(Graphics graphics) {
    super.paint(graphics);
    //设置背景颜色
    graphics.setColor(new Color(255, 215, 0));
    graphics.fillRect(0, 0, 945, 945);
    //绘制线段,每个线段相距50
    graphics.setColor(Color.BLACK);
    for (int i = 0; i < 19; i++ ) {
     graphics.drawLine(20, 20+50 * i, 920, 20+i * 50);
     graphics.drawLine(20+i * 50, 20, 20+i * 50, 920);
    }
    //画棋子
    for ( int i = 0 ; i < 19 ; i++ )
     for (int j = 0 ; j < 19 ; j++ ) {
      Piece piece = board.getPieceOnBoard(i, j);//获取棋盘上的棋子
      if (piece == null)
       continue;
      if ( piece.getColor().equals("black")) {
       graphics.setColor(Color.black);
       graphics.fillOval(5+i*50, 5+j*50, 30, 30);
      }
      else {
       graphics.setColor(Color.white);
       graphics.fillOval(5+i*50, 5+j*50, 30, 30);
      }
     }
     //棋盘中的9个星位,半径为8
     graphics.setColor(Color.black);
     for (int i = 0; i < 3; i++ )
     for (int j = 0; j < 3; j++ ) {
      graphics.fillOval(162 + i * 300, 162 + j * 300, 16, 16);
     }
   }

而需要对棋盘进行变化的时候,那就直接更新这个画布就行

panel.updateUI();

效果如下:

在这里插入图片描述
对于初学者我再次强烈推荐@xietansheng这位大佬关于java Swing图像界面开发的博客:https://blog.youkuaiyun.com/xietansheng/article/details/72814492

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值