虹姥 发表于 2025-6-7 09:48:05

基于Java语言的扫雷游戏设计开发

一、 游戏实现的主要功能

1、用户可以选择级别并且重新开始游戏;
2、具有计时功能,即显示用户完成所有扫雷任务所使用的时间;
3、可显示剩余雷数,当用户插旗后雷数减1;
4、左键点击打开空格,右键点击插旗,左右键双击翻开周围未插旗的空格;
5、当找出全部的雷后,提示游戏结束。
二、游戏设计与实现

1 扫雷游戏界面设计

系统的整体布局为:空布局,采用了菜单、按钮、面板、标签等组件,菜单主要包括开始游戏、选择级别、退出等选项;按钮包括雷区按钮、笑脸按钮、数字按钮等,面板是标签的容器包括雷的数量、时间等信息。
package com.game.mine;

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

/**
* 功能:游戏窗口
*/
public class GameFrame extends JFrame implements ActionListener
{
        private GamePanel panel;
        JMenuItem JEasy, JNormal, JHigh;
        public GameFrame()
        {
                try
                {
                        //窗口
                        this.setTitle("扫雷");
                        this.setLayout(null);
                        this.setBackground(Color.WHITE);
                        this.setResizable(false);
                        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                        //菜单
                        JMenuBar JMine = new JMenuBar();
                        JMenu JGame = new JMenu("游戏");
                        JGame.setFont(new Font("宋体",Font.PLAIN,14));
                        JMenuItem JNew = JGame.add("   开始");
                        JNew.setFont(new Font("宋体",Font.PLAIN,14));
                        JNew.addActionListener(this);
                        JNew.setActionCommand("new");
                        JGame.addSeparator();
                        this.JEasy = JGame.add("√ 初级");
                        this.JEasy.setFont(new Font("宋体",Font.PLAIN,14));
                        this.JEasy.addActionListener(this);
                        this.JEasy.setActionCommand("easy");
                        this.JNormal = JGame.add("   中级");
                        this.JNormal.setFont(new Font("宋体",Font.PLAIN,14));
                        this.JNormal.addActionListener(this);
                        this.JNormal.setActionCommand("normal");
                        this.JHigh = JGame.add("   高级");
                        this.JHigh.setFont(new Font("宋体",Font.PLAIN,14));
                        this.JHigh.addActionListener(this);
                        this.JHigh.setActionCommand("hard");
                        JGame.addSeparator();
                        JMenuItem JExit = JGame.add("   退出");
                        JExit.setFont(new Font("宋体",Font.PLAIN,14));
                        JExit.addActionListener(this);
                        JExit.setActionCommand("exit");
                        JMine.add(JGame);
                        JMenu JHelp = new JMenu("帮助");
                        JHelp.setFont(new Font("宋体",Font.PLAIN,14));
                        JMenuItem JAbout = JHelp.add("关于");
                        JAbout.setFont(new Font("宋体",Font.PLAIN,14));
                        JAbout.addActionListener(this);
                        JAbout.setActionCommand("about");
                        JMine.add(JHelp);
                        this.setJMenuBar(JMine);
                        //面板
                        this.panel = new GamePanel();
                        this.add(this.panel);
                        //显示
                        this.panel.setLevel(this.panel.EASY);
                        this.setSize(this.panel.getWidth() + 15,this.panel.getHeight() + 60);
                        this.setLocationRelativeTo(null);
                        this.setVisible(true);
                }
                catch(Exception e)
                {
                        JOptionPane.showMessageDialog(this,"程序出现异常错误,即将退出!\r\n\r\n"+ e,
                                        "提示",JOptionPane.ERROR_MESSAGE);
                        System.exit(0);
                }
        }

