不再做了,最后一个版本,虽然还是很多问题,代码也很难看。
1.增加刷新按钮。
2.可选难度。
3.修复一些小bug。
4.增加界面友好性。
直接贴代码,代码中都有注释,而且扫雷都会玩,规则很简单。
Card.java
package version_6;
/**
* @author Chalmers
* 2015年12月26日 上午10:12:46
*/
public class Card {
//该方块附近雷的数目
public int count;
//该方块是否已经被翻开
public boolean flag;
}
MainFrame.java
package version_6;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
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 javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
/**
* @author Chalmers
* @version 创建时间:2015年12月24日 下午10:25:44
*/
/**
* 增加刷新按钮
*
*/
public class MainFrame extends JFrame {
JMenuBar menuBar = new JMenuBar();
JMenu level = new JMenu("难度选择");
JMenuItem easy = new JMenuItem("简单");
JMenuItem middle = new JMenuItem("中等");
JMenuItem harder = new JMenuItem("困难");
// 行
private int rowNum = 0;
// 列
private int colNum = 0;
// 面板宽度
public int width = 0;
// 面板高度
public int height = 0;
// 剩余的方块数目
private int remainCount = 0;
// 雷的数目
private int bomb = 10;
// 用来存放方块的信息
private Card[][] card = null;
// 因为方块附近最大雷的数目为8,所以设置雷为9
public static final int BOOM = 9;
// 附近没有雷
public static final int NONE = 0;
// 考虑最极端的情况,某个位置附近有8个雷
private String[] img = new String[] { "0.jpg", "1.jpg", "2.jpg", "3.jpg",
"4.jpg", "5.jpg", "6.jpg", "7.jpg", "8.jpg", "boom.jpg", "flag.png" };
private JPanel panel = null;
// 方块
private JLabel[][] label = null;
// 刷新按钮
private JButton refreshBt = null;
// 存放按钮的面板
private JPanel panelUp = null;
public MainFrame(int row, int col, int count) {
this.rowNum = row;
this.colNum = col;
this.bomb = count;
width = 42 * colNum;
height = 50 * rowNum;
remainCount = rowNum * colNum;
card = new Card[rowNum][colNum];
label = new JLabel[rowNum][colNum];
panel = new JPanel();
panelUp = new JPanel();
panelUp.setSize(340, 20);
panelUp.setBorder(BorderFactory.createLineBorder(Color.BLACK));
setJMenuBar(menuBar);
menuBar.add(level);
// add(level);
level.add(easy);
level.add(middle);
level.add(harder);
refreshBt = new JButton("刷新");
ClickListener cl = new ClickListener();
refreshBt.addActionListener(cl);
easy.addActionListener(cl);
middle.addActionListener(cl);
harder.addActionListener(cl);
initJLabel();
Toolkit tool = getToolkit();
Dimension dim = tool.getScreenSize();
// 横竖间隔为1,1
panel.setLayout(new GridLayout(rowNum, colNum, 1, 1));
panelUp.setLayout(new FlowLayout());
panelUp.add(refreshBt);
setLayout(new BorderLayout());
add(panel, BorderLayout.CENTER);
add(panelUp, BorderLayout.NORTH);
panel.setVisible(true);
setVisible(true);
// 设置在屏幕的位置和面板大小
setBounds((int) (dim.getWidth() - width) / 2,
(int) (dim.getHeight() - height) / 2, width, height);
setIconImage(new ImageIcon("img\\扫雷.jpg").getImage());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 设置为不可调整大小
setResizable(false);
setVisible(true);
}
private void initJLabel() {
initBoom();
for (int i = 0; i < rowNum; i++) {
for (int j = 0; j < colNum; j++) {
label[i][j] = new JLabel();
label[i][j].setBorder(BorderFactory
.createLineBorder(Color.BLACK));
// 点击事件
label[i][j].addMouseListener(new JLabelListener(i, j));
panel.add(label[i][j]);
}
}
}
// 初始化雷位置
private void initBoom() {
// 记录当前已随机生成雷的数目
int count = 0;
int row = 0;
int col = 0;
for (int i = 0; i < rowNum; i++) {
for (int j = 0; j < colNum; j++) {
card[i][j] = new Card();
card[i][j].count = 0;
card[i][j].flag = false;
}
}
while (count < bomb) {
do {
// 随机产生雷位置
row = (int) (Math.random() * rowNum);
col = (int) (Math.random() * colNum);
} while (card[row][col].count == BOOM); // 直到该位置没有雷位置
// 在该位置设置雷
card[row][col].count = BOOM;
count++;
}
// 初始化数值
for (int i = 0; i < rowNum; i++) {
for (int j = 0; j < colNum; j++) {
// 如果该处不是雷,则计算该处周围的雷的数目
if (!(card[i][j].count == BOOM)) {
count(i, j);
}
}
}
}
// 将每个位置的周围的雷的数据计算出来
private void count(int row, int col) {
int count = 0;
// 左上
if (row - 1 >= 0 && col - 1 >= 0) {
if (card[row - 1][col - 1].count == BOOM) {
count++;
}
}
// 上方
if (row - 1 >= 0) {
if (card[row - 1][col].count == BOOM) {
count++;
}
}
// 右上
if (row - 1 >= 0 && col + 1 < colNum) {
if (card[row - 1][col + 1].count == BOOM) {
count++;
}
}
// 左边
if (col - 1 >= 0) {
if (card[row][col - 1].count == BOOM) {
count++;
}
}
// 右边
if (col + 1 < colNum) {
if (card[row][col + 1].count == BOOM) {
count++;
}
}
// 左下
if (row + 1 < rowNum && col - 1 >= 0) {
if (card[row + 1][col - 1].count == BOOM) {
count++;
}
}
// 下边
if (row + 1 < rowNum) {
if (card[row + 1][col].count == BOOM) {
count++;
}
}
// 右下
if (row + 1 < rowNum && col + 1 < colNum) {
if (card[row + 1][col + 1].count == BOOM) {
count++;
}
}
// 将对应方块设置为计算后的数值
card[row][col].count = count;
}
private class JLabelListener extends MouseAdapter {
private int row = 0;
private int col = 0;
public JLabelListener(int row, int col) {
this.row = row;
this.col = col;
}
@Override
public void mouseClicked(MouseEvent e) {
/*
* 右键点击
*/
if (e.getButton() == 3 && card[row][col].flag == false) {
label[row][col].setIcon(new ImageIcon("img\\"
+ img[img.length - 1]));
return;
}
/*
* 左键点击
*/
// 如果不是雷,并且没有被点击过
if (!(card[row][col].count == BOOM) && card[row][col].flag == false) {
// 如果该位置附近雷数为0
if (card[row][col].count == NONE) {
// 进入递归
open(row, col);
} else {
// 否则打开
label[row][col].setIcon(new ImageIcon("img\\"
+ img[card[row][col].count]));
// 改变该位置方块状态
card[row][col].flag = true;
// 剩余方块-1
remainCount--;
// 如果剩余的方块和雷的数目一样,那么表示过关
if (remainCount == bomb) {
JOptionPane.showMessageDialog(null, "恭喜过关!");
return;
}
}
// 如果是雷
} else if (card[row][col].count == BOOM
&& card[row][col].flag == false) {
label[row][col].setIcon(new ImageIcon("img\\" + "over.jpg"));
card[row][col].flag = true;
// 提醒
JOptionPane.showMessageDialog(null, "游戏失败!!");
// 将所有的方块翻开
openAll();
}
}
// 递归翻牌
private void open(int row, int col) {
if (card[row][col].count == NONE && card[row][col].flag == false) {
label[row][col].setIcon(new ImageIcon("img\\"
+ img[card[row][col].count]));
// 改变方块状态,表示该方块已经被翻开
card[row][col].flag = true;
remainCount--;
// 左上
if (row - 1 >= 0 && col - 1 >= 0) {
open(row - 1, col - 1);
}
// 上方
if (row - 1 >= 0) {
open(row - 1, col);
}
// 右上
if (row - 1 >= 0 && col + 1 < colNum) {
open(row - 1, col + 1);
}
// 左边
if (col - 1 >= 0) {
open(row, col - 1);
}
// 右边
if (col + 1 < colNum) {
open(row, col + 1);
}
// 左下
if (row + 1 < rowNum && col - 1 >= 0) {
open(row + 1, col - 1);
}
// 下边
if (row + 1 < colNum) {
open(row + 1, col);
}
// 右下
if (row + 1 < rowNum && col + 1 < colNum) {
open(row + 1, col + 1);
}
} else {
if (card[row][col].flag == false) {
label[row][col].setIcon(new ImageIcon("img\\"
+ img[card[row][col].count]));
card[row][col].flag = true;
remainCount--;
}
return;
}
}
// 翻开所有的方块
private void openAll() {
for (int i = 0; i < rowNum; i++) {
for (int j = 0; j < colNum; j++) {
// 翻开雷牌
if (card[i][j].flag == false && card[i][j].count == 9) {
label[i][j].setIcon(new ImageIcon("img\\"
+ img[card[i][j].count]));
}
card[i][j].flag = true;
}
}
}
}
class ClickListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == easy) {
setVisible(false);
new MainFrame(9, 9, 9);
} else if (e.getSource() == middle) {
setVisible(false);
new MainFrame(16, 16, 40);
} else if (e.getSource() == harder) {
setVisible(false);
new MainFrame(16, 30, 99);
} else if (e.getSource() == refreshBt) {
// 将panel上的控件全部移除
panel.removeAll();
// 初始化
initJLabel();
// 刷新
repaint();
// 设置可见
setVisible(true);
}
}
}
public static void main(String[] args) {
new MainFrame(9, 9, 10);
}
}