扫雷(java图形界面好例题)

CleanMine.java

package xjj;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ButtonGroup;
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;
import javax.swing.JRadioButtonMenuItem;

public class CleanMine extends JFrame implements ActionListener{
	public static int result,showNumb;//result表示标记是雷的个数,而showNumb表示点开的个数
	private boolean isFirst = true;//设置必须点击新游戏才能开始游戏
	private JLabel jlbtime,jlbremain;
	public static JLabel time;//时间
	public static JLabel remainMine;//剩余雷的个数
	private JButton start;
	private JPanel jpane;
	public static int row,col,mineNumber;//雷的排列,行和列,以及雷的总个数
	private Dimension dim;
	private JRadioButtonMenuItem[] difficult;//菜单项
	
	public CleanMine(){
		super("扫雷");
		dim=this.getToolkit().getScreenSize();//获取屏幕分辨率
		this.setLocation(dim.width*2/5, dim.height/3);//设置位置,根据难易程度做出人性化变动
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		addMenu();
		jlbremain=new JLabel("剩余地雷:");
		time=new JLabel("10");
		remainMine=new JLabel("0");
		jlbtime=new JLabel("耗时:");
		start=new JButton("新游戏");
		start.setActionCommand("new");
		start.addActionListener(this);
		JPanel p=new JPanel();
		p.add(jlbremain);p.add(remainMine);p.add(start);p.add(jlbtime);p.add(time);
		this.add(p,BorderLayout.NORTH);
		this.row=9;this.col=9;this.mineNumber=10;
		restart();
	}
	
	private void restart() {
		if(jpane!=null){
			this.remove(jpane);
		}
		jpane=new MinePanel(row,col,mineNumber,isFirst);
		this.add(jpane,BorderLayout.CENTER);
		this.remainMine.setText(mineNumber+"");
		this.time.setText("0");
		this.setSize(col*30, row*30+10);
		this.setResizable(false);
		
		this.setVisible(true);
	}

	public void addMenu(){
		JMenuBar jbar=new JMenuBar();
		this.setJMenuBar(jbar);
		JMenu game = new JMenu("游戏");
		JMenu help = new JMenu("帮助");
		JMenuItem jitemexit=new JMenuItem("退出");
		jitemexit.setActionCommand("exit");
		ButtonGroup bgp=new ButtonGroup();
		
		String[] difficults={"复杂","中等","简单"};
		difficult=new JRadioButtonMenuItem[difficults.length];
		for(int i=difficults.length-1;i>=0;i--){
			difficult[i]=new JRadioButtonMenuItem(difficults[i],true);
			difficult[i].addActionListener(this);
			bgp.add(difficult[i]);
			game.add(difficult[i]);
		}
		game.addSeparator();jitemexit.addActionListener(this);game.add(jitemexit);
		jbar.add(game);
		JMenuItem jitemview=new JMenuItem("关于扫雷");
		jitemview.setActionCommand("view");
		jitemview.addActionListener(this);
		help.add(jitemview);
		jbar.add(help);
	}
	
	public static void main(String[] args){
		new CleanMine();
	}
	
	public void actionPerformed(ActionEvent e) {
		if(e.getActionCommand().equalsIgnoreCase("new")){
			this.result=0;
			this.showNumb=0;
			this.isFirst=false;
			restart();
			return ;
		}
		if(e.getActionCommand().equals("简单")){
			this.row=9;this.col=9;this.mineNumber=10;
			this.setLocation(dim.width*2/5, dim.height/3);
			restart();
			return ;
		}
		if(e.getActionCommand().equals("中等")){
			this.row=16;this.col=16;this.mineNumber=40;
			this.setLocation(dim.width*2/5, dim.height/5);
			restart();
			return ;
		}
		if(e.getActionCommand().equals("复杂")){
			this.row=16;this.col=30;this.mineNumber=99;
			this.setLocation(dim.width/7, dim.height/7);
			restart();
			return ;
		}
		if(e.getActionCommand().equalsIgnoreCase("exit")){
			System.exit(0);
		}
		if(e.getActionCommand().equalsIgnoreCase("view")){
			JOptionPane.showMessageDialog(this,"扫雷的规则:\n\t尽快找到雷区中的所有不是地雷的格子,而不许踩到地雷。" +
					"点开的数字是几,\n则说明该数字旁边的8个位置中有几个雷,如果挖开的是地雷,则会输掉游戏。");
		}
	}

}


MinePanel.java

package xjj;