        @Override
        public void actionPerformed(ActionEvent e)
        {
                String command = e.getActionCommand();
                if("new".equals(command))
                {
                        this.panel.newGame();
                }
                else if("easy".equals(command))
                {
                        this.JEasy.setText("√ 初级");
                        this.JNormal.setText("   中级");
                        this.JHigh.setText("   高级");
                        this.panel.setLevel(this.panel.EASY);
                        this.setSize(this.panel.getWidth() + 15,this.panel.getHeight() + 60);
                        this.setLocationRelativeTo(null);
                }
                else if("normal".equals(command))
                {
                        this.JEasy.setText("   初级");
                        this.JNormal.setText("√ 中级");
                        this.JHigh.setText("   高级");
                        this.panel.setLevel(this.panel.NORMAL);
                        this.setSize(this.panel.getWidth() + 15,this.panel.getHeight() + 60);
                        this.setLocationRelativeTo(null);
                }
                else if("hard".equals(command))
                {
                        this.JEasy.setText("   初级");
                        this.JNormal.setText("   中级");
                        this.JHigh.setText("√ 高级");
                        this.panel.setLevel(this.panel.HARD);
                        this.setSize(this.panel.getWidth() + 15,this.panel.getHeight() + 60);
                        this.setLocationRelativeTo(null);
                }
                else if("exit".equals(command))
                {
                        System.exit(0);
                }
                else if("about".equals(command))
                {
                        JOptionPane.showMessageDialog(this,
                                        "1、左键用于打开安全的格子,推进游戏进度;右键用于标记地雷,以辅助判断,或为接下来的双击做准备;\n" +
                                                        "双击在一个数字周围的地雷标记完时,相当于对数字周围未打开的方块均进行一次左键单击操作:\n" +
                                                        "2、左键单击:在判断出不是雷的方块上按下左键,可以打开该方块。如果方块上出现数字,则该数字表示\n" +
                                                        "其周围3×3区域中的地雷数(一般为8个格子,对于边块为5个格子,对于角块为3个格子。所以扫雷中最大\n" +
                                                        "的数字为8);如果方块上为空(相当于0),则可以递归地打开与空相邻的方块;如果踩雷,则游戏结束。\n" +
                                                        "3、右键单击:在判断为地雷的方块上按下右键,可以标记地雷(显示为小红旗)。重复一次或两次操作可\n" +
                                                        "标记?或取消标记。\n" +
                                                        "4、双击:同时按下左键和右键完成双击。当双击位置周围已标记雷数等于该位置数字时操作有效,相当于\n" +
                                                        "对该数字周围未打开的方块均进行一次左键单击操作。地雷未标记完全时使用双击无效。若数字周围有标错\n" +
                                                        "的地雷,则游戏结束,标错的地雷上会显示一个判断错误标志。","提示",JOptionPane.INFORMATION_MESSAGE);
                }
        }

}2 雷区的设计

