Java 扫雷游戏

程序分析

使用Java编写的扫雷游戏界面程序,主要内容总结如下:

  1. Frame类继承自JFrame,构建了扫雷游戏的界面。
    • 包含文本框text、标签nowBombsetBomb、按钮start、面板MenuPamelbombPanel等组件。
    • 通过jbInit方法进行初始化设置,包括布局、组件添加和事件监听等。
  2. 游戏逻辑相关方法:
    • start_actionPerformed:处理开始按钮的动作,根据设置的地雷数进行相应操作。
    • startBomb:开始布雷,设置地雷位置并计算周围雷数。
    • CountRoundBomb:计算方块周围的雷数。
    • isWin:判断是否挖完了所有的雷。
    • isNull:当选中的位置为空时,翻开周围的地图。
    • turn:翻开方块。
    • actionPerformed:处理左键点击事件。
    • mouseClicked:处理右键点击事件。
  3. 内部类:
    • Frame1_start_actionAdapter:处理开始按钮的动作事件。
    • Bomb:表示游戏中的方块按钮,包含相关属性和方法。
    • Bomb_actionAdapter:处理方块按钮的动作事件。
    • Bomb_mouseAdapter:处理方块按钮的鼠标点击事件。

最后,在main方法中创建Frame对象并使其可见,启动游戏界面。

