正式开始写博客了-【第一个程序-扫雷】

一直有写一个博客的想法【没有博客能叫程序员?】,但是一直都没有去做,今天下定决定正式开始了,学了将近三年的vb.net,由于大学专业非计科类的,学的也是一般般。从7月开始学习java,由于也算是有基础,语法部分过得很快。然后就决定做一个程序来练练手。由于平时偶尔喜欢玩扫雷,决定就做一个简单点的扫雷好了。


第一步,起名字

给程序起一个名字还是很重要的,不然很快就认不出来了。直接使用了在线翻译软件决定名字为 Mine Clear


第二步,分析程序

整个程序比较简单,初始化什么的都比较简单,核心是点击潜在地雷的时候的反应,如果是地雷,游戏直接结束。如果不是地雷则计算周围的地雷数目【范围是 (x-1,x-1)  & (y-1,y+1)】。如果数目是0,那么需要对周围的潜在地雷全部触发掉,来完成自动扩展。


第三步,列出成员

函数

构造函数(必备)

void startGame() 开始游戏(初始化游戏)

void gameOver() 游戏结束

int  getMineCounter(int x,int y) 计算由x,y指定的坐标地雷的周围地雷数

boolean inArea(int x,int y) 判断参数是否在当前游戏坐标范围内

void click(int x,int y)从MouseClick监听器中抽取出来,用于实现自动扩展

类:

Mine 类(继承自JButton,添加三个公开字段,Boolean isMine , int x , int y)

常量:

int MINE_ROW_COUNT 一行的地雷数

int MINE_COL_COUNT 一列的地雷数

int MINE_COUNT 游戏中的真正地雷数目

变量:

int  clearNumer 清除的地雷数目,用于判断游戏是否胜利

boolean[][]  cleared 对应坐标的地雷时候清除【这一部分可以放进Mine类中】

Mine[][]  mines 对应坐标的地雷


代码:

Mine类的定义

public class Mine extends JButton{
	boolean isMine;
	public   Mine(boolean isM ) {
		isMine = isM;
	}
	public Mine() {
		isMine = false;
	}
	int x;
	int y;
}

void startGame() //开始游戏

	/*
	 *初始化游戏
	 */
	static void startGame(Game g,JPanel jp){
		ArrayList<Mine> Mines = new ArrayList<Mine>();	//定义地雷动态集合
		clearNumber = 0;				//初始化已清除数目为0
		cleared =new boolean[MINE_ROW_COUNT][MINE_COL_COUNT];	//初始化是否清除数组
		mines = new Mine[MINE_ROW_COUNT][MINE_COL_COUNT];		//实例化地雷数组



		for (int i = 0; i < MINE_ROW_COUNT * MINE_COL_COUNT; i++) {	
			Mine tmpMine = g.new Mine();				//实例化地雷,由于是内部类,需要使用 parent.new childclass()这种方式
			tmpMine.addMouseListener(MouseClick);			//给地雷添加点击的监听
			Mines.add(tmpMine);					//添加地雷到地雷动态集合

		}
		ArrayList<Integer> mineNumber =new ArrayList<Integer>();	//定义集合存放是真正地雷的编号
		Random random = new Random();					//实例化随机器
		
		while(mineNumber.size()<MINE_COUNT)				//当地雷的编号的个数小于真正地雷数则继续循环
		{
			int tmpNumber = random.nextInt(MINE_ROW_COUNT * MINE_COL_COUNT);
			for (int i=  0;i<mineNumber.size();i++)
			{
				if (tmpNumber == mineNumber.get(i))		//去重复
						continue;
			}
			mineNumber.add(tmpNumber);				//	添加
		}
		while(mineNumber.size() > 0 )					//循环按编号给真正地雷的isMine赋值为true
		{
			int tmpNumber = mineNumber.get(0);
			Mine tmpMine = 	Mines.get(tmpNumber);
			tmpMine.isMine=true;
			mineNumber.remove(0);
		}
		
				
		
		GridLayout gridLayout =new GridLayout(MINE_ROW_COUNT,MINE_COL_COUNT,3,3);	//设置布局为网格布局,并指定行数和列数,行列间距为3
		contentPane.setLayout(gridLayout);						
		g.setSize(40*MINE_ROW_COUNT, 40*MINE_COL_COUNT);				//设置界面大小,保持地雷的大小固定
		g. setResizable(false);								//禁止调整界面大小
		for (int i =0 ; i<MINE_ROW_COUNT;i++)
		{
			for (int j=0 ;j<MINE_COL_COUNT;j++)
			{
				cleared[i][j] = false ;						//cleared赋值为false【不太清楚是否会自动初始化为false】
				Mine m = Mines.get(i*MINE_COL_COUNT +j);			//从动态集合中取出地雷
				mines[i][j] = m;						//吧地雷赋值给mines数组
				m.x=i;								//设置坐标
				m.y=j;
				jp.add(m);							//添加地雷到界面
				
				
				
			}
		}
		jp.revalidate();								//刷新界面
	
} 


