原生JS之掃雷
阿新 • • 發佈:2018-10-31
注:所有程式碼是根據網上教程所編寫
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>掃雷</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="wrapper"> <div class="btn" id="btn"></div> <div class="box" id="box"></div> <div class="flag" id="flag"> 當前剩餘累數: <span id="score">10</span> </div> <div class="alertBox" id="alertBox"> <div class="alertImg" id="alertImg"> <div class="close" id="close"></div> </div> </div> </div> <script src="sl.js"></script> </body> </html>
css程式碼
*{ margin: 0; padding: 0; } .wrapper{ width: 100%; height: 1000px; position: fixed; top:0; left: 0; background-image:url('img/bg.jpg') ; background-size: 100% 100%; } .btn{ height: 80px; width: 170px; position: absolute; left:50%; margin-left:-85px; top:75%; background-image:url('img/start.gif') ; background-size: 100% 100%; cursor: pointer; } .box{ height: 500px; width: 500px; /* 設定景深800px 繞x軸旋轉45°*/ transform: perspective(500px) rotateX(45deg) ; margin: 100px auto; /* border:1px solid #B25F27; */ border-top:1px solid #B25F27; border-left: 1px solid #B25F27; /* 設定邊框陰影 */ box-shadow: 5px 5px 5px rgba(0,0, 0, 0.3); display: none; } .flag{ position: absolute; top:150px; left:50%; width: 200px; height: 50px; margin-left:-100px; color: #333333; font-size: 20px; font-weight: bolder; display: none; } .alertBox{ display: none; position: absolute; width: 100%; height: 100%; left: 0; top:0; background-color: rgba(0,0, 0, 0.2); } .alertImg{ height: 400px; width: 600px; background-size: 100% 100%; position: absolute; left: 0; right: 0; top:20%; margin: auto; border-radius: 20px; } .close{ position: absolute; right: 0; top:0; height: 30px; width: 30px; background-image: url('img/x.jpg'); background-size: 100% 100%; cursor: pointer; border-radius: 20px; } .block{ float: left; width: 49px; height: 49px; border-right: 1px solid #B25F27; border-bottom: 1px solid #B25F27; /* 向內陰影 */ box-shadow: 0 0 4px #333333 inset; background-image: url('img/green.jpg'); background-size: 100% 100%; cursor: pointer; } .show{ background-image: url('img/mine.jpg'); background-size: 100% 100%; } .num{ background: #ECD0A1; font-size: 18px; font-weight: bold; line-height: 49px; text-align: center; } .flagbox{ background-image: url('img/flag.jpg'); background-size: 100% 100%; }
js部分
編碼的邏輯思路
點選開始遊戲 動態生成100個格子-->100div
leftClick沒有雷 顯示數字(代表以當前格子為中心,周圍8個格子的雷個數) 有雷 遊戲結束
擴散(當前周圍沒有雷)
rightClick 沒有標記並且沒有數字--進行標記/有標記--取消標記 判斷標記是否正確,所有都正確標記,提示成功
已經出現數字--不進行任何操作
程式碼
var startBtn=document.getElementById('btn'); var box=document.getElementById('box'); var flag=document.getElementById('flag'); var alertBox=document.getElementById('alertBox'); var alertImg=document.getElementById('alertImg'); var close=document.getElementById('close'); var score=document.getElementById('score'); var minesNum;//雷的數量 var minesOver;//被標記的雷的數量 var block;//選中的格子 var mineMap=[]; var startGame=true; bindEvent(); function bindEvent(){ startBtn.onclick=function(){ if(startGame){ box.style.display='block'; flag.style.display='block'; init(); startGame=false; } } //取消預設事件 box.oncontextmenu=function(){ return false; } box.onmousedown=function(e){ //獲取事件原物件 即當前點選的格子 var event=e.target; //e.which==1代表點選左鍵 if(e.which==1){ leftClick(event); }//e.which==3代表點選右鍵 else if(e.which==3){ rightClick(event); } } close.onclick=function(){ alertBox.style.display='none'; flag.style.display='none'; box.style.display='none'; box.innerHTML=''; startGame=true; } } //生成100個格子 並隨機生成10個雷區 function init(){ minesNum=10; minesOver=10; score.innerHTML=minesOver; for(var i=0;i<10;i++){ for(var j=0;j<10;j++){ var con=document.createElement('div'); //給生成的每個div新增類名 con.classList.add('block'); //用行和列表示每一個格子的id con.setAttribute('id',i+'-'+j); //將生成的格子插入box裡 box.appendChild(con); mineMap.push({mine:0}); } } block=document.getElementsByClassName('block'); //隨機生成雷區 while(minesNum){ var mineIndex=Math.floor(Math.random()*100); if(mineMap[mineIndex].mine==0){ mineMap[mineIndex].mine=1;//表示已經生成雷區 block[mineIndex].classList.add('ismine'); minesNum--; } } } //dom表示點選事件的原物件 function leftClick(dom){ //插旗後 不能被左點選 if(dom.classList.contains('flagbox')){ return ; } var ismine=document.getElementsByClassName('ismine'); if(dom&& dom.classList.contains('ismine')){ //遊戲失敗的情況 for(var i=0;i<ismine.length;i++){ ismine[i].classList.add('show'); } setTimeout(function(){ alertBox.style.display='block'; alertImg.style.backgroundImage='url("img/over.jpg")'; },500) } else { var n=0;//表示點選的格子周圍的雷的個數 var posArr = dom && dom.getAttribute('id').split('-'); var posX = posArr && +posArr[0];//x軸座標值 var posY = posArr&& +posArr[1];//y軸座標值 dom && dom.classList.add('num'); //座標i,j周圍的關係 //i-1,j-1 i-1,j i-1,j+1 //i,j-1 i,j i,j+1 //i+1,j-1 i+1,j i+1,j+1 for(var i=posX-1;i<=posX+1;i++){ for(var j=posY-1;j<=posY+1;j++){ var aroundBox = document.getElementById(i+'-'+j); //aroundBox.classList.contains('ismine') 表示類名為ismine if(aroundBox&&aroundBox.classList.contains('ismine')){ n++; } } } dom && (dom.innerHTML=n); if(n==0){ for(var i=posX-1;i<=posX+1;i++){ for(var j=posY-1;j<=posY+1;j++){ var nearBox=document.getElementById(i+'-'+j); if(nearBox&&nearBox.length!=0){ //判斷格子是否被點選或者已經顯示數字 if(!nearBox.classList.contains('check')){ nearBox.classList.add('check') leftClick(nearBox); } } } } } } } function rightClick(dom){ //判斷是否已經顯示數字 如果已經顯示數字 則不做任何操作 if(dom.classList.contains('num')){ return ; } //toggle切換 如果沒有flagbox類名,則加上,反之則去掉 dom.classList.toggle('flagbox'); if(dom.classList.contains('ismine')&&dom.classList.contains('flagbox')){ minesOver--; } if(dom.classList.contains('ismine')&&!dom.classList.contains('flagbox')){ minesOver++; } score.innerHTML=minesOver; if(minesOver==0) { alertBox.style.display='block'; alertImg.style.backgroundImage='url("img/success.jpg")'; } }