用Java开发一个扫雷游戏

news2024/11/25 1:47:12

以下是用Java开发一个扫雷游戏的基本步骤:

  1. 创建一个窗口和画布,用来显示游戏界面。

  2. 创建一个游戏逻辑类,包含一些基本的操作,如生成地雷、计算周围地雷数量、打开方格等。

  3. 在画布上绘制游戏界面,包括格子、数字、地雷等。

  4. 给格子添加鼠标事件,实现左键点击打开方格、右键点击插上旗子等操作。

  5. 实现游戏的胜利和失败判定,包括所有非地雷方格都被打开、点中地雷等。

效果如下:

以下是一个简单的代码示例:

import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;

public class MineSweeper extends JPanel {
    private int[][] grid;
    private boolean[][] reveal;
    private int numMines;
    private int gridSize;
    private final int BLOCK_SIZE = 30;
    private final int MARGIN = 20;

    public MineSweeper(int gridSize, int numMines) {
        this.gridSize = gridSize;
        this.numMines = numMines;
        grid = new int[gridSize][gridSize];
        reveal = new boolean[gridSize][gridSize];
        setPreferredSize(new Dimension(gridSize * BLOCK_SIZE + MARGIN * 2, gridSize * BLOCK_SIZE + MARGIN * 2));
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                handleClick(e.getX(), e.getY(), e.getButton());
            }
        });
        generateGrid();
    }

    private void generateGrid() {
        Random rnd = new Random();
        int count = 0;
        while (count < numMines) {
            int x = rnd.nextInt(gridSize);
            int y = rnd.nextInt(gridSize);
            if (grid[x][y] != -1) {
                grid[x][y] = -1;
                count++;
            }
        }
        for (int i = 0; i < gridSize; i++) {
            for (int j = 0; j < gridSize; j++) {
                if (grid[i][j] != -1) {
                    int countMines = 0;
                    for (int x = Math.max(i - 1, 0); x <= Math.min(i + 1, gridSize - 1); x++) {
                        for (int y = Math.max(j - 1, 0); y <= Math.min(j + 1, gridSize - 1); y++) {
                            if (grid[x][y] == -1) {
                                countMines++;
                            }
                        }
                    }
                    grid[i][j] = countMines;
                }
            }
        }
    }

    private void handleClick(int x, int y, int button) {
        if (x < MARGIN || x >= MARGIN + gridSize * BLOCK_SIZE || y < MARGIN || y >= MARGIN + gridSize * BLOCK_SIZE) {
            return;
        }
        int i = (x - MARGIN) / BLOCK_SIZE;
        int j = (y - MARGIN) / BLOCK_SIZE;
        if (button == MouseEvent.BUTTON1) {
            if (reveal[i][j]) {
                return;
            }
            reveal[i][j] = true;
            if (grid[i][j] == -1) {
                JOptionPane.showMessageDialog(this, "You click a mine! Try again!");
                generateGrid();
            } else if (grid[i][j] == 0) {
                for (int x1 = Math.max(i - 1, 0); x1 <= Math.min(i + 1, gridSize - 1); x1++) {
                    for (int y1 = Math.max(j - 1, 0); y1 <= Math.min(j + 1, gridSize - 1); y1++) {
                        if (!reveal[x1][y1]) {
                            handleClick(MARGIN + x1 * BLOCK_SIZE + BLOCK_SIZE / 2, MARGIN + y1 * BLOCK_SIZE + BLOCK_SIZE / 2, MouseEvent.BUTTON1);
                        }
                    }
                }
            }
        } else if (button == MouseEvent.BUTTON3) {
            reveal[i][j] = !reveal[i][j];
        }
        repaint();
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.BLACK);
        g.fillRect(MARGIN, MARGIN, gridSize * BLOCK_SIZE, gridSize * BLOCK_SIZE);
        for (int i = 0; i < gridSize; i++) {
            for (int j = 0; j < gridSize; j++) {
                if (reveal[i][j]) {
                    g.setColor(Color.WHITE);
                    g.fillRect(MARGIN + i * BLOCK_SIZE, MARGIN + j * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
                    if (grid[i][j] == -1) {
                        g.setColor(Color.RED);
                        g.fillRect(MARGIN + i * BLOCK_SIZE, MARGIN + j * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
                    } else if (grid[i][j] > 0) {
                        g.setColor(Color.BLUE);
                        g.setFont(new Font("Arial", Font.BOLD, BLOCK_SIZE / 2));
                        g.drawString("" + grid[i][j], MARGIN + i * BLOCK_SIZE + BLOCK_SIZE / 4, MARGIN + j * BLOCK_SIZE + BLOCK_SIZE / 2);
                    }
                } else {
                    g.setColor(Color.GRAY);
                    g.fillRect(MARGIN + i * BLOCK_SIZE, MARGIN + j * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
                    if (reveal[i][j]) {
                        g.setColor(Color.WHITE);
                        g.fillRect(MARGIN + i * BLOCK_SIZE, MARGIN + j * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
                    } else {
                        g.setColor(Color.BLACK);
                        g.drawRect(MARGIN + i * BLOCK_SIZE, MARGIN + j * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("Mine Sweeper");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.add(new MineSweeper(10, 10));
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

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

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

相关文章

华为ensp:边缘端口并启动BUDU保护

如上图前提是三个交换机都做了rstp&#xff0c;则在边缘的地方做 边缘端口并启动BUDU保护&#xff0c;也就是我用绿色圈出来的地方 边缘1 进入交换机的系统视图 interface e0/0/3 进入接口 stp edged-port enable quit 再退回系统视图 stp bpdu-protection 这样就可以了…

前端工具nvm实现node自由

node的自由之路 前言 大家使用vue框架开发的朋友可能会遇到首次运行公司项目环境的时候&#xff0c;会出现使用npm install命令安装依赖包的时候出现各种各样的问题&#xff0c;其中很重要的一个错误原因就是因为你的nodejs版本和当时搭建环境的版本不一致造成的。今天就来给…

C语言精华题目锦集1

第一题 test.c文件中包括如下语句&#xff0c;文件中定义的四个变量中&#xff0c;是指针类型的是&#xff08;&#xff09;【多选】 #define INT_PTR int* typedef int* intptr; INT_PRT a,b; int_ptr c,d;A:a  B:b  C:c  D:d #define是宏定义&#xff0c;此时在程序中IN…

软考网络工程师知识点总结(四)

目录 61、FTP文件传输服务 62、DHCP动态主机配置协议 63、电子邮件服务 64、各种新技术相关概念及功能的考查 65、Windows的ipconfig命令 66、Windows的其它命令及说明 67、Linux系统关机和重启命令 68、Linux系统文件属性命令 69、SNMP协议版本 70、SNMP协议的报文类…

移远EC600U-CN开发板 day04

控件探索-滑杆&#xff08;lv.slider&#xff09; 1. 显示一个简单的滑杆 def slider_event_cb(evt): slider evt.get_target()# 修改label的值label.set_text(str(slider.get_value()))slider lv.slider(scr) #创建滑杆组件 slider.set_width(200) #设置滑杆宽…

OpenCV 实现透视变换

一&#xff1a;OpenCV透视变换的概念 仿射变换(affine transform)与透视变换(perspective transform)在图像还原、图像局部变化处理方面有重要意义。通常&#xff0c;在2D平面中&#xff0c;仿射变换的应用较多&#xff0c;而在3D平面中&#xff0c;透视变换又有了自己的一席之…

华视电子驱动安装

1、安装驱动 下载地址&#xff1a;http://ws.it0355.com/a/202101/07/a27013.htm 双击exe文件安装驱动&#xff1a; 检查驱动运行正常&#xff1a; http://www.winwin7.com/soft/xtbd-12727.html vc库安装

https:/myproject.git did not send all necessary objects

事情是由于在git push 的时候&#xff0c;电脑突然蓝屏了&#xff0c;再打开电脑的时候&#xff0c;git pull git push都失效了&#xff0c; 粗暴的解决方式是重新在拉取代码&#xff0c;可以暂时解决&#xff0c;但是考虑到可能以后还会遇到这个问题&#xff0c;所以在不紧急…

取暖器/暖风机上架 亚马逊美国站UL1278测试标准要求

美国是一个对安全要求非常严格的国家&#xff0c;美国本土的所有电子产品生产企业早在很多年前就要求有相关检测。而随着亚马逊在全球商业的战略地位不断提高&#xff0c;境外的电子设备通过亚马逊不断涌入美国市场。“为保证消费者得安全&#xff0c;亚马逊始终强调带电得产品…

Perl爬虫程序的框架

Perl爬虫程序的框架&#xff0c;这个框架可以用来爬取任何网页的内容。 perl #!/usr/bin/perl use strict; use warnings; use LWP::UserAgent; use HTML::TreeBuilder; # 创建LWP::UserAgent对象 my $ua LWP::UserAgent->new; # 设置代理信息 $ua->proxy(http, ); …

【python自动化】Playwright基础教程(九)-悬浮元素定位自定义ID定位组合定位断言

【python自动化】Playwright基础教程&#xff08;九&#xff09;-悬浮元素定位&自定义ID定位&组合定位&断言 本文目录 文章目录 【python自动化】Playwright基础教程&#xff08;九&#xff09;-悬浮元素定位&自定义ID定位&组合定位&断言playwright系…

Egg.js 中 Service 的使用

Service 服务 Service是用来编写和数据库直接交互的业务逻辑代码。Service就是在复杂业务场景下用于做业务逻辑封装的一个抽象层。 简单来说&#xff0c;就是把业务逻辑代码进一步细化和分类&#xff0c;所以和数据库交互的代码都放到Service中。这样作有三个明显的好处。 保…

学会这10个Fluent仿真优化技巧,效率蹭蹭蹭

ANSYS Fluent 是计算流体动力学 (CFD) 仿真的强大工具&#xff0c;使工程师和科学家能够分析和预测各种应用中的流体行为。然而&#xff0c;运行模拟可能需要大量计算&#xff0c;因此优化设置对于在最短的时间内获得最准确的结果非常重要。 Fluent对电脑配置要求高&#xff1f…

server2008、2016远程桌面授权的激活方法

远程桌面服务安装好之后使用的是120天临时授权&#xff0c;所以会跳出以下提示&#xff0c;我们介绍远程桌面授权的激活。 现在我们使用命令 mstsc /admin 强制登录服务器 需要在“远程桌面服务”--安装“远程桌面授权”--默认安装 “计算机”单击右键“管理”--“角色” 默认…

css实现鼠标悬停时元素的显示与隐藏

css实现鼠标悬停时元素的显示与隐藏 跟着B站黑马学习小兔鲜项目&#xff0c;有个点记录一下 就是当鼠标悬浮在商品列表上时&#xff0c;列表中的商品会显示出来&#xff0c;离开时&#xff0c;商品隐藏&#xff0c;如下&#xff1a; 感觉这个功能经常会遇到&#xff0c;但一直…

浅析网络协议-HTTP协议

1.HTTP简介 HTTP协议是Hyper Text Transfer Protocol&#xff08;超文本传输协议&#xff09;的缩写,是用于从万维网&#xff08;WWW:World Wide Web &#xff09;服务器传输超文本到本地浏览器的传送协议。 HTTP是一个基于TCP/IP通信协议来传递数据&#xff08;HTML 文件, 图…

微信动态表情包怎么做?微信动态表情包做法

在使用手机微信聊天时经常会使用各种各样的动态表情包来增加聊天的欢乐气氛。这种动态的表情包要比静态的表情画面更丰富。那么&#xff0c;如何制作表情包呢&#xff1f;很简单&#xff0c;通过使用在线制作动画&#xff08;https://www.gif.cn/&#xff09;工具-GIF中文网&am…

Illumination Adaptive Transformer

Abstract. 现实世界中具有挑战性的照明条件&#xff08;低光、曝光不足和曝光过度&#xff09;不仅会产生令人不快的视觉外观&#xff0c;还会影响计算机视觉任务。现有的光自适应方法通常单独处理每种情况。更重要的是&#xff0c;它们中的大多数经常在 RAW 图像上运行或过度…

arcgis--NoData数据处理

方法一&#xff1a;利用【栅格计算器】可以对NoData的值进行修改。【Spatial Analyst工具】-【地图代数】-【栅格计算器】&#xff0c;将NoData修改为某一个值。 方法二&#xff1a;先对原始数据进行重分类&#xff0c;分成1类&#xff0c;将NoData赋值为2,。然后&#xff0c;将…

USB拦截工具

USB 闪存驱动器对组织的安全和数据构成了独特的威胁。它们的便携性和充足的存储容量使它们成为数据盗窃的便捷媒介。 什么是 USB 拦截器 USB&#xff08;通用串行总线&#xff09;阻止程序用于禁用插入可移动存储设备的端口&#xff0c;便携性和充足的存储容量使 USB 成为可能…