JavaScript版经典游戏之扫雷游戏完整示例【附demo源码下载】
更新时间:2017年1月9日 10:00 点击:2150
本文实例讲述了JavaScript扫雷游戏。分享给大家供大家参考,具体如下:
翻出年初写的游戏贴上来,扫雷相信大家都玩过,先上图:
源码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Javascript版扫雷</title> <style> input{ margin:0; padding:0;} input{ outline:none;} #game_box{ width:400px; height:430px; margin:100px auto; border:#333 1px solid; background:#ccc -webkit-repeating-linear-gradient(top,#ccc,#000);background:#ccc -moz-repeating-linear-gradient(top,#ccc,#000);background:#ccc -o-repeating-linear-gradient(top,#ccc,#000);background:#ccc -ms-repeating-linear-gradient(top,#ccc,#000); box-shadow:0 0 50px 10px #333; box-shadow:0 0 50px 10px #333; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#CBCBCB', endColorstr='#000000'); } #map{width:400px; height:348px;*height:380px;} #time{ height:18px; line-height:22px; text-align:center;margin:6px 0; margin-top:10px; _margin-top:40px; color:#fff; position:relative;} #time input{ width:40px; height:18px; line-height:18px; text-align:center;} #table_map{ width:336px; height:336px; border:none; border-left:#000 1px solid;border-top:#000 1px solid; margin:32px 32px 0px 32px; background:#D8ECF6; text-align:center; border-collapse: collapse} #table_map td{ width:20px; height:20px; border:none;border-right:#000 1px solid;border-bottom:#000 1px solid; color:#333333; transition:all 0.7s; cursor:pointer;} #table_map td.mask{ border:none;border-right:#000 1px solid;border-bottom:#000 1px solid; background:#333; } #table_map td.over{ border:none;border-right:#000 1px solid;border-bottom:#000 1px solid; } .over_bg{ background:#E1E1E1;} @-webkit-keyframes round{ from{ -webkit-transform:rotateX(0);} to{ -webkit-transform:rotateX(360deg);} } @-webkit-keyframes show{ from{ -webkit-transform:rotateX(180deg) rotateY(0) scale(0);} to{ -webkit-transform:rotateX(360deg) rotateY(360deg) scale(1);} } @-moz-keyframes round{ from{ -moz-transform:rotateX(0);} to{ -moz-transform:rotateX(360deg);} } @-moz-keyframes show{ from{ -moz-transform:rotateX(180deg) rotateY(0) scale(0);} to{ -moz-transform:rotateX(360deg) rotateY(360deg) scale(1);} } @-ms-keyframes round{ from{ -ms-transform:rotateX(0);} to{ -ms-transform:rotateX(360deg);} } @-ms-keyframes show{ from{ -ms-transform:rotateX(180deg) rotateY(0) scale(0);} to{ -ms-transform:rotateX(360deg) rotateY(360deg) scale(1);} } #game_box{-webkit-animation:show 3s;-moz-animation:show 3s;-ms-animation:show 3s;} </style> </head> <body> <div id="game_box"> <div id="map"></div> <div id="time">时间:<input type="text" value="0" disabled="disabled" /> 炸弹:<input type="text" value="50" disabled="disabled" /></div> </div> <script> // 2014年3月 by 王美建 QQ1207526854 window.onload=function() { Game.init('game_box','map'); }; var Game={ data : { //关卡数据 mine : 40, col : 16, row : 16 }, init : function(box_id,mapbox_id){ //初始化 this.oBox = document.getElementById(box_id); this.mapBox = document.getElementById(mapbox_id) this.mapBox.innerHTML = this.createMap(); this.oMap = this.mapBox.getElementsByTagName('table')[0]; this.aTd = this.oMap.getElementsByTagName('td'); this.time = document.getElementById('time').getElementsByTagName('input')[0]; this.mineNum = document.getElementById('time').getElementsByTagName('input')[1]; this.mineNum.value = this.data.mine; this.surplus = []; this.iCount = this.data.col*this.data.row-this.data.mine; this.createMine(); this.addVal(); this.play(); }, createMap : function() //生成画布 { var html = ''; var This = this.data; var i=0,j=0; function createTd() { var tds = ''; for(j = 0; j < This.row; j++) { tds += '<td class = "mask" index='+ (This.col*i+j) +'></td>'; }; return tds; } for(i = 0; i < This.col; i++) { html += '<tr>' + createTd() + '</tr>'; }; return ('<table id="table_map" cellpadding="0" cellspacing="0" ><tbody>'+html+'</table></tbody>'); }, createMine : function(){ //生成炸弹 var This = this.data; this.indexArr = []; this.mineArr = []; for(var i = 0,j = This.col*This.row; i < j; i++ ) { this.indexArr.push(i) ; //所有单元格的索引 }; for( var i = 0; i < This.mine; i++ ) //随机取出This.mine个做为炸弹的索引,不重复 { var index = Math.round(Math.random()*(this.indexArr.length-1)); //索引 this.mineArr.push(this.indexArr.splice(index,1)[0]); }; this.mineArr.sort( function(a,b){return a-b;} ); }, addVal : function() //给有炸弹的td添加自定义属性hasMine值为true { for(var i = 0, j = this.mineArr.length; i < j; i++) { this.aTd[ this.mineArr[i] ].hasMine = true; }; }, play : function() {//鼠标左右键同时按下 ev.button=3 this.timeOnoff = false; var This = this; this.markNum = []; this.oMap.oncontextmenu=function(ev) //插旗标记 { var ev = ev || window.event; var target = ev.srcElement || ev.target; if( target.tagName.toLowerCase() == 'td' && target.className == 'mask' ) { !target.mark ? (target.innerHTML = '▲',target.style.color = '#FFEFAD',target.mark = true,This.mineNum.value--,This.markNum.push( target.getAttribute( 'index' ) )) : (target.innerHTML = '',target.style.color = '#333333',target.mark = false,This.mineNum.value++,This.markNum.splice( This.findIndex( This.markNum,target.getAttribute( 'index' ) ),1 )); }; return false; }; this.oMap.onclick = function(ev) { var ev = ev || window.event; var target = ev.srcElement || ev.target; if(!This.timeOnoff) //开始计时 { This.timeOnoff = true; This.timer=setInterval(function(){ This.time.style.webkitAnimation = 'round 1s infinite'; //计时器翻转 This.time.value++; },1000) }; function openTd(aTd,meg,len) { var num = 0; var show = null; var t = Math.ceil( 15*This.data.col*This.data.row/len ); //未打开格子越多,翻开时间间隔越短 show = setInterval(function(){ aTd[ This.surplus[num] ].className = 'over'; aTd[ This.surplus[num] ].style.webkitAnimation = 'round 1s 1'; if( aTd[ This.surplus[num] ].hasMine && aTd[ This.surplus[num] ].className == 'over' ) { aTd[ This.surplus[num] ].style.color = '#333333'; aTd[ This.surplus[num] ].innerHTML = '★'; }else{ aTd[ This.surplus[num] ].innerHTML = ''; }; num++; if(num == len) { clearInterval(show); alert(meg); } },t) }; function countSur() //统计没打开的格子的索引 { var iCheck = 0; This.surplus = []; for( var i = 0,j = This.data.col*This.data.row; i < j; i++ ) { if( This.aTd[i].className == 'mask' ) { iCheck++; This.surplus.push( i ); }; }; return iCheck; }; if( target.tagName.toLowerCase() == 'td' && target.className == 'mask' && !target.hasMine )//没踩到雷 { This.count( parseInt(target.getAttribute('index')) ); //递归 target.style.webkitAnimation = 'round 1s 1'; if( This.iCount <= 10 ) //通关检测 { //console.log( 'iCheck='+iCheck+'iCount='+This.iCount ) if( countSur() == This.data.mine ) //剩下格子数等于炸弹数而又没踩到炸弹,可不就是过关了 { clearInterval( This.timer ); This.time.style.webkitAnimation = ''; //停止计时器翻转 openTd( This.aTd,'不错小伙子,过关了!用时:'+This.time.value+'s',This.surplus.length ); }; }; }else if( target.tagName.toLowerCase() == 'td' && target.className == 'mask' && target.hasMine ){ //踩到雷 clearInterval(This.timer); //停止计时器 This.time.style.webkitAnimation = ''; //停止计时器翻转 var mineArr = This.mineArr; //优化:全局变局部 var aTd = This.aTd; for( var i = 0,j = mineArr.length; i < j; i++ ) { aTd[ mineArr[i] ].style.color = '#333333'; aTd[ mineArr[i] ].className = 'over'; aTd[ mineArr[i] ].innerHTML = '★'; //显示炸弹标志 }; target.style.color = 'red'; countSur(); openTd( aTd,'小朋友,你输了~',This.surplus.length ); }; }; }, findIndex : function(arr,ele) //找到数组某个元素在数组中的位置 { for(var i=0,j=arr.length;i<j;i++) { if(ele === arr[i]) { return i; }; }; return -1; }, count : function(iNow) //统计事件源周围炸弹 { var arr = []; //事件源周围的格子索引 var iNum = 0; //事件源周围炸弹个数 var len = this.data.col; if( iNow % len == 0 ) //点击最左边的格子时 { arr = [iNow+1,iNow-len,iNow-len+1,iNow+len,iNow+len+1]; }else if( iNow == ( Math.floor( iNow/len ) + 1 ) *len -1 ){ //点击靠右边的格子时 arr = [iNow-1,iNow-len,iNow-len-1,iNow+len,iNow+len-1]; }else{ //点击不靠边的格子时 arr = [iNow-1,iNow+1,iNow-len,iNow-len+1,iNow-len-1,iNow+len,iNow+len-1,iNow+len+1]; }; for( var i = 0; i < arr.length; i++ ) //统计周围炸弹 { if( this.aTd[ arr[ i ] ] && this.aTd[ arr[ i ] ].hasMine ) { iNum++; } }; if( iNum == 0 ) //当前点击格子周围没有炸弹则递归 { this.aTd[iNow].className = ''; this.aTd[ iNow ].innerHTML == '▲' ? this.aTd[ iNow ].innerHTML = '' : ''; for( var i = 0,j = arr.length; i < j; i++ ) { if( this.aTd[ arr[ i ] ] && this.aTd[ arr[i] ].className == 'mask') { this.aTd[ arr[i] ].className = ''; this.aTd[ arr[i] ].innerHTML == '▲' ? this.aTd[ arr[i] ].innerHTML = '' : ''; this.iCount--; this.count( arr[i] ); }; }; }else{ //当前点击格子周围有炸弹则显示炸弹个数 this.aTd[iNow].innerHTML = iNum; this.aTd[iNow].style.color = '#333333'; this.aTd[iNow].style.webkitAnimation = 'round 1s 1'; this.aTd[iNow].className == 'mask' ? (this.aTd[iNow].className = '',this.iCount--) : ''; }; } }; </script> </body> </html>
完整实例代码点击此处本站下载。
更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《JavaScript数据结构与算法技巧总结》、《JavaScript数学运算用法总结》、《JavaScript切换特效与技巧总结》、《JavaScript查找算法技巧总结》、《JavaScript动画特效与技巧汇总》、《JavaScript错误与调试技巧总结》及《JavaScript遍历算法与技巧总结》
希望本文所述对大家JavaScript程序设计有所帮助。
上一篇: AngularJS封装指令方法详解
相关文章
使用PHP+JavaScript将HTML页面转换为图片的实例分享
这篇文章主要介绍了使用PHP+JavaScript将HTML元素转换为图片的实例分享,文后结果的截图只能体现出替换的字体,也不能说将静态页面转为图片可以加快加载,只是这种做法比较interesting XD需要的朋友可以参考下...2016-04-19- 在昨天的《Javascript权威指南》学习笔记之十:ECMAScript 5 增强的对象模型一文中,对于一段代码的调试出现了一个奇怪现象,现将源代码贴在下面: 复制代码 代码如下: <script type="text/javascript"> function Person(){}...2014-05-31
- 最近做一个小项目不可避免的需要前端脚本与后台进行交互。由于是在asp.net中实现,故问题演化成asp.net中jiavascript与后台c#如何进行交互。...2020-06-25
- 复制代码 代码如下: //element:需要添加新样式的元素,value:新的样式 function addClass(element, value ){ if (!element.className){ element.className = value; }else { newClassName = element.className; newClas...2014-05-31
- 在javascritp中,不一定只有对象方法的上下文中才有this, 全局函数调用和其他的几种不同的上下文中也有this指代。 它可以是全局对象、当前对象或者任意对象,这完全取决于函数的调用方式。JavaScript 中函数的调用有以下...2015-03-15
- 首先,我想到的是另建一个结果数组,用来存储原始数组中不重复的数据。遍历原始数组依次跟结果数组中的元素进行比较,检测是否重复。于是乎,我写出了如下代码A: Array.prototype.clearRepetitionA = function(){ var resul...2015-11-08
- 这篇文章主要介绍了JavaScript预解析,对象的的相关资料,小编觉得这篇文章写的还不错,需要的朋友可以参考下,希望能够给你带来帮助...2021-11-10
- 事件触发器从字面意思上可以很好的理解,就是用来触发事件的,但是有些没有用过的朋友可能就会迷惑了,事件不是通常都由用户在页面上的实际操作来触发的吗?这个观点不完全正确,因为有些事件必须由程序来实现,如自定义事件,jQue...2014-06-07
- 有一道js面试题,题目是这样的:下列代码的执行结果是什么,为什么? 复制代码 代码如下: var i, j, k; for (i=0, j=0; i<10, j<6; i++, j++) { k = i+j; } document.write(k); 答案是显示10,这道题主要考察JavaScript的逗...2015-03-15
JavaScript学习笔记整理_setTimeout的应用
下面小编就为大家带来一篇JavaScript学习笔记整理_setTimeout的应用。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2016-10-03- 这篇文章主要介绍了Javascript类型转换的规则实例解析,涉及到javascript类型转换相关知识,对本文感兴趣的朋友一起学习吧...2016-02-27
- 通过 HTML DOM,可访问 JavaScript HTML 文档的所有元素。 HTML DOM (文档对象模型) 当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model)。 HTML DOM 模型被构造为对象的树: 通过可编程的对象模型,Java...2015-10-23
- 1、ActiveX向Javascript传参 复制代码 代码如下: <script language="javascript" for="objectname" event="fun1(arg)"> fun2(arg); </script> objectname为ActiveX控件名,通过<object>标签里的id属性设定,如下; 复制...2014-06-07
JavaScript中的数组遍历forEach()与map()方法以及兼容写法介绍
下面小编就为大家带来一篇JavaScript中的数组遍历forEach()与map()方法以及兼容写法介绍。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2016-05-20- Window有navigator对象让我们得知浏览器的全部信息.我们可以利用一系列的API函数得知浏览器的信息.JavaScript代码如下:function message(){ txt = "<p>浏览器代码名: " + navigator.appCodeName + "</p>";txt+= "<p>...2015-11-24
- 这篇文章主要为大家介绍了JavaScript设计模式中的装饰者模式,对JavaScript设计模式感兴趣的小伙伴们可以参考一下...2016-01-21
- 神马是“解释器模式”?先翻开《GOF》看看Definition:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。在开篇之前还是要科普几个概念: 抽象语法树: 解释器模式并未解释如...2014-06-07
- 虽然ES6都还没真正发布,但已经有用ES6重写的程序了,各种关于ES789的提议已经开始了,这你敢信。潮流不是我等大众所能追赶的。潮流虽然太快,但我们不停下学习的步伐,就不会被潮流丢下的,下面来领略下ES6中新特性,一堵新生代JS...2015-11-24
- 这篇文章主要介绍了JS中的compose函数和pipe函数用法,想深入了解Javascript的同学,可以参考下...2021-04-27
- ---恢复内容开始---1.location.href.....(1)self.loction.href="http://www.cnblogs.com/url" window.location.href="http://www.cnblogs.com/url" 以上两个用法相同均为在当前页面打开URL页面 (2)this.locati...2015-10-30