目录
1、前言
2、效果展示
3、代码
3.1 Main
3.2 MineJFrame 主界面和菜单
3.3 GridJLabel 数字和炸弹方格实现
3.4 BasicGridButton 基本方格的点击事件的监听相关逻辑判断
3.5 笑脸按钮和计数计时功能实现
3.6 Win 弹出获胜窗口
3.7 DataClass 数据类
4、图片资源在github上。
去年土木大四寒假时,不想做毕设,学Java玩,很想做一个小游戏,但那时Java基础语法都还没学完,就找了个简单的来做,网上找了找,刚好找到了扫雷的图片资源,就做了个全图片的扫雷。菜得要命。还有本人英语一言难尽。虽然这注释少,我一年后(现在)还是看的懂,就不在添加注释了。有问题可以加讨论吹水群:332566785,也可以发邮件[email protected]。
中级模式
高级模式
胜利
失败
public class Main {
public static void main(String[] args)
{
new MineJFrame();
}
}
import javax.swing.*;
import java.awt.*;
public class MineJFrame extends JFrame {
ImageIcon icon = new ImageIcon("image/icon.gif");
Image imageIcon = icon.getImage();
DataClass dataClass = new DataClass();
FaceJLabel faceJLabel = new FaceJLabel(this);
GridJLabel gridJLabel = new GridJLabel(faceJLabel);
public MineJFrame() {
setFrame();
mineMenu();
initframe();
setVisible(true);
}
/*
* 加载GridJPanel,设置JFrame尺寸
*/
public void initframe(){
//dataClass.reStart();
add(faceJLabel);
add(gridJLabel);
setMinimumSize(new Dimension(DataClass.getMineRow()*16+16, DataClass.getMineRand()*16+104));
repaint();
pack();
}
/*
* 重置
*/
public void reStart(){
dataClass.reStart();
remove(gridJLabel);
gridJLabel = new GridJLabel(faceJLabel);
add(gridJLabel);
faceJLabel.reSet();
}
/*
*实现菜单
*/
protected void mineMenu(){
JMenuBar menuBar=new JMenuBar();
JMenu menu = new JMenu("菜单");
menu.setMargin(new Insets(0,0,0,0));//设置字边距;
menu.addSeparator();//添加分割线;
JMenu difficulty = new JMenu("难度");
JMenuItem primary = new JMenuItem("初级");
JMenuItem intermediate = new JMenuItem("中级");
JMenuItem senior = new JMenuItem("高级");
difficulty.addSeparator();//添加分割线;
JMenu cheat = new JMenu("作弊模式");
JMenuItem cheatOpen = new JMenuItem("开");
JMenuItem cheatClose = new JMenuItem("关");
primary.addActionListener(e -> {
DataClass.setMineGrid(9,9,10);
initframe();
reStart();
revalidate();
});
intermediate.addActionListener(e -> {
DataClass.setMineGrid(16,16,40);
initframe();
reStart();
validate();
});
senior.addActionListener(e -> {
DataClass.setMineGrid(32,16,99);
initframe();
reStart();
validate();
});
cheatOpen.addActionListener(e -> {
DataClass.isCheat=true;
initframe();
reStart();
validate();
});
cheatClose.addActionListener(e -> {
DataClass.isCheat=false;
initframe();
reStart();
validate();
});
difficulty.add(primary);
difficulty.add(intermediate);
difficulty.add(senior);
cheat.add(cheatOpen);
cheat.add(cheatClose);
menu.add(difficulty);
menu.add(cheat);
menuBar.add(menu);
setJMenuBar(menuBar);
}
public void setFrame(){
setTitle("扫雷");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setIconImage(imageIcon);
getContentPane().setBackground(new Color(191, 191, 191, 255));
setResizable(false);
setLocationRelativeTo(null);
validate();
}
}
随机生成炸弹格,通过递归计算九宫格内炸弹个数。
import javax.swing.*;
import java.awt.*;
import java.util.Random;
public class GridJLabel extends JLabel {
//二维数组,按钮的X,Y
public BasicGridButton[][] mineGrid = new BasicGridButton[DataClass.getMineRow()][DataClass.getMineRand()];
public boolean[][] mineLocation = new boolean[DataClass.getMineRow()][DataClass.getMineRand()];
//用随机数生成含有炸弹的按钮的X,Y
{
for(int i = 0; i< DataClass.getMineNums(); i++){
Random row = new Random();
int m = row.nextInt(DataClass.getMineRow());
int n = row.nextInt(DataClass.getMineRand());
if(i==0&&m
鼠标左键和鼠标右键不同点击次数的判顶。
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class BasicGridButton extends JButton {
int m;
int n;
boolean isMine =true;
GridJLabel gridJLabel;
public BasicGridButton(){
initButton();
}
public BasicGridButton(GridJLabel gridJLabel,int m,int n){
this();
this.gridJLabel = gridJLabel;
this.m=m;
this.n=n;
}
public void initButton(){
setLayout(null);
setSize(16, 16);
this.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3&& !DataClass.isBomb[m][n]&&!DataClass.gameEnd&&!DataClass.isWin) {
DataClass.i[m][n] += 1;
if (DataClass.i[m][n]%3==1) DataClass.flagNumber++;
else if(DataClass.i[m][n]%3==2)DataClass.flagNumber--;
}
if (e.getButton() == MouseEvent.BUTTON1&& DataClass.i[m][n]%3!=1&&!DataClass.gameEnd&&!DataClass.isWin){
if(gridJLabel.mineLocation[m][n]){
DataClass.isBomb[m][n]=true;
DataClass.gameEnd=true;
} else if (!DataClass.numberDowm[m][n]){
blankSpace(m,n);
winner();
}
}
if (!DataClass.isStart){
DataClass.isStart=true;
}
gridJLabel.reset();
gridJLabel.validate();
}
});
}
public void isCheat(){
if(isMine && DataClass.isCheat) setIcon(new ImageIcon("image/hole.gif"));//开启作弊模式
else setIcon(new ImageIcon(DataClass.mineGridIcon[DataClass.i[m][n]%3]));
}
public void bomb(){
if(DataClass.gameEnd&& isMine) {
if (DataClass.isBomb[m][n]) {
setIcon(new ImageIcon(Toolkit.getDefaultToolkit().getImage("image/mine2.gif")));
} else {
setIcon(new ImageIcon("image/mine.gif"));
}
}
}
public void number(int i){
if (DataClass.numberDowm[m][n])setIcon(new ImageIcon(DataClass.numberIcon[i]));
}
public void blankSpace(int m,int n){
if (gridJLabel.mineLocation[m][n]) return;
if (gridJLabel.countNumber[m][n]>0){
DataClass.numberDowm[m][n]=true;
DataClass.count++;
return;
}
if (gridJLabel.countNumber[m][n]==0){
if (DataClass.numberDowm[m][n]){
for (int p = -1;p+m
这里感觉用多线程要好点,但当时偷懒不想用。
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class FaceJLabel extends JLabel {
MineJFrame mineJFrame;
public FaceJLabel(){
init();
setVisible(true);
}
public FaceJLabel(MineJFrame mineJFrame){
this();
this.mineJFrame=mineJFrame;
}
public void init(){
setLayout(null);
setBackground(new Color(191, 191, 191, 82));
setLocation(2,2);
setSize(DataClass.getMineRow()*16+12, 36);
flagJLabel();
countTime();
timeJLabel();
faceButton();
setVisible(true);
}
public void reSet(){
removeAll();
init();
revalidate();
this.repaint();
}
public void faceButton(){
int x=DataClass.getMineRow()*16+12;
JButton face = new JButton();
face.setIcon(new ImageIcon("image/face0.gif"));
if (DataClass.gameEnd)face.setIcon(new ImageIcon("image/face3.gif"));
else if (DataClass.isWin)face.setIcon(new ImageIcon("image/face4.gif"));
face.setSize(26, 26);
face.setLayout(null);
face.setLocation((x-46)/2, 5);
face.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if(e.getButton()==MouseEvent.BUTTON1) {
mineJFrame.initframe();
mineJFrame.reStart();
mineJFrame.revalidate();
repaint();
}
}
});
this.add(face);
}
public void flagJLabel(){
int i=DataClass.getMineNums()-DataClass.flagNumber;
int i1=0,i2,i3;
if (i<0){
i=-i;
i1=10;
} else if(i>98) {
i=99;
}
i3=i%10;
i2=(i-i3)/10;
JLabel f100= new JLabel();
f100.setLayout(null);
f100.setLocation(2,7);
f100.setSize(13,23);
f100.setIcon(new ImageIcon(DataClass.timeAndFlagNumberIcon[i1]));
f100.setVisible(true);
add(f100);
JLabel f010= new JLabel();
f010.setLayout(null);
f010.setLocation(15,7);
f010.setSize(13,23);
f010.setIcon(new ImageIcon(DataClass.timeAndFlagNumberIcon[i2]));
f010.setVisible(true);
add(f010);
JLabel f001= new JLabel();
f001.setLayout(null);
f001.setLocation(28,7);
f001.setSize(13,23);
f001.setIcon(new ImageIcon(DataClass.timeAndFlagNumberIcon[i3]));
f001.setVisible(true);
add(f001);
}
public void countTime(){
if (DataClass.isStart&&!DataClass.isCount){
DataClass.isCount=true;
TimerTask addCountTime = new TimerTask() {
@Override
public void run() {
if (DataClass.isWin||DataClass.gameEnd||!DataClass.isStart)cancel();
else if (DataClass.countTime<999){
DataClass.countTime++;
}
else {
DataClass.countTime=999;
cancel();
}
reSet();
updateUI();
}
};
java.util.Timer timer = new Timer();
timer.schedule(addCountTime,new Date(),1000L);
}
}
public void timeJLabel(){
int x=DataClass.getMineRow()*16+12;
int i001=DataClass.countTime%10;
int i010=(DataClass.countTime%100-i001)/10;
int i100=(DataClass.countTime-DataClass.countTime%100)/100;
JLabel t100= new JLabel();
t100.setLayout(null);
t100.setLocation(x-30,7);
t100.setSize(13,23);
t100.setIcon(new ImageIcon(DataClass.timeAndFlagNumberIcon[i001]));
t100.setVisible(true);
add(t100);
JLabel t010= new JLabel();
t010.setLayout(null);
t010.setLocation(x-43,7);
t010.setSize(13,23);
t010.setIcon(new ImageIcon(DataClass.timeAndFlagNumberIcon[i010]));
t010.setVisible(true);
add(t010);
JLabel t001= new JLabel();
t001.setLayout(null);
t001.setLocation(x-56,7);
t001.setSize(13,23);
t001.setIcon(new ImageIcon(DataClass.timeAndFlagNumberIcon[i100]));
t001.setVisible(true);
add(t001);
}
}
>.< 赢了!
import javax.swing.*;
import java.awt.*;
public class Win extends JFrame {
ImageIcon icon = new ImageIcon("image/Fireworks.png");
Image imageIcon = icon.getImage();
public Win() {
this.setTitle("赢了");
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setIconImage(imageIcon);
this.getContentPane().setBackground(new Color(255, 255, 255, 255));
JLabel hh = new JLabel(" >.< 赢了!");
this.add(hh);
this.setMinimumSize(new Dimension(66, 66));
this.setResizable(false);
this.setLocationRelativeTo(null);
this.setVisible(DataClass.isWin);
this.pack();
}
}
通过一个类提处理数据并加载图片。
import java.awt.*;
public class DataClass {
private static int mineRow=9;
private static int mineRand=9;
private static int mineNums=10;
public static int countTime=0;
public static int count=0;//用于记录已经点开的数字格数
public static int flagNumber=0;
public static int[][] i=new int[32][16];//用于储存插旗和问号的状态,随便命名的;
public static boolean isStart = false;
public static boolean gameEnd = false;
public static boolean isWin = false;
public static boolean isCheat = false;
public static boolean isCount = false;
public static boolean[][] isBomb=new boolean[32][16];
public static boolean[][] numberDowm=new boolean[32][16];
public static Image[] mineGridIcon = new Image[]{
Toolkit.getDefaultToolkit().getImage("image/blank.gif"),
Toolkit.getDefaultToolkit().getImage("image/flag.gif"),
Toolkit.getDefaultToolkit().getImage("image/ask.gif")
};
public static Image[] numberIcon = new Image[9];
static {
for(int i=0;i<9;i++){
numberIcon[i]=Toolkit.getDefaultToolkit().getImage("image/"+i+".gif");
}
}
public static Image[] timeAndFlagNumberIcon = new Image[11];
static {
for(int i=0;i<10;i++){
timeAndFlagNumberIcon[i]=Toolkit.getDefaultToolkit().getImage("image/d"+i+".gif");
}
timeAndFlagNumberIcon[10]=Toolkit.getDefaultToolkit().getImage("image/d10.gif");
}
public static void setMineGrid(int row, int rand, int nums){
mineRow=row;
mineRand=rand;
mineNums=nums;
}
public static int getMineRow(){
return mineRow;
}
public static int getMineRand(){
return mineRand;
}
public static int getMineNums(){
return mineNums;
}
//重置
public void reStart(){
flagNumber=0;
isStart = false;
count=0;
countTime=0;
i=new int[32][16];
gameEnd=false;
isWin = false;
isCount = false;
isBomb=new boolean[32][16];
numberDowm=new boolean[32][16];
}
}