Java GUI编程实践1:五子棋

这篇博客介绍了如何使用Java Swing开发一个五子棋游戏,包括棋盘界面设计、棋局保存、落子事件处理、胜负判断以及功能按钮如【开始】、【认输】、【退出】和【游戏设置】的实现。详细源代码可在GitCode上查看。

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


前言

五子棋是一种两人对弈的纯策略性棋类游戏,棋具与围棋同用,是起源于中国古代的传统黑白棋种之一1。五子棋游戏规则简单易懂,老少皆宜,趣味横生,引人入胜。在这里用Java swing制作一个五子棋游戏。

系统总体设计

游戏开始时,由白方先开局,将一枚棋子落在棋盘上的一个交叉点上,然后由红方落子,如此轮流下子,直到某一方首先在棋盘的横向、纵向、或对角线上五子连成一条直线,则该方该局获胜。在一局中的任意时刻双方都可以认输,也可以重新开局。

项目解析

这个小游戏是用IntelliJ IDEA编写的,在Main.java中建立了4个类:

* public class Main  # 提供进入程序的main()方法
* class MyFrame extends JFrame # GUI的基础框架
* class MainScreen extends JPanel implements ActionListener, MouseListener # 各种组件的容器
* class MapPanel extends JPanel # 内有paint()方法,专门用来画棋盘

棋盘界面开发

关于棋盘界面的具体约定如下:

  • 棋盘总体大小为19 x 19(纵向、横向各19条线)
  • 棋盘总宽度为360像素,分成18份,每份20像素。
  • 棋盘总高度为360像素,分成18份,每份20像素。

具体实现代码如下:

 public void paint(Graphics g) {
 			         // 双缓冲技术防止屏幕闪烁
        BufferedImage bi = new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);
        Graphics g1 = bi.createGraphics();
        // 绘制标题、双方信息
        g1.drawString("游戏信息:" + Main.xinxi, 130, 45);
        g1.drawString("白方时间:" + Main.black_msg, 80, 480);
        g1.drawString("红方时间:" + Main.white_msg, 310, 480);
        // 绘制棋盘
        for(int i = 0; i < 19; i++) {
            g1.drawLine(60, 80+20*i, 420, 80+20*i);
            g1.drawLine(60+20*i, 80, 60+20*i, 440);
        }
        // 标注点位
        g1.fillOval(98, 138, 4, 4);
        g1.fillOval(98, 258, 4, 4);
        g1.fillOval(98, 378, 4, 4);

        g1.fillOval(218, 138, 4, 4);
        g1.fillOval(218, 258, 4, 4);
        g1.fillOval(218, 378, 4, 4);

        g1.fillOval(338, 138, 4, 4);
        g1.fillOval(338, 258, 4, 4);
        g1.fillOval(338, 378, 4, 4);
        
        // 绘制全部棋子
        draw_allwzq(g1);
        // 将缓冲区的图片显示出来
        g.drawImage(bi, 0, 0, this);
    }

保存棋局数组

通过一个全局二维数组变量保存已经下过的所有棋子的位置:

public class Main {
    public static int[][] allwzq = new int[19][19];
    ...
   	}
}

处理落子事件

当鼠标单击棋盘上的某个纵横线交叉点时,在该点上显示一个棋子。需要在public void mousePressed(MouseEvent e)中编写代码。只需要改变全局二维数组的值,然后MainScreen调用repaint()方法即可。

