首页 > 代码库 > 很久木来博客园了,今天献上周末撸的扫雷游戏咯~~

很久木来博客园了,今天献上周末撸的扫雷游戏咯~~

下面先上效果图

技术分享

上图为最终效果,界面没美化,有点丑将就将就,,,,哈哈

 

不多说,上代码看注释已经注释好多,扫雷主要难度在于计算但前点击周围你的安全区域,我的想法是:递归循环计算当前点击的上、下、左、右4个格子,如果遇到空白则继续,如果遇到周围有雷则停止。

技术分享由中心点往外扩散,在扩散中肯定回遇到已经处理过的格子,则跳过continue。。。。

html代码

<!doctype html><html><head>	<meta charset="UTF-8">	<title>扫雷游戏</title>	<style>				*{padding:0;margin:0;}				.main{			margin: 10px 0 0 10px;		}				.head{					}				.body{			margin: 10px;		}				.minefield,		.minefield tr,		.minefield td{border:1px solid #000;}				.minefield td{			color:#00f;			width: 20px;			height: 20px;			text-align: center;			cursor: pointer;		}				/*.minefield td:hover{background-color:#ccc;}*/				/*初始化颜色*/		.init-color{background-color: #ddd;}		/*打开颜色*/		.oper-color{background-color: #fff;}		/*标志颜色*/		.flag-color{background-color: #00FF00;}		/*雷颜色*/		.mine-color{background-color: #f00;}						fieldset{			padding: 5px;			width: 800px;			font-size: 14px;		}		legend{			font-size: 12px;			color: #00f;;		}				.info{			font-size: 12px;			color: #00f;		}	</style></head><body>	<div class="main">		<div class="head">			<fieldset>				<legend>难度</legend>				<fieldset>					<legend><input type="radio" name="define" checked="checked" value="http://www.mamicode.com/1"/>系统定义</legend>					<label title="9x9,10"><input type="radio" name="diff" checked="checked" value="http://www.mamicode.com/1"/>初级</label>					<label title="16x16,40"><input type="radio" name="diff" value="http://www.mamicode.com/2"/>中级</label>					<label title="16x30,99"><input type="radio" name="diff" value="http://www.mamicode.com/3"/>高级</label>				</fieldset>				<fieldset>					<legend><input type="radio" name="define" value="http://www.mamicode.com/0"/>自定义</legend>					<label>行数(9~24):<input type="text" id="rowNum" value="http://www.mamicode.com/9"/></label>					<label>列数(9~30):<input type="text" id="colNum" value="http://www.mamicode.com/9"/></label>					<label>雷数(10~668):<input type="text" id="mineNum" value="http://www.mamicode.com/10"/></label>				</fieldset>				<button type="button" id="start">走你</button>								<div class="body" id="minefield"></div>				<div class="info">					<label>用时:<span id="useTime">0</span>秒</label>    <span id="gameEnd"></span>				</div>			</fieldset>		</div>			</div>		<script src="http://www.mamicode.com/jquery-1.9.1.min.js"></script>
     <script src="http://www.mamicode.com/minefield.jquery.js"></script> <script>        $(function(){   $(‘#start‘).bind(‘click‘, function(){ var data = http://www.mamicode.com/{},"define"]:checked‘).val(),   diff = $(‘input[name="diff"]:checked‘).val(),   rowNum = $.trim($(‘#rowNum‘).val()),   colNum = $.trim($(‘#colNum‘).val()),   mineNum = $.trim($(‘#mineNum‘).val());     // 选择系统定义     if(define == ‘1‘){   switch(diff){ case ‘1‘: data = http://www.mamicode.com/{>                // 这里根据列、行计算最多雷数怎么计算?希望高手指点一二~~   if(9 > mineNum || mineNum > 668 || mineNum > (rowNum*colNum-1) ){ alert(‘干,这是要死的节奏啊,弄这么多雷!!‘); return ;   }          if(rowNum && !isNaN(rowNum)){ data.rowNum = parseInt(rowNum);   }   if(colNum && !isNaN(colNum)){ data.colNum = parseInt(colNum);        }   if(mineNum && !isNaN(mineNum)){ data.mineNum = parseInt(mineNum);   } }
              // 清除下面计时器
              clearTimeout(timeFlag); $(‘#gameEnd‘).empty();
              // 游戏启动时调用 data.gameStart = function(){ useTime(1); $(‘#gameEnd‘).html(‘进行中....加油~使劲~‘); } data.gameEnd = function(flag){ clearTimeout(timeFlag); var time = $(‘#useTime‘).text(); var str = ‘‘; if(flag){
                       // 游戏通过后可以根据条件给玩家定义一些级别 if(time <= 20){   str = ‘你雷逼‘; } if(20 < time < 50){   str = ‘你牛逼!‘; } if(50<=time<100){   str = ‘恭喜你过关!‘; } if(time >= 100){   str = ‘终于过了,不容易啊~~~‘; } $(‘#gameEnd‘).html(‘<span style="color:#0f0;">‘+str+‘</span>‘); }else{ $(‘#gameEnd‘).html(‘<span style="color:#f00;">真是彩笔~~</span>‘); } }
              // 启动游戏 $(‘#minefield‘).minefield(data); }); // 初始化 $(‘#start‘).click(); });
         // 计时器 var timeFlag; function useTime(time){ $(‘#useTime‘).text(time); timeFlag = setTimeout(function(){ useTime(time+1); },1000); } </script></body></html>

minefield.jquery.js 脚本代码

         /**		*	minefield.jquery.js		*	扫雷插件		*	CBQ 343330602@qq.com		*/		(function(window, $){						//扩展array indexOf方法			if(!Array.prototype.indexOf){				Array.prototype.indexOf = function(v){					var i , len;					for(i=0,len=this.length;i<len;i++){						if(this[i] == v){							return i;						}					}										return -1;				}			}						function Minefield( options, dom ){				this._default = {					init: true,   // 是否初始化					rowNum: 9,   // 多少行					colNum: 9,   // 多少列					mineNum: 10,   // 累的个数					gameStart: function(){},					gameEnd: function(){}				};				this.settings = $.extend(true, this._default, options); // 用户配置				this.$dom = $(dom);  // 当前插入扫雷dom对象				this.$table = $(‘<table class="minefield" border="1" cellpadding="1" cellspacing="1"><tbody></tbody></table>‘); // 扫雷对象				this.mineData = []; // 雷分布数组(包括所有对象)				this.minePosition = []; // 存储雷区位置(只有雷区)				this.mineNumData = []; // 每个格子的雷数				this.gameStart = false;				this.gameOver = false;								this.tempSafeArea = [];												this._init(); // 初始化			}						// 扩展prototype对象			$.extend(Minefield.prototype,{				// 初始化函数				_init: function(){					var me = this;					// 创建地雷分布区域					me._createMineData();					// 创建用户交互界面					me._createGame();					// 创建事件监听					me._addEvent();				},				// 创建雷的分布区域				_createMineData: function(){					var me=this,						i=0, j=0,						rowNum = me.settings.rowNum,						colNum = me.settings.colNum,						max = rowNum * colNum,						mineNum = me.settings.mineNum,						mineData = me.mineData,						minePosition = me.minePosition,						mine;					for(i=0; i<max; i++){						mineData.push(0);					}										// 生成雷					for(j=0;j<mineNum;){						mine = Math.floor(Math.random()*(max-1));						//如果生成的雷已经存在,则重新生成						if(minePosition.indexOf(mine) == -1){							minePosition.push(mine);							mineData[mine] = 1;							j++;						}					}									},				// 创建用户交互界面				_createGame: function(){					var me=this,						i=0, j=0,index = 0,						rowNum = me.settings.rowNum,						colNum = me.settings.colNum,						mineData = me.mineData,						mineNumData = me.mineNumData,						trs=[], tds=[],						isMine = 0						;										for(i=0; i<rowNum; i++){						tds.splice(0, colNum);						for(j=0; j<colNum; j++){							isMine = mineData[index];							// 获取每个格子的旁边的地雷数量,如果格子本身就是地雷则为 -1							if(isMine == 1){								mineNumData[index] = -1;							}else{								mineNumData[index] = me.getMineNumber(j, i);							}														// tds.push(‘<td class="init-color"> ‘+index+‘,‘+isMine+‘,‘+mineNumData[index]+‘</td>‘);							// tds.push(‘<td class="init-color"> ‘+isMine+‘,‘+mineNumData[index]+‘</td>‘);							tds.push(‘<td class="init-color"> </td>‘);							index++;						}												trs.push(‘<tr>‘ + tds.join(‘‘) + ‘</tr>‘);					}										me.$table.find(‘tbody‘).append(trs.join(‘‘));					me.$dom.empty().append(me.$table);				},				// 绑定事件				_addEvent: function(){					var me = this;
                       // 只为table添加事件,这样可以减少多余不必要的事件,如果给每个格子添加点击事件那要污染多少 me.$table .bind(‘click‘, function(e){ var target = e.target, $currTr, currIndex,mineNum, name = target.nodeName.toLowerCase(), allSafeArea; var $currTd; if(name == ‘td‘){
                                      // 如果游戏已经结束则无需继续往下走 if(!me.gameStart){ me.gameStart = true; me.settings.gameStart ? me.settings.gameStart():‘‘; } $currTd = $(target); // 当前点击格子 $currTr = $currTd.parent(); // 当前点击行
                                      // 如果格子已经被点击过,则无需再做操作 if($currTd.hasClass(‘open-color‘) || $currTd.hasClass(‘flag-color‘) || me.gameOver){ return ; } // 计算当前点击位置 currIndex = (当前行 * 列数) + 当前位置 ,因为使用table布局所以点击没行格子都会从0开始 currIndex = ($currTr.index() * me.settings.colNum) + $currTd.index(); mineNum = me.mineNumData[currIndex]; switch(mineNum){ case 0 : // 安全区 // 清空安全区,重新计算 me.tempSafeArea.splice(0,me.tempSafeArea.length);
                                               // 计算当前点击格子旁边的安全格子 me._getLRUDSafeArea($currTd.index(), $currTr.index());
                                               // 修改安全格子背景颜色 me._setSafeBgColor( me.tempSafeArea ); if(me._isWin()){ // 获胜事件 me.settings.gameEnd ? me.settings.gameEnd(true):‘‘; } break; case -1 : // 雷区 $currTd.addClass(‘mine-color‘); me.gameOver = true; me._showMine(); // 失败事件 me.settings.gameEnd ? me.settings.gameEnd(false):‘‘; break; default: // 其他 $currTd.removeClass(‘init-color‘).addClass(‘open-color‘).text(mineNum); if(me._isWin()){ // 获胜事件 me.settings.gameEnd ? me.settings.gameEnd(true):‘‘; } break; } } }) .bind(‘contextmenu‘, function(e){ // 右击事件,用于标识自己认为的雷区,或解除 e.stopPropagation(); var target = e.target, name = target.nodeName.toLowerCase(); var $currTd; if(name == ‘td‘ && !me.gameOver){ $currTd = $(target); if( $currTd.hasClass(‘init-color‘) ){ $currTd.removeClass(‘init-color‘).addClass(‘flag-color‘); return false; } if( $currTd.hasClass(‘flag-color‘) ){ $currTd.removeClass(‘flag-color‘).addClass(‘init-color‘); return false; } } return false; }) ; }, // 获取每个单元的上、下、左、右、左上、右上、左下、右下八个位置的雷分布 getMineNumber: function( x, y ){ var me = this, mineData = http://www.mamicode.com/me.mineData,>                   // 获取当前格子的上(Up)、下(Down)、左(Left)、右(Right)安全区 _getLRUDSafeArea: function(x, y){ var me = this, mineNumData = http://www.mamicode.com/me.mineNumData,>                   // 每次点击判断是否赢了 _isWin: function(){ var me = this; if(me.$table.find(‘.init-color,.flag-color‘).size() == me.settings.mineNum){ return true; } return false; },
                   // 显示所有雷区 _showMine: function(){ var me = this, i, len, minePosition = me.minePosition, $tds = me.$table.find(‘td‘); for(i=0,len=minePosition.length; i<len; i++){ $($tds[minePosition[i]]).addClass(‘mine-color‘); } } }); // jquery插件 $.fn.minefield = function( options ){ return this.each(function(index, dom){ new Minefield( options, dom ); }); }; })(window, jQuery);

  

很久木来博客园了,今天献上周末撸的扫雷游戏咯~~