diff --git a/src b/src new file mode 100644 index 0000000..afae743 --- /dev/null +++ b/src @@ -0,0 +1,308 @@ +package com.first; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Image; +import java.awt.Insets; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.UIManager; + +public class MineSweeper { + static private GamePanel gPanel;/* 雷区 */ + static private int midtime = 3600, mineNum = 0;/* 倒计时时间以及可用旗子数量 */ + static private JLabel label1, label2; + static CountDown cd; + + public MineSweeper() { + JFrame jf = new JFrame("扫雷小游戏"); + jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + jf.setLayout(null); + jf.setBounds(600, 200, 700, 800); + + label1 = new JLabel("剩余时间:" + formatTime(midtime)); + label1.setBounds(10, 20, 120, 20); + jf.add(label1); + + label2 = new JLabel("剩余旗子:" + mineNum); + label2.setBounds(400, 20, 240, 20); + jf.add(label2); + + JButton resetButt = new JButton("重置"); + resetButt.setMargin(new Insets(0, 0, 0, 0)); + resetButt.setBounds(230, 15, 60, 30); + resetButt.addActionListener(e -> { + jf.dispose(); + new MineSweeper(); + midtime = 3600; + }); + jf.add(resetButt); + + gPanel = new GamePanel(20, 20); + gPanel.setBounds(40, 100, 600, 600); + jf.add(gPanel); + + jf.setVisible(true); + } + + static class CountDown extends Thread { + @Override + public void run() { + super.run(); + while (midtime > 0) { + try { + --midtime; + label1.setText("剩余时间:" + formatTime(midtime)); + sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if (midtime == 0) { + JOptionPane.showMessageDialog(null, "时间已到", "游戏结束", JOptionPane.PLAIN_MESSAGE); + } + } + } + + private static String formatTime(int seconds) { + int hrs = seconds / 3600; + int mins = (seconds % 3600) / 60; + int secs = seconds % 60; + return String.format("%02d:%02d:%02d", hrs, mins, secs); + } + + public static void main(String[] args) { + new MineSweeper(); + cd = new CountDown(); + cd.start(); + } + + public static void setMineNum(int minesCount2) { + mineNum = minesCount2; + label2.setText("剩余旗子:" + mineNum); + } +} + +class GamePanel extends JPanel { + private int rows, cols, minesCount; + private final int BLOCKWIDTH = 30; + private final int BLOCKHEIGHT = 30; + private Buts[][] buts; + private JLabel[][] jlabel; + private boolean[][] state; + private int[][] click; + private ImageIcon mineIcon; + + public GamePanel(int row, int col) { + rows = row; + cols = col; + minesCount = rows * cols / 10; + MineSweeper.setMineNum(minesCount); + + + try { + mineIcon = new ImageIcon(ImageIO.read(new File("mine.png"))); + } catch (IOException e) { + e.printStackTrace(); + } + + // 缩放图标到合适大小 + Image scaledImage = mineIcon.getImage().getScaledInstance( + BLOCKWIDTH, BLOCKHEIGHT, Image.SCALE_SMOOTH); + mineIcon = new ImageIcon(scaledImage); + + buts = new Buts[rows][cols]; + jlabel = new JLabel[rows][cols]; + state = new boolean[rows][cols]; + click = new int[rows][cols]; + + setLayout(null); + initButtons(); + initLable(); + buryMines(); + writerNumber(); + } + + private void writerNumber() { + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + if (!state[i][j]) { + int numbers = 0; + for (int r = -1; r < 2; r++) { + for (int c = -1; c < 2; c++) { + if ((i + r > -1) && (i + r < cols) && (j + c > -1) && (j + c < rows)) { + if (state[i + r][j + c]) numbers++; + } + } + } + if (numbers > 0) { + click[i][j] = 2; + } + jlabel[i][j].setText(String.valueOf(numbers)); + jlabel[i][j].setIcon(null); // 确保数字位置不显示图标 + } + } + } + } + + private void initButtons() { + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + Buts but = new Buts(); + but.i = i; + but.j = j; + but.setBounds(BLOCKWIDTH * j, BLOCKHEIGHT * i, BLOCKWIDTH, BLOCKHEIGHT); + but.setMargin(new Insets(0, 0, 0, 0)); + + but.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.getButton() == MouseEvent.BUTTON1) { + openButtons(but); + } + if (e.getButton() == MouseEvent.BUTTON3) { + placeFlag(but); + } + } + }); + buts[i][j] = but; + this.add(buts[i][j]); + } + } + } + + protected void placeFlag(Buts but) { + if (click[but.i][but.j] != 3) { + buts[but.i][but.j].setText("旗"); + click[but.i][but.j] = 3; + minesCount--; + MineSweeper.setMineNum(minesCount); + } else { + buts[but.i][but.j].setText(""); + if (!state[but.i][but.j]) { + if (Integer.valueOf(jlabel[but.i][but.j].getText()) > 0) { + click[but.i][but.j] = 2; + } else { + click[but.i][but.j] = 0; + } + minesCount++; + MineSweeper.setMineNum(minesCount); + } else { + click[but.i][but.j] = 0; + } + } + if (minesCount == 0) { + boolean flag = true; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + if ((click[i][j] != 3) && state[i][j]) { + flag = false; + } + } + } + MineSweeper.cd.stop(); + JOptionPane.showMessageDialog(null, flag ? "您成功了" : "旗子已经用完", "游戏结束", JOptionPane.PLAIN_MESSAGE); + } + } + + protected void openButtons(Buts but) { + int i = but.i; + int j = but.j; + + if (state[i][j] && (click[i][j] != 3)) { + openAllCell(); + MineSweeper.cd.stop(); + JOptionPane.showMessageDialog(null, "您踩到地雷了", "游戏结束", JOptionPane.PLAIN_MESSAGE); + } + + if (click[i][j] == 2) { + buts[i][j].setVisible(false); + jlabel[i][j].setVisible(true); + } + + if ((click[i][j] == 0) || (click[i][j] == 1)) { + for (int r = -1; r < 2; r++) { + for (int c = -1; c < 2; c++) { + if ((i + r > -1) && (i + r < cols) && (j + c > -1) && (j + c < rows) + && (!state[i + r][j + c])) { + + if (click[i + r][j + c] == 0) { + buts[i + r][j + c].setVisible(false); + jlabel[i + r][j + c].setVisible(true); + click[i + r][j + c] = 1; + openButtons(buts[i + r][j + c]); + } + + if (click[i + r][j + c] == 2) { + buts[i + r][j + c].setVisible(false); + jlabel[i + r][j + c].setVisible(true); + } + } + } + } + } + } + + private void openAllCell() { + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + buts[i][j].setVisible(false); + jlabel[i][j].setVisible(true); + if (state[i][j]) { + jlabel[i][j].setIcon(mineIcon); + } + click[i][j] = 1; + } + } + } + + private void initLable() { + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + JLabel l = new JLabel("", JLabel.CENTER); + l.setBounds(j * BLOCKWIDTH, i * BLOCKHEIGHT, BLOCKWIDTH, BLOCKHEIGHT); + l.setBorder(BorderFactory.createLineBorder(Color.gray)); + l.setOpaque(true); + l.setBackground(Color.lightGray); + l.setHorizontalTextPosition(SwingConstants.CENTER); + l.setVerticalTextPosition(SwingConstants.CENTER); + this.add(l); + jlabel[i][j] = l; + l.setVisible(false); + } + } + } + + private void buryMines() { + for (int i = 0; i < minesCount; i++) { + int x = (int) (Math.random() * rows); + int y = (int) (Math.random() * cols); + if (!state[x][y]) { + state[x][y] = true; + jlabel[x][y].setIcon(mineIcon); + jlabel[x][y].setText(""); + } else { + i--; + } + } + } +} + +class Buts extends JButton { + public int i, j; +} \ No newline at end of file