public void mousePressed(MouseEvent e) {
        // 如果对局已经结束,则不响应
        if(Main.is_finished) {
            return;
        }
        // 获取鼠标点击位置在棋盘上的映射
        int x = (e.getX() - 65 + 10) / 20;
        int y = (e.getY() - 85 + 10) / 20;
        System.out.println(e.getX() + "," + e.getY() + "=(" + x + "," + y + ")");
        // 棋盘四方最边上的线不能落子
        if(x >= 1 && x <= 17 && y >= 1 && y <= 17) {
            if(Main.is_black) {
                // 白方落子
                Main.allwzq[x][y] = 1;
                // 统计白方是否胜利
                boolean flag1 = is_win(1, x, y); 
                if(flag1) {
                    Main.is_finished = true;
                    JOptionPane.showMessageDialog(this, "游戏结束,白方胜利!");
                }
            } else {
                // 红方落子
                Main.allwzq[x][y] = 2;
                // 统计红方是否胜利
                boolean flag2 = is_win(2, x, y); 
                if(flag2) {
                    Main.is_finished = true;
                    JOptionPane.showMessageDialog(this, "游戏结束,红方胜利!");
                }
            }
            this.repaint();
        }
    }

判断胜负

一方落子之后,要判断横向、纵向、或对角线上是否有5个连续的同色棋子。算法是追溯到落子所在的行、列、或对角线,每当碰到需要的颜色的棋子,计数器加一,每当碰到其它颜色的棋子,计数器归零。

    public boolean is_win(int color, int x, int y) {
        // 判断横向
        int count = 0;
        for(int i = 1; i <= 17; i++) {
            if(Main.allwzq[i][y] == color) {
                count++;
                if(count == 5) {
                    return true;
                }
            }
            if(Main.allwzq[i][y] != color) {
                count = 0;
            }
        }
        ...
   	}

功能按钮的实现

【 开始 】按钮

单击【 开始 】按钮,则开始新的游戏,如下:

        if(e.getSource() == btn_start) {
            int result = JOptionPane.showConfirmDialog(this, "是否重新开始游戏?");
            if(result == 0) {
                // 重新开始游戏
                // (1)把棋盘清空
                // (2)把游戏参数复位到初始值
                intial_parameters();
            }
        }

【 认输 】按钮

单击【 认输 】按钮,表示一方放弃游戏,投子认输。

			if(e.getSource() == btn_giveUp) {
            int result = JOptionPane.showConfirmDialog(this, "是否确认认输?");
            if(result == 0) {
                if(Main.is_black) {
                    JOptionPane.showMessageDialog(this, "白方已经认输,游戏结束!");
                } else {
                    JOptionPane.showMessageDialog(this, "红方已经认输,游戏结束!");
                }
                // 棋局结束,单击【 开始 】可重新开始游戏
                Main.is_finished = true;
            }
        }

【 退出 】按钮

单击【 退出 】按钮后弹出确认对话框,确认后退出程序,否则游戏继续。

			 if(e.getSource() == btn_exit) {
            int result = JOptionPane.showConfirmDialog(this, "要退出游戏吗?");
            if(result == 0) {
                System.exit(0);
            }
        }

【 游戏设置 】按钮

这里将实现游戏倒计时的设置。如果设置了倒计时,当一方时间用完,系统将自动判定该方为输。

			if(e.getSource() == btn_setting) {
            String input = JOptionPane.showInputDialog(this, "请输入游戏的最大时间(单位:分钟):");
            try {
                Main.max_time = Integer.parseInt(input) * 60;
                // 提示输入每方每次落子的最大时限,0表示无限制
                intial_parameters_with_dialog();                
            } catch (NumberFormatException e2) {
                JOptionPane.showMessageDialog(this, "请正确输入时间!");
            }
        }

【 关于 】按钮

【 关于 】按钮用来显示程序作者的相关信息。

			 if(e.getSource() == btn_about) {
            JOptionPane.showMessageDialog(this, "制作者:下唐人\n制作时间:2023年9月");
        }

源代码

完整的源代码请在GitCode中下载查看:项目首页 - wuziqi - GitCode

运行

该项目已经编译好可执行JAR包,可直接运行。方法是打开终端,然后输入:

cd java1_jar/
java -jar java1.jar 

运行结果展示

在这里插入图片描述


  1. 聚慕课教育研发中心 编著. Java从入门到项目实践. 清华大学出版社. 2018 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

下唐人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值