一:效果图:
二:资源
js扫雷小游戏源代码下载地址
js贪吃蛇小游戏链接
python小黄脸大战小游戏链接
vue高仿网易云音乐app
三:源代码:
html部分:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><link rel="stylesheet" href="css/index.css"></head><body><div id="main"><div class="level"><button class="active">初级</button><button>中级</button><button>高级</button><button>重新开始</button></div><div class="gameBox"></div><div class="info">剩余雷数:<span class="mineNum"></span></div></div><script src="js/index.js"></script></body></html>
css部分:
#main{margin: 100px auto;}.level{text-align: center;margin-bottom: 10px}.level button{padding: 5px 15px;background: #1565C0;border: none;color: #fff;border-radius: 3px;outline: none;cursor: pointer;}.level button.active{background: #00abff;}table{border-spacing: 1px;background-image: linear-gradient(to bottom right, #B3E5FC, #3644BE);margin: 0 auto;}td{padding: 0;width: 20px;height: 20px;background: rgba(255,255,255,0);border: 2px solid;border-color: #95CCF6 #3644BE #3644BE #95CCF6;text-align: center;line-height: 20px;}td.zero{border-color: #E1F5FE;background: #E1F5FE;}td.one{border-color: #E1F5FE;background: #E1F5FE;color: #0332fe;}td.two{border-color: #E1F5FE;background: #E1F5FE;color: #019f02;}td.three{border-color: #E1F5FE;background: #E1F5FE;color: #ff2600;}td.four{border-color: #E1F5FE;background: #E1F5FE;color: #93208f;}td.five{border-color: #E1F5FE;background: #E1F5FE;color: #ff7f29;}td.six{border-color: #E1F5FE;background: #E1F5FE;color: #ff3fff;}td.seven{border-color: #E1F5FE;background: #E1F5FE;color: #3fffbf;}td.eight{border-color: #E1F5FE;background: #E1F5FE;color: #22ee0f;}.info{text-align: center;margin-top: 10px;}.mine {background: #E1F5FE url(../img/bg3.png) no-repeat center;background-size:cover;}.flag{background: #E3F2FD url(../img/bg2.png) no-repeat center;background-size:cover;}
js部分:
function Mine(tr,td,mineNum){this.tr = tr; // 行数this.td = td; // 列数this.mineNum = mineNum; // 雷数this.squares = []; // 存储所有方块的信息,它是一个二维数组,按行与列的顺序排放,存取都使用行列的形式this.tds = []; // 存储所有单元格的DOMthis.surplusMine = mineNum // 剩余雷的数量this.allRight = false; // 右击标的小红旗是否全是雷this.parent = document.querySelector('.gameBox');}// 生成n个不重复的数字Mine.prototype.randomNum = function () {var square = new Array(this.tr*this.td);for(var i =0; i<square.length; i++) {square[i]=i;}// console.log(square);square.sort(function(){return 0.5-Math.random()}); // 随机排序return square.slice(0,this.mineNum); }Mine.prototype.init = function () {var rn = this.randomNum(); // 雷在格子里的位置var n = 0; // 用来找到格子对应的索引for(var i = 0; i<this.tr; i++){this.squares[i] = [];for(var j = 0; j<this.td; j++) {// 取一个方块在数组里的数据要使用行与列的形式去取。//找方块周围的方块的时候要用坐标的形式去取。行与列的形式跟坐标的形式x,y是刚好相反的。if(rn.indexOf(n)!=-1){this.squares[i][j]={type:'mine',x:j,y:i}}else{this.squares[i][j]={type:'number',x:j,y:i,value:0}}n++;}}// console.log(this.squares);this.updateNum();this.createDom();this.parent.oncontextmenu = function () {// 禁止鼠标右键菜单显示return false;}// 剩余雷数this.mineNumDom = document.querySelector('.mineNum');this.mineNumDom.innerHTML = this.surplusMine;}Mine.prototype.createDom = function() {var This = this;var table = document.createElement('table');for(var i = 0; i < this.tr; i++){// 行var domTr = document.createElement('tr');this.tds[i] = [];for(var j = 0; j<this.td; j++) {// 列var domTd = document.createElement('td');// domTd.innerHTML = 0;domTd.pos = [i,j]; // 把格子对应的行与列存到格子身上,为了下面通过这个值到数组里取对应的数据domTd.onmousedown = function() {This.play(event, this) // This 指的是实例对象, this指的是点击的那个td}this.tds[i][j] = domTd;// if(this.squares[i][j].type == 'mine'){//domTd.className= 'mine'// }// if(this.squares[i][j].type == 'number'){//domTd.innerHTML = this.squares[i][j].value;// }domTr.appendChild(domTd);}table.appendChild(domTr);}this.parent.innerHTML = '';this.parent.appendChild(table);}// 获取某个格子周围的8个格子Mine.prototype.getAround = function(square){var x = square.x;var y = square.y;var result = []; // 把找到的格子的坐标返回出去(二维数组)// 通过坐标循环九宫格for(var i=x-1; i<=x+1; i++){for(var j=y-1; j<=y+1; j++){if(i<0 || // 格子超出左边范围j<0 || // 格子超出上边范围i>this.td-1 || // 格子超出右边边范围j>this.tr-1 || // 格子超出下边范围(i==x && j==y) || // 当前循环到的格子是自己,this.squares[j][i].type == 'mine' // 周围的格子是个雷){continue;}result.push([j,i]); // 要与行与列的形式返回出去,因为到时候需要用它去取数组里的数据}}return result;}// 更新所有的数字Mine.prototype.updateNum = function(){for(var i=0; i<this.tr; i++){for(var j=0; j<this.td; j++) {// 只更新雷周围的数字if(this.squares[i][j].type == 'number'){continue;}var num = this.getAround(this.squares[i][j]); // 获取到每一个雷周围的数字for(var k=0; k<num.length; k++){this.squares[num[k][0]][num[k][1]].value +=1;}}}}Mine.prototype.play = function(ev,obj) {var This = this;if(ev.which == 1 && obj.className !='flag'){// 用户标完小红旗后,就不能使用左键点击// 点击的是左键// console.log(obj);console.log(this.squares);var curSquare = this.squares[obj.pos[0]][obj.pos[1]];var cl = ['zero','one','two','three','four','five','six','seven','eight'];console.log(curSquare);if(curSquare.type == 'number') {console.log('点到数字')obj.innerHTML = curSquare.value;obj.className = cl[curSquare.value];if(curSquare.value == 0){/* 当用户点到了数字01. 显示自己2. 找四周1. 显示四周,(如果四周的值不为0,那就显示到这里,不需要再找了)2. 如果值为01. 显示自己2. 找四周。。。。。 递归*/obj.innerHTML = '';function getAllZero(square) {var around = This.getAround(square); // 找到了周围的N个格子for(var i =0; i<around.length; i++) {var x = around[i][0]; // 行var y = around[i][1]; // 列This.tds[x][y].className = cl[This.squares[x][y].value];if(This.squares[x][y].value == 0) {// 如果以某个格子为中心找到的格子值为0,那就需要接着调用函数(递归)if(!This.tds[x][y].check){// 给对应的td添加一个属性,这条属性用于决定这个格子有没有被找过。如果找过的话,它的值就为trueThis.tds[x][y].check = true;getAllZero(This.squares[x][y]);}}else{// 如果以某个格子为中心找到的格子值不为0,就显示该数字This.tds[x][y].innerHTML = This.squares[x][y].value;}}}getAllZero(curSquare);}}else{// 点到雷// console.log('点到雷')this.gameOver(obj);}}// 用户点击的是右键if(ev.which == 3) {// 如果右击的是一个数字,那就不能点击if(obj.className && obj.className != 'flag') {return;}obj.className = obj.className == 'flag' ? '':'flag'; // 切换classif(this.squares[obj.pos[0]][obj.pos[1]].type == 'mine') {this.allRight = true;}else{this.allRight = false;}if(obj.className == 'flag') {this.mineNumDom.innerHTML = --this.surplusMine;}else{this.mineNumDom.innerHTML = ++this.surplusMine;}if(this.surplusMine == 0) {// 剩余的雷的数量为0,表示用户已经标完小红旗了。这时候判断游戏是成功还是失败if(this.allRight){alert('恭喜你!游戏通过!');}else{alert('游戏失败!');this.gameOver();}}}}// 游戏失败函数Mine.prototype.gameOver = function (clickTd) {/* 1. 显示所有的雷2. 取消所有格子的点击事件3. 给点中的那个雷标上一个红*/for(var i =0; i<this.tr; i++){for(var j=0; j<this.td; j++){if(this.squares[i][j].type == 'mine'){this.tds[i][j].className = 'mine';}this.tds[i][j].onmousedown = null;}}if(clickTd) {clickTd.style.backgroundColor = '#f00';}}// 菜单栏按钮功能var btns = document.querySelectorAll('.level button');var mine = null; // 用来存储生成的实例var ln =0; //用来处理当前选中的状态var arr = [[9,9,10],[16,16,40],[28,28,99]]; // 不同级别的行数列数和雷数for(let i = 0; i<btns.length-1; i++) {btns[i].onclick = function() {btns[ln].className = '';this.className = 'active';mine = new Mine(...arr[i]);mine.init();ln = i;}}btns[0].onclick();btns[3].onclick = function() {mine.init();}// var mine = new Mine(28,28,99);// mine.init();