点击事件:

static	MouseAdapter MouseClick = new MouseAdapter() {			//实例化点击监听
		@Override
		public void mouseClicked(MouseEvent e) {
			Mine  mine  = (Mine) e.getSource();		//获取点击的对象
			click(mine.x, mine.y);				//调用点击方法
		}
	};

static void click(int x,int y)						//点击方法
	{
		if (cleared[x][y]) return ;				//判断该坐标的地雷是否操作过,操作过就直接退出
		//System.out.println("CLICK:"+x+"---"+y);			
		Mine mine = mines[x][y];				//获取到点击的地雷
		if (mine.isMine){					//如果点击的是真正的地雷则调用结束游戏方法
			System.out.println("isMine!");
			gameover( );
		}
		else{
			clearNumber++;					//把清除过得地雷数目加1
			cleared[x][y] = true;				//当前坐标设置为清除过
			mine.setText(""+getMineCounter(mine.x, mine.y));//设置地雷的text属性,显示周围的地雷数
			mine.setEnabled(false);				//设置按钮不可用
			if (clearNumber == MINE_ROW_COUNT * MINE_COL_COUNT-MINE_COUNT )		//如果清除过得数目等于非真正地雷数目则游戏通关
			{
				JOptionPane.showMessageDialog(frame, "游戏通关", "You Win!",JOptionPane.WARNING_MESSAGE); 
			}
		}
	}


计算周围地雷数:

static int getMineCounter(int x,int y)
	{
		int count = 0;
		if (inArea(x-1, y-1))
			if (mines[x-1][ y-1].isMine)
				count++;

		if (inArea(x+1, y-1))
			if (mines[x+1][ y-1].isMine)
				count++;

		if (inArea(x, y-1))
			if(mines[x][ y-1].isMine)
				count++;
		

		if (inArea(x-1, y))
			if (mines[x-1][ y].isMine)
				count++;
	
		if (inArea(x+1, y))
			if (mines[x+1][ y].isMine)
				count++;
		
		
		if (inArea(x-1, y+1))
			if(mines[x-1][ y+1].isMine)
				count++;

		if (inArea(x+1, y+1))
			if(mines[x+1][ y+1].isMine)
				count++;

		if (inArea(x, y+1))
			if(mines[x][ y+1].isMine)
				count++;
				
		if (count==0)
		{
			if (inArea(x+1, y+1))
				click(x+1, y+1);
			
			if (inArea(x+1, y))
				click(x+1, y);
			
			if (inArea(x+1, y-1))
				click(x+1, y-1);
			
			if (inArea(x, y+1))
				click(x, y+1);
			
			if (inArea(x, y-1))
				click(x, y-1);
			
			if (inArea(x-1, y+1))
				click(x-1, y+1);
			
			if (inArea(x-1, y))
				click(x-1, y);
			
			if (inArea(x-1, y-1))
				click(x-1, y-1);
			
		}
		return count;
	}
	
	static boolean inArea(int x,int y)
	{
		if (x<0 || x>MINE_COL_COUNT-1)
			return false ;
		if (y<0 || y>MINE_ROW_COUNT-1)
			return false ;
		return true;
	}








  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值