[java]代码库
1.主类
package s1213扫雷6;
//3.改变难度 关闭旧窗体,新建一个窗体,执行所有原来的代码
//7.菜单栏选项的时间,应该放在public void actionPerformed(ActionEvent e) 这个方法里面
//8尽量使用if+elseif 少用if+else 因为一旦情况发生改变,else很容易出现判断失误的情况
//10.每一次更改状态变量都要写上条件,因为以后更改程序,有可能发生条件变化,原代码就会出错!!!
//12.打开和读取文件的功能
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
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 java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.*;
public class Main1213 extends JFrame {
int bombNum=30; //地雷数目
int nearBombNum[][]=new int[100][100]; //存储这个格子周围地雷的数目
int stackNum=0; //表示堆栈中有多少个元素,用作while循环的终止条件
Boolean isBomb[][]=new Boolean [50][50]; //存储格子是不是地雷,false(不是地雷),true(地雷)
Mybutton button[][]=new Mybutton[100][100]; //Mybutton类型的数组,专门存放按钮,方便得到按钮的x,y参数(坐标参数)
Stack<Mybutton> a=new Stack<Mybutton>(); //创建一个堆栈对象,用来开图
static Main1213 b=null;
ImageIcon redFlagIcon=new ImageIcon("E:/Michael/javaImage/扫雷图片/1.jpg"); //红旗
ImageIcon clickIcon=new ImageIcon("E:/Michael/javaImage/扫雷图片/2.jpg"); //鼠标左键单击时的图标
ImageIcon InitialIcon=new ImageIcon("E:/Michael/javaImage/扫雷图片/3.png"); //初始图片
ImageIcon mouseOverIcon=new ImageIcon("E:/Michael/javaImage/扫雷图片/4.png"); //鼠标覆盖时的图标
ImageIcon bombIcon=new ImageIcon("E:/Michael/javaImage/扫雷图片/5.jpg"); //地雷的图标
//地雷数从1-8的对应图标,BombNumberPicture[0]对应图标地雷数为1,BombNumberPicture[7]对应图标地雷数为8
ImageIcon BombNumberPicture[]={
new ImageIcon("E:/Michael/javaImage/扫雷图片/6.jpg"),
new ImageIcon("E:/Michael/javaImage/扫雷图片/7.jpg"),
new ImageIcon("E:/Michael/javaImage/扫雷图片/8.jpg"),
new ImageIcon("E:/Michael/javaImage/扫雷图片/9.jpg"),
new ImageIcon("E:/Michael/javaImage/扫雷图片/10.jpg"),
new ImageIcon("E:/Michael/javaImage/扫雷图片/11.jpg"),
new ImageIcon("E:/Michael/javaImage/扫雷图片/12.jpg"),
new ImageIcon("E:/Michael/javaImage/扫雷图片/13.jpg"),};
public static void main(String[] args)
{ b=new Main1213();
b.setBomb(); //布雷
b.Mymenu(); //添加菜单栏
b.init(); //setVisiable的位置很重要,a.Mymenu();a.init(); 顺序交换就看不到菜单栏了。
b.setButton(); //在界面中添加按钮和监听事件
}
public void init()
{ this.setTitle("扫雷"); //设置窗体的标题
this.setLocationRelativeTo(null); //设置窗体出现位置居中
this.setDefaultCloseOperation(3); //设置窗体的关闭操作
this.setResizable(true); //设置禁止调整窗体的大小
this.setIconImage((new ImageIcon("E:/Michael/javaImage/扫雷图片/bomb.png").getImage()));//设置标题栏图标
this.setSize(430,500); //设置窗体的大小
this.setLocationRelativeTo(null); //设置窗体出现在屏幕中间
this.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
this.setVisible(true);
}
public void setButton() //绘制界面,鼠标对界面的操作事件(地雷格子)
{
//事件监听***************************************************************************************************
MouseListener mouseListener=new MouseListener()
{
public void mousePressed(MouseEvent e)
{
//右键点击********************************************************************
if(e.getButton()==MouseEvent.BUTTON3)
{
Mybutton btn = (Mybutton)e.getSource(); //得到事件源对象,并强制转型为Mybutton
int flagAndBomb=0;
if(btn.status==0) //如果该按钮状态为没翻转过
{btn.setIcon(redFlagIcon);btn.setStatus(4);} //改变图标为redFlagIcon,并设置为状态3(红旗)
else if(btn.status==4) //如果该按钮状态为红旗
{btn.setIcon(InitialIcon);btn.setStatus(0);} //改变图标为InitialIcon(初始图标)
else if(btn.status==1) //如果是已经翻开的图标
{
int x=btn.x, y=btn.y; //x,y用来表示当前按钮的坐标
checkBomb(x, y);
//如果标记的红旗下面不是地雷,那么游戏结束*********************************
}
//胜利判断**************************
for(int i=0;i<20;i++)
for(int j=0;j<20;j++)
{ if(isBomb[i][j]&&button[i][j].status==4)
flagAndBomb++;
}
if(flagAndBomb==bombNum)
{ for(int i=0;i<20;i++) //判断胜利后开全图
for(int j=0;j<20;j++)
{changeBombIcon(button[i][j]);}
JOptionPane.showMessageDialog(null, "你胜利了");}
//**********************************
}
//***************************************************************************
//左键点击********************************************************************
if(e.getButton()==MouseEvent.BUTTON1)
{ Mybutton btn = (Mybutton)e.getSource();
if(btn.status==0)
{ btn.setStatus(1);
if(!isBomb[btn.x][btn.y]) //如果点击不是地雷
{ findBomb(); //遍历地图,找到所有位置周围的地雷数目
showBomb(btn); //根据周围地雷数目,更换图标
}
if(isBomb[btn.x][btn.y]) //如果鼠标点击是地雷
{ for(int i=0;i<20;i++) //找到所有的地雷
for(int j=0;j<20;j++)
{ button[i][j].setStatus(1); //改变所有按钮的状态变量为1(翻转状态)
if(isBomb[i][j]) button[i][j].setIcon(bombIcon);} //找到地雷并改变图标为bombIcon(地雷图标)
JOptionPane.showMessageDialog(null, "游戏结束"); //弹出消息提示框,提示游戏结束
}
}
}
//左键点击**********************************************************************
}
//计算点击处周围8个格子中的红旗数,保存在flag,用count来记录红旗和地雷的吻合数目
public void checkBomb(int x, int y) {
int bomb=0,flag=0;
for(int i=0;i<8;i++)
{
if(new Mybutton(getX(x,i),getY(y,i)).locationLegalJudge()) //边界判断
{
if(button[getX(x,i)][getY(y,i)].status==3||button[getX(x,i)][getY(y,i)].status==4)
{
flag++; //如果格子状态表示红旗,那么红旗数目+1
if(isBomb[getX(x,i)][getY(y,i)])
{bomb++; }
}
}
}
//如果红旗和地雷吻合,则开图,不吻合就结束游戏,共2种情况***************************************
if(bomb==nearBombNum[x][y]) //如果周围雷数和判断一样
{
for(int i=0;i<8;i++) //周围8个格子,每个格子判断一次
{
if(new Mybutton(getX(x,i),getY(y,i)).locationLegalJudge()&&!isBomb[x][y]) //边界判断,而且不是地雷
{
changeBombIcon(button[getX(x,i)][getY(y,i)]); //点击处左上角判断
if(nearBombNum[getX(x,i)][getY(y,i)]==0&&!isBomb[getX(x,i)][getY(y,i)])
showBomb(button[getX(x,i)][getY(y,i)]);
}
}
}
//如果红旗和地雷吻合,则开图,不吻合就结束游戏,共2种情况***************************************
//如果标记的红旗下面不是地雷,那么游戏结束*********************************
if ((bomb!=nearBombNum[x][y]&&flag>=nearBombNum[x][y]))
{
for(int i=0;i<20;i++) //找到所有的地雷
for(int j=0;j<20;j++)
{ button[i][j].setStatus(1); //改变所有按钮的状态变量为1(翻转状态)
if(isBomb[i][j]) button[i][j].setIcon(bombIcon);} //找到地雷并改变图标为bombIcon(地雷图标)
JOptionPane.showMessageDialog(null, "游戏结束"); //弹出消息提示框,提示游戏结束
}
}
public void mouseEntered(MouseEvent e)
{
Mybutton btn=(Mybutton)e.getSource(); //要强制转型
if(btn.status==0) btn.setIcon(mouseOverIcon); //如果还没有翻转,那么改变按钮图案
}
public void mouseExited(MouseEvent e)
{
Mybutton btn=(Mybutton)e.getSource(); //要强制转型,得到事件源
if(btn.status==0) btn.setIcon(InitialIcon); //如果按钮还未翻转,那么改变按钮图案
}
public void mouseReleased(MouseEvent e)
{}
public void mouseClicked(MouseEvent e)
{}
};
//*******************************************************************************************************
//绘制游戏界面************************************************************************************************
for(int i=0;i<20;i++) //生成界面按钮20行20列
for(int j=0;j<20;j++)
{
Mybutton jb=new Mybutton(i,j);
jb.setPreferredSize(new Dimension(20,20));
jb.addMouseListener(mouseListener); //要将new mouselistener的代码放到前面这行代码才不会出错
button[i][j]=jb; //通过这种方式就可以根据i,j唯一确定每个按钮
this.add(jb); //界面添加按钮
}
JLabel jl = new JLabel(); //用来计时的标签
JLabel j2 = new JLabel("游戏计时:");
this.add(j2);
this.add(jl);
//计时功能*********************************************
TimerTask task = new TimerTask()
{ int n=0;
public void run()
{ jl.setText(""+n); n++;} //计时++
};
Timer timer = new Timer();
timer.schedule(task, 0, 1000);
//计时功能*********************************************
//绘制游戏界面************************************************************************************************
}
public void setBomb() //布雷
{ for(int i=0;i<20;i++) //遍历地图,将所有格子的地雷状态变量都初始化为0,0表示不是地雷
for(int j=0;j<20;j++) //遍历地图,将所有格子的地雷状态变量都初始化为0,0表示不是地雷
isBomb[i][j]=false; //遍历地图,将所有格子的地雷状态变量都初始化为0,0表示不是地雷
int n=0;
while(n<bombNum) //当n<地雷数,就一直循环执行
{ int x=new Random().nextInt(20); //随机产生行数
int y=new Random().nextInt(20); //随机产生列数
if(!isBomb[x][y]) {isBomb[x][y]=!isBomb[x][y];n++;} //如果随机产生的位置原来的状态是没有地雷,将地雷状态改变,地雷数加1
}
}
public void findBomb() //找出地图中所有位置周围地雷的数目,保存在nearBombNum[x][y]中
{ for(int x=0;x<20;x++) //遍历整个地图
for(int y=0;y<20;y++)
{
if(!isBomb[x][y]) //只有当这个位置不是地雷的时候才执行查找周围地雷数的代码
{
int n=0; //n记录周围地雷的数目
for(int i=0;i<8;i++)
{
if(new Mybutton(getX(x,i),getY(y,i)).locationLegalJudge()&&isBomb[getX(x,i)][getY(y,i)]) //边界判断
{
n++;
}
}
setNearBombNum(x,y,n);
}
}
}
public void showBomb(Mybutton btn) //点击后更改图标和开图功能
{
int x=btn.x, y=btn.y,k=nearBombNum[x][y]; //x,y用来表示当前按钮的坐标,k用来表示是按钮周围的地雷数
if(btn.status==0) btn.setStatus(1); //表示访问过了
if(k==0) //如果这个格子周围没有地雷
{
for(int i=0;i<8;i++)
{
if(new Mybutton(getX(x,i),getY(y,i)).locationLegalJudge()&&!isBomb[getX(x,i)][getY(y,i)]) //边界判断
{
changeBombIcon(button[getX(x,i)][getY(y,i)]); //点击处左上角判断
if(nearBombNum[getX(x,i)][getY(y,i)]==0&&button[getX(x,i)][getY(y,i)].status==0) {
a.push(button[getX(x,i)][getY(y,i)]);
stackNum++;
}
}
}
while(stackNum>0) //深度优先遍历,先将所有空格加进去,再倒出来
{ stackNum--;showBomb(a.pop());}
}
else changeBombIcon(btn); //如果点击的不是空格,那么直接改变按钮图案
}
public void changeBombIcon(Mybutton btn) //根据周围地雷数,改变按钮图标
{
int nearBombNumber=nearBombNum[btn.x][btn.y]; //k用来表示是按钮周围的地雷数
if(nearBombNumber==0){
btn.setIcon(mouseOverIcon);
if(isBomb[btn.x][btn.y])
{btn.setIcon(redFlagIcon);btn.setStatus(3);} //如果是地雷,那么就改变图标
}
else
{
btn.setIcon(BombNumberPicture[nearBombNumber-1]); btn.setStatus(1);
}
}
//**************************************菜单栏*************************************************//
public void Mymenu()
{
JMenu file,edit,help,nandu;//声明JMenu类对象
JMenuItem newgame,exit,copy,chuji,zhongji,gaoji,author,wanfa;//声明menuitem类对象
//初始菜单项
newgame=new JMenuItem("新游戏",new ImageIcon("C:/Users/Administrator/Desktop/images/2.jpg")); //创建menuItem对象
exit=new JMenuItem("关闭"){{b.dispose();}}; //创建menuItem对象
copy=new JMenuItem("保存战绩"){ //创建menuItem对象
{ addActionListener(
e->{
JFileChooser a=new JFileChooser(); //打开文件路径程序框
a.setDialogTitle("另存为");
a.showSaveDialog(null) ; //注意showSaveDialog和showOpenDialog的区别
});
}};
author=new JMenuItem("作者"){ //创建menuItem对象
{ addActionListener(
e->JOptionPane.showMessageDialog(null,"游戏作者:贺思源 制作时间:2014.12.13"));
}};
wanfa=new JMenuItem("玩法"); //创建menuItem对象
chuji=new JMenuItem("初级"); //创建menuItem对象
zhongji=new JMenuItem("中级"); //创建menuItem对象
gaoji=new JMenuItem("高级"); //创建menuItem对象
nandu=new JMenu("难度"){{add(chuji);add(zhongji);add(gaoji);}}; //创建menuItem对象
help=new JMenu("帮助"){{add(author);add(wanfa); }}; //创建JMenu对象
file=new JMenu("游戏(G)"){{setMnemonic('G');add(newgame);add(nandu);addSeparator();add(exit);}}; //创建JMenu对象
edit=new JMenu("编辑"){{add(copy);}};
JMenuBar menubar=new JMenuBar(){{add(file);add(help);add(edit);}}; //创建menubar对象
chuji.addActionListener( e->
{
this.dispose(); //关闭旧窗体
Main1213 s2=new Main1213();
s2.setbombNum(30);
s2.setBomb(); //布雷
s2.Mymenu(); //添加菜单栏
s2.init(); //setVisiable的位置很重要,a.Mymenu();a.init(); 顺序交换就看不到菜单栏了。
s2.setButton(); //在界面中添加按钮和监听事件
});
zhongji.addActionListener( e->
{
this.dispose(); //关闭旧窗体
Main1213 s2=new Main1213();
s2.setbombNum(60);
s2.setBomb(); //布雷
s2.Mymenu(); //添加菜单栏
s2.init(); //setVisiable的位置很重要,a.Mymenu();a.init(); 顺序交换就看不到菜单栏了。
s2.setButton(); //在界面中添加按钮和监听事件
});
gaoji.addActionListener( e->
{
this.dispose(); //关闭旧窗体
Main1213 s2=new Main1213();
s2.setbombNum(90);
s2.setBomb(); //布雷
s2.Mymenu(); //添加菜单栏
s2.init(); //setVisiable的位置很重要,a.Mymenu();a.init(); 顺序交换就看不到菜单栏了。
s2.setButton(); //在界面中添加按钮和监听事件
});
exit.addActionListener(e-> this.dispose()); //关闭游戏
this.setJMenuBar(menubar); //设置menuBar
}
//********************************************************************************************//
public void setbombNum(int x) //设置地雷数目
{ bombNum=x;}
public Mybutton getButton(int x,int y) {
return button[x][y];
}
//根据x坐标和index,得到周围第i个格子的x坐标
public int getX(int x,int index) {
int xLocation[]={x-1,x,x+1,x-1,x+1,x-1,x,x+1,};
return xLocation[index];
}
//根据y坐标和index,得到周围第i个格子的y坐标
public int getY(int y,int index) {
int yLocation[]={y+1,y+1,y+1,y,y,y-1,y-1,y-1};
return yLocation[index];
}
public int[][] getNearBombNum() {
return nearBombNum;
}
public void setNearBombNum(int x,int y,int bombNumber) {
nearBombNum[x][y]=bombNumber;
}
}
2.Mybutton类
package s1213扫雷6;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.border.EmptyBorder;
public class Mybutton extends JButton {
int status; // 0(未翻转),1(翻转),3(地雷),4(红旗)
int x, y;
ImageIcon i1 = new ImageIcon("E:/Michael/javaImage/扫雷图片/3.png"); // 初始图片
EmptyBorder o = new EmptyBorder(2, 2, 0, 0); // 生成按钮边界对象
Mybutton() { // 构造方法
this.setIcon(i1); // 给按钮添加图标
this.setBorder(o); // 改变按钮边界
}
Mybutton(int x, int y) { // 调用本类构造方法
this();
this.x = x;
this.y = y;
}
public boolean locationLegalJudge() {
return this.x >= 0 && this.x <=19 && this.y >= 0 && this.y <=19;
}
public void setStatus(int x) // 改变按钮的状态变量方法
{
this.status = x;
}
public int getStatus() {
return status;
}
}
[源代码打包下载]
初级程序员
by: 彭浩 发表于:2016-11-22 09:22:40 顶(0) | 踩(0) 回复
图片 包中没有啊
回复评论