import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class MinePanel extends JPanel implements ActionListener{
	private boolean isFirst;
	private int row,col,mineNumber;
	private JButton[][] mine;
	private int[][] mark;
	Thread t;

	public MinePanel(int row,int col,int mineNumber,boolean isFirst){
		this.isFirst=isFirst;
		this.row=row;
		this.col=col;
		this.mineNumber=mineNumber;
		mine=new JButton[this.row][this.col];
		mark=new int[this.row][this.col];
		this.setLayout(new GridLayout(row,col));
		createMine();
		createButtons();
		if(isFirst){
			firstinist();
		}else{
			init();//初始化
		}
	}
	private void firstinist(){
		for(int i=0;i<mine.length;i++){
			for(int j=0;j<mine[i].length;j++){
				mine[i][j]=new JButton();
				this.add(mine[i][j]);
			}
		}
	}
	private void init() {
		this.setLayout(new GridLayout(row,col));
		for(int i=0;i<mine.length;i++){
			for(int j=0;j<mine[i].length;j++){
				this.add(mine[i][j]);
			}
		}
		
	}

	private void createButtons() {
		for(int i=0;i<mine.length;i++){
			for(int j=0;j<mine[i].length;j++){
				mine[i][j]=new MineButton(i,j);
				mine[i][j].setSize(6, 6);
				mine[i][j].addActionListener(this);
				mine[i][j].addMouseListener(
						new MouseAdapter(){
							public void mouseClicked(MouseEvent e){
								if(e.getButton()==MouseEvent.BUTTON3){
									int remain=Integer.parseInt(CleanMine.remainMine.getText());
									JButton b=(JButton)e.getSource();
									if(b.getText().equals("")&&remain>0){
										CleanMine.result++;//System.out.println(CleanMine.showNumb+" "+CleanMine.result);
										if(CleanMine.result==CleanMine.row*CleanMine.col-CleanMine.showNumb){
											JOptionPane.showMessageDialog(b, "congratulations ! xjj万岁 !");
										}
										remain--;
										CleanMine.remainMine.setText(remain+"");
										b.setText("$");
									}else if(b.getText().equals("$")){
										CleanMine.result--;System.out.println(CleanMine.showNumb);
										remain++;
										CleanMine.remainMine.setText(remain+"");
										b.setText("");
									}
								}
							}
						}
						                     );
			}
		}
		
	}

	private void createMine() {
		int n=0;
		while(n<mineNumber){//随机生成规定个数的雷的位置
			int i=(int)(Math.random()*row);
			int j=(int)(Math.random()*col);
			if(mark[i][j]!=-1){
				mark[i][j]=-1;
				n++;
			}
		}
		for(int i=0;i<mark.length;i++){//对地图做标记
			for(int j=0;j<mark[i].length;j++){
				if(mark[i][j]!=-1){
					mark[i][j]=getSurroundMineNumber(mark,i,j);
				}
			}
		}
	}

	private int getSurroundMineNumber(int[][] mark2, int n, int m) {
		int numb=0;
		int[] direct={0,1,-1};
		int x,y;
		for(int i=0;i<direct.length;i++){
			for(int j=0;j<direct.length;j++){
				if(i==0&&j==0){
					continue;
				}
				x=n+direct[i];
				y=m+direct[j];
				if(x>=0 && x<mark2.length && y>=0 &&  y<mark2[0].length){//对周围八个方向进行遍历
					numb+=(mark2[x][y]==-1? 1:0);
				}
			}
		}
		return numb;
	}

	public void actionPerformed(ActionEvent e) {
		MineButton b=(MineButton)e.getSource();
		int r=b.getRow();
		int c=b.getCol();
		if(mark[r][c]==-1){//踩到雷,将地图所有都显示出来
			//String str=CleanMine.time.getText();
			//isFirst=true;
			CleanMine.time.setText("0");
			for(int i=0;i<mark.length;i++){
				for(int j=0;j<mark[i].length;j++){
					if(mark[i][j]==-1){
						mine[i][j].setText("@");
					}else if(mark[i][j]==0){
						mine[i][j].setText("");
						mine[i][j].setBackground(Color.green);
					}else{
						mine[i][j].setText(mark[i][j]+"");
						mine[i][j].setBackground(Color.green);
					}
				}
			}
			JOptionPane.showMessageDialog(this, "叫你扫雷,不是踩雷,游戏结束 !");
		}else{
			showEmpty(mark,r,c);
		}
	}

	private void showEmpty(int[][] mark2, int r, int c) {
		MineButton b=(MineButton)mine[r][c];
		if(b.isCleared()){
			return ;
		}CleanMine.showNumb++;//System.out.println(CleanMine.showNumb);
		if(CleanMine.result==CleanMine.row*CleanMine.col-CleanMine.showNumb){
			JOptionPane.showMessageDialog(this,"congratulations ! xjj万岁 !");
		}
		int x,y;
		int[] direct={0,1,-1};
		if(mark[r][c]==0){//若是空的  将其显示出来,并继续遍历
			b.setBackground(Color.green);
			b.setCleared(true);
			for(int i=0;i<direct.length;i++){
				for(int j=0;j<direct.length;j++){
					if(i==0&&j==0){
						continue;
					}
					if(b.getText().equals("$")){
						continue;
					}
					x=r+direct[i];
					y=c+direct[j];
					if(x>=0 && x<mark2.length && y>=0 &&  y<mark2[0].length){
						//CleanMine.showNumb++;
						showEmpty(mark2,x,y);
					}
				}
			}
		}else{
			if(b.getText().equals("$")){//若被标记是雷,则不显示
				return ;
			}
			b.setText(mark[r][c]+"");//若是数字,则将数字显示出来
			b.setBackground(Color.green);
			b.setCleared(true);
		}
	}
	
}

MineButton.java

package xjj;

import java.awt.Insets;

import javax.swing.JButton;

public class MineButton extends JButton {
	private int row,col;
	private boolean cleared=false;
	public MineButton(int row, int col) {
		this.row=row;
		this.col=col;
		this.setMargin(new Insets(0,0,0,0));
	}

	public int getCol() {
		return col;
	}
	
	public int getRow() {
		return row;
	}
	
	public boolean isCleared() {
		return cleared;
	}
	
	public void setCleared(boolean cleared) {
		this.cleared = cleared;
	}


}









评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值