源码

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;public class Frameextends JFrame {JTextField text;JLabel nowBomb, setBomb;int BombNum, BlockNum; // 当前雷数,当前方块数int rightBomb, restBomb, restBlock; // 找到的地雷数,剩余雷数,剩余方块数JButton start = new JButton(" 开始 ");JPanel MenuPamel = new JPanel();JPanel bombPanel = new JPanel();Bomb[][] bombButton;JPanel c;BorderLayout borderLayout1 = new BorderLayout();GridLayout gridLayout1 = new GridLayout();public Frame() {try {setDefaultCloseOperation(EXIT_ON_CLOSE);jbInit();} catch (Exception exception) {exception.printStackTrace();}}private void jbInit() throws Exception {c = (JPanel) getContentPane();setTitle("扫雷");c.setBackground(Color.WHITE);MenuPamel.setBackground(Color.GRAY);c.setLayout(borderLayout1);setSize(new Dimension(600, 600));setResizable(false);BlockNum = 144;BombNum = 10;text = new JTextField("10 ", 3);nowBomb = new JLabel("当前雷数" + ":" + BombNum);setBomb = new JLabel("设置地雷数");start.addActionListener(new Frame1_start_actionAdapter(this));MenuPamel.add(setBomb);MenuPamel.add(text);MenuPamel.add(start);MenuPamel.add(nowBomb);c.add(MenuPamel, java.awt.BorderLayout.SOUTH);bombPanel.setLayout(gridLayout1);gridLayout1.setColumns((int) Math.sqrt(BlockNum));gridLayout1.setRows((int) Math.sqrt(BlockNum));bombButton = new Bomb[(int) Math.sqrt(BlockNum)][(int) Math.sqrt(BlockNum)];for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) {for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {bombButton[i][j] = new Bomb(i, j);// bombButton[i][j].setSize(10, 10);bombButton[i][j].setFont(new Font("", Font.PLAIN, 14));// 设置字体大小bombButton[i][j].setForeground(Color.white);bombButton[i][j].addMouseListener(new Bomb_mouseAdapter(this));bombButton[i][j].addActionListener(new Bomb_actionAdapter(this));bombPanel.add(bombButton[i][j]);}}c.add(bombPanel, java.awt.BorderLayout.CENTER);startBomb();}/* 开始按钮 */public void start_actionPerformed(ActionEvent e) {int num = Integer.parseInt(text.getText().trim());if (num >= 5 && num < 50) {BombNum = num;startBomb();} else if (num < 5) {JOptionPane.showMessageDialog(null, "您设置的地雷数太少了,请重设!", "错误",JOptionPane.ERROR_MESSAGE);num = 10;BombNum = num;} else {JOptionPane.showMessageDialog(null, "您设置的地雷数太多了,请重设!", "错误",JOptionPane.ERROR_MESSAGE);num = 10;BombNum = num;}}/* 开始,布雷 */public void startBomb() {nowBomb.setText("当前雷数" + ":" + BombNum);for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) {for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {bombButton[i][j].isBomb = false;bombButton[i][j].isClicked = false;bombButton[i][j].isRight = false;bombButton[i][j].BombFlag = 0;bombButton[i][j].BombRoundCount = 9;bombButton[i][j].setEnabled(true);bombButton[i][j].setText("");bombButton[i][j].setFont(new Font("", Font.PLAIN, 14));// 设置字体大小bombButton[i][j].setForeground(Color.BLUE);rightBomb = 0;restBomb = BombNum;restBlock = BlockNum - BombNum;}}for (int i = 0; i < BombNum;) {int x = (int) (Math.random() * (int) (Math.sqrt(BlockNum) - 1));int y = (int) (Math.random() * (int) (Math.sqrt(BlockNum) - 1));if (bombButton[x][y].isBomb != true) {bombButton[x][y].isBomb = true;i++;}}CountRoundBomb();}/* 计算方块周围雷数 */public void CountRoundBomb() {for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) {for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {int count = 0;// 当需要检测的单元格本身无地雷的情况下,统计周围的地雷个数if (bombButton[i][j].isBomb != true) {for (int x = i - 1; x < i + 2; x++) {for (int y = j - 1; y < j + 2; y++) {if ((x >= 0) && (y >= 0)&& (x < ((int) Math.sqrt(BlockNum)))&& (y < ((int) Math.sqrt(BlockNum)))) {if (bombButton[x][y].isBomb == true) {count++;}}}}bombButton[i][j].BombRoundCount = count;}}}}/* 是否挖完了所有的雷 */public void isWin() {restBlock = BlockNum - BombNum;for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) {for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {if (bombButton[i][j].isClicked == true) {restBlock--;}}}if (rightBomb == BombNum || restBlock == 0) {JOptionPane.showMessageDialog(this, "您挖完了所有的雷,您胜利了!", "胜利",JOptionPane.INFORMATION_MESSAGE);startBomb();}}/** 当选中的位置为空,则翻开周围的地图* */public void isNull(Bomb ClickedButton) {int i, j;i = ClickedButton.num_x;j = ClickedButton.num_y;for (int x = i - 1; x < i + 2; x++) {for (int y = j - 1; y < j + 2; y++) {if (((x != i) || (y != j)) && (x >= 0) && (y >= 0)&& (x < ((int) Math.sqrt(BlockNum)))&& (y < ((int) Math.sqrt(BlockNum)))) {if (bombButton[x][y].isBomb == false&& bombButton[x][y].isClicked == false&& bombButton[x][y].isRight == false) {turn(bombButton[x][y]);}}}}}/* 翻开 */public void turn(Bomb ClickedButton) {ClickedButton.setEnabled(false);ClickedButton.isClicked = true;if (ClickedButton.BombRoundCount > 0) {ClickedButton.setText(ClickedButton.BombRoundCount + "");} else {isNull(ClickedButton);}}/* 左键点击 */public void actionPerformed(ActionEvent e) {if (((Bomb) e.getSource()).isClicked == false&& ((Bomb) e.getSource()).isRight == false) {if (((Bomb) e.getSource()).isBomb == false) {turn(((Bomb) e.getSource()));isWin();} else {for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) {for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {if (bombButton[i][j].isBomb == true) {bombButton[i][j].setText("b");}}}((Bomb) e.getSource()).setForeground(Color.RED);((Bomb) e.getSource()).setFont(new Font("", Font.BOLD, 20));((Bomb) e.getSource()).setText("X");JOptionPane.showMessageDialog(this, "你踩到地雷了,按确定重来", "踩到地雷", 2);startBomb();}}}/* 右键点击 */public void mouseClicked(MouseEvent e) {Bomb bombSource = (Bomb) e.getSource();boolean right = SwingUtilities.isRightMouseButton(e);if ((right == true) && (bombSource.isClicked == false)) {bombSource.BombFlag = (bombSource.BombFlag + 1) % 3;if (bombSource.BombFlag == 1) {if (restBomb > 0) {bombSource.setForeground(Color.RED);bombSource.setText("F");bombSource.isRight = true;restBomb--;} else {bombSource.BombFlag = 0;}} else if (bombSource.BombFlag == 2) {restBomb++;bombSource.setText("Q");bombSource.isRight = false;} else {bombSource.setText("");}if (bombSource.isBomb == true) {if (bombSource.BombFlag == 1) {rightBomb++;} else if (bombSource.BombFlag == 2) {rightBomb--;}}nowBomb.setText("当前雷数" + ":" + restBomb);isWin();}}public static void main(String[] args) {Frame frame = new Frame();frame.setVisible(true);}
}class Frame1_start_actionAdapterimplements ActionListener {private Frame adaptee;Frame1_start_actionAdapter(Frame adaptee) {this.adaptee = adaptee;}public void actionPerformed(ActionEvent e) {adaptee.start_actionPerformed(e);}
}class Bombextends JButton {int num_x, num_y; // 第几号方块int BombRoundCount; // 周围雷数boolean isBomb; // 是否为雷boolean isClicked; // 是否被点击int BombFlag; // 探雷标记boolean isRight; // 是否点击右键public Bomb(int x, int y) {num_x = x;num_y = y;BombFlag = 0;BombRoundCount = 9;isBomb = false;isClicked = false;isRight = false;}
}class Bomb_actionAdapterimplements ActionListener {private Frame adaptee;Bomb_actionAdapter(Frame adaptee) {this.adaptee = adaptee;}public void actionPerformed(ActionEvent e) {adaptee.actionPerformed(e);}
}class Bomb_mouseAdapterextends MouseAdapter {private Frame adaptee;Bomb_mouseAdapter(Frame adaptee) {this.adaptee = adaptee;}public void mouseClicked(MouseEvent e) {adaptee.mouseClicked(e);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/50150.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

note24:表分区规范

目录 分区设计原则 分区维护 存储方式及分布键规范 分区设计原则 表分区用于解决数据量特别大的表的问题&#xff0c;比如事实表&#xff0c;解决办法就是将表分成很多小且更容易管理的部分。 表分区参考以下几个原则 &#xff08;1&#xff09;表是否足够大&#xff1f;…

免费【2024】springboot 趵突泉景区的智慧导游小程序

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

MATLAB基础:数组

今天我们继续学习MATLAB中的数组 我们在学习MATLAB时了解到&#xff0c;MATLAB作者秉持着“万物皆可矩阵”的思想企图将数学甚至世间万物使用矩阵表示出来&#xff0c;而矩阵的处理&#xff0c;自然成了这门语言的重中之重。 数组基础 在MATLAB中&#xff0c;数组是一个基本…

十、SpringBoot 统⼀功能处理【拦截器、统一数据返回格式、统一异常处理】

十、SpringBoot 统⼀功能处理 1. 拦截器【HandlerInterceptor、WebMvcConfig】1.1 拦截器快速⼊⻔⾃定义拦截器&#xff1a;实现HandlerInterceptor接⼝&#xff0c;并重写其所有⽅法注册配置拦截器&#xff1a;实现WebMvcConfigurer接⼝&#xff0c;并重写addInterceptors⽅法…

堆(c++)

堆是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。 堆总是满足下列性质&#xff1a; 堆中某个节点的值总是不大于或不小于其父节点的值&#xff1b;堆总是一棵完全二叉树。 常见的堆有二叉堆、斐波那契堆等。 堆是非线性数据结构&#…

初识C++ · map和set的使用

目录 前言&#xff1a; 1 set 2 map 前言&#xff1a; 在前面阶段&#xff0c;我们已经学习了stl里面的部分容器&#xff0c;比如vector,list,deque等&#xff0c;这些容器都被称为序列式容器&#xff0c;也就是每个值之间式没有关联的&#xff0c;那么今天介绍的容器&…

【笔记本触摸屏】超级好用技巧

选中文字&#xff1a;点一下要复制的文字开头&#xff0c;按住shift键不放&#xff0c;然后点一下你想要的文字结尾滚动&#xff1a;双指向 水平 或者 垂直 方向滑动放大或者缩小: 将两个手指放在触摸板上&#xff0c;让后收缩后者拉伸显示更多命令&#xff08;类似于右键单击&…

四十九、 通过境内数据交易所进行跨境数据贸易应考虑哪些跨境数据合规问题?

根据中国信通院数据显示&#xff0c;2023 年我国数字经济规模可达 56.1 万亿元, 数字经济占 GDP 比重接近于第二产业&#xff0c;占国民经济的比重&#xff0c;达到 40%以上。伴随数字技术兴起以及各项数字经济相关的政策和法律的落地&#xff0c;以跨境数据流动为底层支撑的跨…

智能音箱和普通音箱有什么区别

智能音箱和普通音箱在多个方面存在显著的区别&#xff0c;主要包括设计目的、功能特点、连接方式、音质表现以及交互方式等。 一、设计目的和功能特点 智能音箱&#xff1a;设计目的不仅仅是为了播放音乐&#xff0c;更重要的是集成了语音识别和语音交互功能&#xff0c;成为…

IGV.js | 载入自己下载的gtf文件

1.安装 htslib-1.20 https://www.htslib.org/doc/tabix.html J3$ cd ~/Downloads/ $ wget https://github.com/samtools/htslib/releases/download/1.20/htslib-1.20.tar.bz2 $ tar jxvf htslib-1.20.tar.bz2编译安装&#xff1a; $ cd htslib-1.20/ $ ./configure --prefix/…

ts -> class -> abstract

在TypeScript中&#xff0c;你可以直接使用abstract关键字来定义抽象类和抽象方法。抽象类不能被实例化&#xff0c;而抽象方法必须在派生类中被实现。以下是一个具体的例子&#xff1a; abstract class Animal {name: string;constructor(name: string) {this.name name;}//…

C#中的Action

C#中的Action是一种委托类型&#xff0c;‌用于引用不返回值的方法。‌Action可以接受0到16个参数&#xff0c;‌并且不返回任何值。‌它是一种通用的委托类型&#xff0c;‌非常方便用于处理不同参数和不同函数签名的情况。‌Action的用法包括声明Action委托类型、‌创建Actio…

vue的三大核心知识点

响应式&#xff1a; 监听data属性getter setter(包括数组)模板编译&#xff1a; 模板到render函数再到vnodevdom&#xff1a; patch(elem, vnode)和patch(vnode, newVnode) vue组件初次渲染过程 解析模板为render函数&#xff08;或在开发环境已完成&#xff0c;vue-loader&a…

WIX Toolset 3.11 对本地化的支持方案

1.准备主题文件和本地化文件 WIX Toolset种主题文件为xml文件&#xff0c;负责配置控件的布局&#xff0c; 本地化文件为wxl文件&#xff0c;负责配置待加载的字符串&#xff0c;主题文件根据ID加载需要显示的文字内容。考虑到英文和中文字符长度大小不一&#xff0c;所以这里…

渗透测试——prime1靶场实战演练{常用工具}端口转发

文章目录 概要信息搜集 概要 靶机地址&#xff1a;https://www.vulnhub.com/entry/prime-1,358 信息搜集 nmap 扫网段存活ip及端口 找到除了网关外的ip&#xff0c;开放了80端口&#xff0c;登上去看看 是一个网站&#xff0c;直接上科技扫一扫目录 python dirsearch.py -u …

尝试带你理解 - 进程地址空间,写时拷贝

序言 在上一篇文章 进程概念以及进程状态&#xff0c;我们提到了 fork 函数&#xff0c;该函数可以帮我们创建一个子进程。在使用 fork 函数时&#xff0c;我们会发现一些奇怪的现象&#xff0c;举个栗子&#xff1a; 1 #include <stdio.h>2 #include <unistd.h>3 …

跟《经济学人》学英文:2024年07月20日这期 The Russell 2000 puts in a historic performance

Why investors have fallen in love with small American firms The Russell 2000 puts in a historic performance 罗素2000指数&#xff1a; 罗素2000指数&#xff08;英语&#xff1a;Russell 2000 Index&#xff09;为罗素3000指数中收录市值最小的2000家&#xff08;排序…

Linux 常用命令详解:从基础操作到进阶应用

Linux 常用命令详解&#xff1a;从基础操作到进阶应用 简介 Linux 是一个强大且灵活的操作系统&#xff0c;它在服务器、开发环境和个人计算机中得到了广泛的应用。Linux 的命令行界面提供了丰富的工具和命令&#xff0c;可以帮助用户高效地管理系统、处理文件、监控性能和进…

WebKit的暗黑魅力:全面拥抱Dark Mode

WebKit的暗黑魅力&#xff1a;全面拥抱Dark Mode 在当今数字时代&#xff0c;用户越来越注重个性化体验和视觉舒适度。暗黑模式&#xff08;Dark Mode&#xff09;作为一种新兴的界面风格&#xff0c;以其减轻视觉疲劳和节省电量的特点&#xff0c;迅速受到用户的青睐。WebKit…

学习笔记 韩顺平 零基础30天学会Java(2024.7.25)

P425 枚举类引出 举了一个例子&#xff0c;季节类创建对象&#xff0c;但是根据Java的规则&#xff0c;可以设置春夏秋冬以外的对象&#xff0c;而且可以修改&#xff0c;这样就会不符合实际&#xff0c;因此引出枚举 P426 自定义枚举类 1.构造器私有化&#xff0c;使外面没有办…