扫雷游戏的规则很简单:
游戏面板上有一些格子,每个格子中有一个数字(空白表示数字为 0)或是地雷,格子中的数字表示格子周围格子中地雷的数量。玩家要做的就是把数字格子找出来,时间花的越少越好。
除边界上的格子外,每个格子周围有 8 个格子:上、下、左、右、4 个斜角。所以数字范围是 0~8。
所以我们的算法如下:
根据用户选择的难易程度(有初、中、高三个级别,级别越高地雷和格子数量越多),随机产生一定个数的地雷并随机放在格子中。然后遍历格子,计算每个格子中的数字,标记在格子上。玩家左键点击格子时显示格子内容(如果遇到地雷则挑战失败,游戏结束),右键点击格子时标记格子为地雷,真到正确标记所有地雷并打开所有非地雷格子,挑战成功,游戏结束。
小技巧:由于格子中数字范围是 0~8,所以为了便于计算,我们可以把地雷所在的格子中的数字记为 9。
我们分4个步骤
首先我们需要有一个面板来显示游戏信息,包括剩余地雷个数、所用时间、难度级别等。因为格子数量不是固定的,所以我们先不画格子,放在 JS 代码中绘制。
创建 index.html 文件
添加如下代码并保存:
JavaScript版扫雷
然后需要调整面板上游戏信息的位置,添加一些样式,在 index.css 中添加如下代码并保存:
.main { margin:10px auto; padding:20px; background:#EEE; width:600px; zoom:1; } .main table { background:#CCC; float:left; } .main table td { border:2px outset #EEE; font-size:20px; width:32px; height:32px; text-align:center; cursor:pointer; } .main table td:hover { background-color:#AAA; } .main #operation { width:180px; float:right; text-align:center; } .landMine { background-image:url(mine.png); background-position:center; background-repeat:no-repeat; } .main table td.normal { border:2px solid #EEE; background-color:#AAA; } .main table td.normal:hover { background-color:#AAA; } .flag { background-image:url(flag.png); background-position:center; background-repeat:no-repeat; } .main:after { clear: both; display: block; content: ""; line-height: 0; height: 0; visibility:hidden; } .main .tip { font-size:14px; margin:5px; } .main .tip ul { } .main .tip ul li { margin:5px 0; line-height:20px; } .main .light{ font-size:30px; } .main .red { color:red; } .main .f60 { color:#F60; } .main input[type=button] { padding:2px 10px; margin:5px; font-size:20px; cursor:pointer; } .main .txtleft { text-align:left; } .main input[type='radio'], .main fieldset label { cursor:pointer; } .main fieldset { margin:10px 0; line-height:25px; }
画格子需要传入一些参数,如放格子的表格的 id,格子的数量(用行数和列数表示)。另外,游戏的其他数据也要进行初始化。
在 jms.js 中添加如下代码并保存:
//在jms.js中 (function () { var JMS = function (id,rowCount,colCount, minLandMineCount, maxLandMineCount) { if (!(this instanceof JMS)) return new JMS(id, rowCount, colCount, minLandMineCount, maxLandMineCount); this.doc = document; this.table = this.doc.getElementById(id);//画格子的表格 this.cells = this.table.getElementsByTagName("td");//小格子 this.rowCount = rowCount || 10;//格子行数 this.colCount = colCount || 10;//格子列数 this.landMineCount = 0;//地雷个数 this.markLandMineCount = 0;//标记的地雷个数 this.minLandMineCount = minLandMineCount || 10;//地雷最少个数 this.maxLandMineCount = maxLandMineCount || 20;//地雷最多个数 this.arrs = [];//格子对应的数组 this.beginTime = null;//游戏开始时间 this.endTime = null;//游戏结束时间 this.currentSetpCount = 0;//当前走的步数 this.endCallBack = null;//游戏结束时的回调函数 this.landMineCallBack = null;//标记为地雷时更新剩余地雷个数的回调函数 this.doc.oncontextmenu = function () {//禁用右键菜单 return false; }; this.drawMap(); }; JMS.prototype = { //画格子 drawMap: function () { var tds = []; if (window.ActiveXObject && parseInt(navigator.userAgent.match(/msie ([d.]+)/i)[1]) < 8) { var css = '#JMS_main table td{background-color:#888;}', head = this.doc.getElementsByTagName("head")[0], style = this.doc.createElement("style"); style.type = "text/css"; if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(this.doc.createTextNode(css)); } head.appendChild(style); } for (var i = 0; i < this.rowCount; i++) { tds.push(""); for (var j = 0; j < this.colCount; j++) { tds.push(" "); } tds.push(""); } this.setTableInnerHTML(this.table, tds.join("")); }, //添加HTML到Table setTableInnerHTML: function (table, html) { if (navigator && navigator.userAgent.match(/msie/i)) { var temp = table.ownerDocument.createElement('p'); temp.innerHTML = ' ' + html + '
'; if (table.tBodies.length == 0) { var tbody = document.createElement("tbody"); table.appendChild(tbody); } table.replaceChild(temp.firstChild.firstChild, table.tBodies[0]); } else { table.innerHTML = html; } } }; window.JMS = JMS; })();上面的代码中,部分代码是为了兼容 IE 浏览器,可忽略。
在 index.js 的调用代码中,我们需要绑定难度选择按钮的事件,然后调用上面定义的 JMS,开始绘制格子。
在 index.js 中添加如下代码并保存:
//在index.js中 var jms = null, timeHandle = null; window.onload = function () { var radios = document.getElementsByName("level"); for (var i = 0, j = radios.length; i < j; i++) { radios[i].onclick = function () { if (jms != null) if (jms.landMineCount > 0) if (!confirm("确定结束当前游戏?")) return false; var value = this.value; init(value, value, value * value / 5 - value, value * value / 5); document.getElementById("JMS_main").style.width = value * 40 + 180 + 60 + "px"; } } init(10, 10); }; function init(rowCount, colCount, minLandMineCount, maxLandMineCount) { var doc = document, landMineCountElement = doc.getElementById("landMineCount"), timeShow = doc.getElementById("costTime"), beginButton = doc.getElementById("begin"); if (jms != null) { clearInterval(timeHandle); timeShow.innerHTML = 0; landMineCountElement.innerHTML = 0; } jms = JMS("landmine", rowCount, colCount, minLandMineCount, maxLandMineCount); }现在,我们开始对游戏初始化,主要分三步:
- 把所有格子(代码中用一个数组表示)初始化为 0
- 随机生成地雷个数,把地雷随机放到数组中,数组项值设置为 9
- 计算其他格子中的数字,值放入数组中
在 jms.js 中 JMS.prototype 内加入如下代码:
//在jms.js中JMS.prototype内加入 //初始化,一是设置数组默认值为0,二是确定地雷个数 init: function () { for (var i = 0; i < this.rowCount; i++) { this.arrs[i] = []; for (var j = 0; j < this.colCount; j++) { this.arrs[i][j] = 0; } } this.landMineCount = this.selectFrom(this.minLandMineCount, this.maxLandMineCount); this.markLandMineCount = 0; this.beginTime = null; this.endTime = null; this.currentSetpCount = 0; }, //把是地雷的数组项的值设置为9 landMine: function () { var allCount = this.rowCount * this.colCount - 1, tempArr = {}; for (var i = 0; i < this.landMineCount; i++) { var randomNum = this.selectFrom(0, allCount), rowCol = this.getRowCol(randomNum); if (randomNum in tempArr) { i--; continue; } this.arrs[rowCol.row][rowCol.col] = 9; tempArr[randomNum] = randomNum; } }, //计算其他格子中的数字 calculateNoLandMineCount: function () { for (var i = 0; i < this.rowCount; i++) { for (var j = 0; j < this.colCount; j++) { if (this.arrs[i][j] == 9) continue; if (i > 0 && j > 0) { if (this.arrs[i - 1][j - 1] == 9) this.arrs[i][j]++; } if (i > 0) { if (this.arrs[i - 1][j] == 9) this.arrs[i][j]++; } if (i > 0 && j < this.colCount - 1) { if (this.arrs[i - 1][j + 1] == 9) this.arrs[i][j]++; } if (j > 0) { if (this.arrs[i][j - 1] == 9) this.arrs[i][j]++; } if (j < this.colCount - 1) { if (this.arrs[i][j + 1] == 9) this.arrs[i][j]++; } if (i < this.rowCount - 1 && j > 0) { if (this.arrs[i + 1][j - 1] == 9) this.arrs[i][j]++; } if (i < this.rowCount - 1) { if (this.arrs[i + 1][j] == 9) this.arrs[i][j]++; } if (i < this.rowCount - 1 && j < this.colCount - 1) { if (this.arrs[i + 1][j + 1] == 9) this.arrs[i][j]++; } } } }, //获取一个随机数 selectFrom: function (iFirstValue, iLastValue) { var iChoices = iLastValue - iFirstValue + 1; return Math.floor(Math.random() * iChoices + iFirstValue); }, //通过数值找到行数和列数 getRowCol: function (val) { return { row: parseInt(val / this.colCount), col: val % this.colCount }; },接下来的两部分我放在下一篇文章里。
页面更新:2024-05-11
上滑加载更多 ↓Top推荐阅读:更多:本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号