GamePanel类是JPanel容器的子类,实现了ActionListener和MouseListener接口所创建的对象:GamePanel()构造方法是GamePanel类中最重要的成员之一。其中GamePanel类的主要方法如下:
(1)initGame()方法可根据参数提供的数据设置雷区的宽度、高度、雷的数目以及计时器置零、初始化游戏界面。
(2)loadImage()方法加载数字图片、空格图片、雷图片、小红旗图片以及各种需要的图片。
(3)setLevel(int level)方法根据传入的参数根据不同的游戏难度重新设置主面板尺寸、重新设置组件位置、重新设置雷数、重新放置地雷位置以及时间清零等。
(4)newGame()方法调用initGame()方法初始化界面然后开始新游戏。
(5)actionPerformed(ActionEvent e)是GamePanel类实现的ActionListener接口中的方法。当用户单击雷区中的中的某个方块时,游戏开始定时器开始计时,单击笑脸按钮初始游戏界面开始新游戏。
(6)mousePressed(MouseEvent e)方法是GamePanel类实现的MouseListener接口中的方法,当用户按下鼠标时如果游戏结束退出游戏,如果游戏未开始,开始新游戏。
(7)mouseReleased(MouseEvent e)方法是GamePanel类实现的MouseListener
接口中的方法,分别定义了鼠标左键或右键后程序所执行的动作。
(8)GamePanel()构造方法对面板,雷区组件以及游戏难度等进行初始化。
package com.game.mine;import java.awt.*;import java.util.Map;import java.util.HashMap;import java.awt.event.*;import javax.swing.*;/** * 功能:游戏面板
*/public class GamePanel extends JPanel implements MouseListener,ActionListener{        private final GameLogic logic;        /** 初级难度(9×9,10个地雷) */        final int EASY = 1;        /** 中级难度(16×16,40个地雷) */        final int NORMAL = 2;        /** 高级难度(30×16,99个地雷) */        final int HARD = 3;        /** 上次游戏难度 */        private int oldLevel = -1;        /** 网格行数 */        int gridRows;        /** 网格列数 */        int gridColumns;        /** 网格尺寸 */        final int gridSize = 30;        /** 地雷数 */        int mineNum;        /** 提示区面板 */        private final JPanel panelTip = new JPanel();        /** 地雷区面板 */        private final JPanel panelMine = new JPanel();        /** 笑脸按钮 */        private final JButton buttonFace = new JButton();        /** 地雷数提示标签 */        JLabel[] labelMineTip = new JLabel;        /** 时间提示标签 */        JLabel[] labelTimeTip = new JLabel;        /** 地雷按钮数组 */        JButton[][] buttonMine = new JButton;        /**       * 地雷信息数组       * number->地雷数:-1-地雷,0到8-周围地雷数       * flag->地雷状态:0-未打开,1-已打开,2-插小旗,3-插问号       */        @SuppressWarnings("unchecked")        //数组不支持泛型        Map[][] mapMine = new Map;        /** 笑脸图片 */        private final ImageIcon[] imageIconFace = new ImageIcon;        /** 时间、雷数提示图片 */        ImageIcon[] imageIconNumberTip = new ImageIcon;        /** 数字图片 */        ImageIcon[] imageIconNumber = new ImageIcon;        /** 空白图片 */        ImageIcon imageIconBlank = new ImageIcon("res/resource/mine/blank.gif");        /** 方格图片 */        ImageIcon imageIconCell = new ImageIcon("res/resource/mine/cell.gif");        /** 红旗图片 */        ImageIcon imageIconFlag = new ImageIcon("res/resource/mine/flag.gif");        /** 问号图片 */        ImageIcon imageIconQuestion = new ImageIcon("res/resource/mine/question.gif");        /** 地雷图片 */        ImageIcon imageIconMine = new ImageIcon("res/resource/mine/mine.gif");        /** 爆炸图片 */        ImageIcon imageIconBomb = new ImageIcon("res/resource/mine/bomb.gif");        /** 找雷错误图片 */        ImageIcon imageIconWrongMine = new ImageIcon("res/resource/mine/wrong mine.gif");        /** 时间提示数字 */        int timeTip = 0;        /** 扫雷提示数字 */        int mineTip = 0;        /** 计时器 */        Timer timer = new Timer(1000,this);        /** 游戏是否开始(true-开始,false-未开始) */        boolean isStart = false;        /** 游戏是否结束(true-结束,false-未结束) */        boolean isGameOver = true;        public GamePanel()        {                //主面板初始化                this.setBackground(Color.LIGHT_GRAY);                this.setBorder(BorderFactory.createRaisedBevelBorder());    //边框凸起                this.setLayout(null);   //自由布局                //提示区面板初始化                this.panelTip.setBackground(Color.LIGHT_GRAY);                this.panelTip.setBorder(BorderFactory.createLoweredBevelBorder());//边框下凹                this.panelTip.setLayout(null);                this.add(this.panelTip);                                //地雷区面板初始化                this.panelMine.setBackground(Color.LIGHT_GRAY);                this.panelMine.setBorder(BorderFactory.createLoweredBevelBorder());   //边框下凹                this.add(this.panelMine);                                //地雷数提示标签初始化                for(int i=0;i
页: [1]
查看完整版本: 基于Java语言的扫雷游戏设计开发