最終效果演示:
涉及知識點:
HTML+CSS+JavaScript
元素節點的增刪
屬性節點(class)的操作。
實現流程:
1. 靜態頁面布局:
上中下三部分:①分數;②主界面是4x4的矩形格子;③開始按鈕

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>別踩白塊Demo</title> </head> <link rel="stylesheet" href="css/index.css"/> <body> <h2> <span>score: </span> <span id="score">0</span> </h2> <div id="main"> <div id="con"> <div class="row"> <div class="cell"></div> <div class="cell black"></div> <div class="cell"></div> <div class="cell"></div> </div> <div class="row"> <div class="cell"></div> <div class="cell black"></div> <div class="cell"></div> <div class="cell"></div> </div> <div class="row"> <div class="cell"></div> <div class="cell"></div> <div class="cell black"></div> <div class="cell"></div> </div> <div class="row"> <div class="cell black"></div> <div class="cell"></div> <div class="cell"></div> <div class="cell"></div> </div> </div> </div> <div class="btn"> <button id="start">Start</button> </div> </body> </html>

h2 { text-align: center; } #main { width: 408px; height: 408px; margin: 0 auto; background: white; border: 2px solid gray; overflow: hidden; } #con { width: 100%; height: 400px; position: relative; border-collapse:collapse; /* top: -100px; */ } /* 行 */ .row{ height: 100px; width: 100%; } /* 一個塊 */ .cell{ height: 100px; width: 100px; float: left; border:rgb(54, 74, 129) 1px solid; } /* 黑塊 */ .black { background: black; } /* 開始按鈕 */ .btn { width: 100%; text-align: center; } #start { margin: 20px auto; width: 150px; height: 50px; border-radius: 10px; background: yellowgreen; line-height: 50px; color: #fff; }
2. 動態的插入黑塊白塊:
每次點擊黑塊,其實是刪除了一個 <div class="row">
然后從上面添加一個新的 <div class="row">
所以,刪除靜態頁面布局中寫的4個<div class="row"> ,使用JS來動態添加
黑塊是使用Math.random()函數生成的
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>別踩白塊Demo</title> </head> <link rel="stylesheet" href="css/index.css"/> <body> <h2> <span>score: </span> <span id="score">0</span> </h2> <div id="main"> <div id="con"></div> </div> <div class="btn"> <button id="start">Start</button> </div> </body> </html>

// ========工具封裝:根據id來獲取元素 function $(id) { return document.getElementById(id); } // ========創建div, className是其類名 function creatediv(className) { var div = document.createElement('div'); div.className = className; return div; } // =========創建一個類名的數組,其中一個為黑塊cell black, 其余為白塊cell function creatcell() { var temp = ['cell', 'cell', 'cell', 'cell', ]; var i = Math.floor(Math.random() * 4);//隨機產生黑塊的位置 Math.random()函數參數 0~1的隨機數 temp[i] = 'cell black'; return temp; } // 創造一個<div class="row">並且有四個子節點<div class="cell"> function createrow() { var con = $('con'); var row = creatediv('row'); //創建div className=row var arr = creatcell(); //定義div cell的類名,其中一個為cell black con.appendChild(row); // 添加row為con的子節點 for (var i = 0; i < arr.length; i++) { row.appendChild(creatediv(arr[i])); //添加row的子節點 cell } //從上面添加新的row if (con.firstChild == null) { con.appendChild(row); } else { con.insertBefore(row, con.firstChild); } }
3. 讓黑塊下落:
①利用top值移動<div id="con">區域,不斷改變top值,從而產生下落的效果

var speed=4; //默認下移速度 //黑塊向下移動 function move(e) { var con = $('con'); //獲取con的top值 var top = parseInt(window.getComputedStyle(con, null)['top']); if(speed + top > 0){ top = 0; }else{ top += speed; } con.style.top = top + 'px';//不斷移動top值,使它動起來 if(top == 0){ createrow();// 下降結束一行,則在最頂部增加一行,完成下降的連續性 con.style.top = '-100px';//並重新隱藏新加的一行 }else{ top += speed; } }
②將展示過后的每一行移除
從上圖可知, <div class="row">越來越多,為了防止其占據內存,並能夠保留 row的數量最多為5(能保證移動的連續性),
那么當rows的length為6時就要刪除最后一個row

function move(e) { 。。。 //保留的最多row的數量為5,那么當rows的length為6時就要刪除最后一個row if($('con').childNodes.length==6){ $('con').removeChild($('con').lastChild); } 。。。 }
③判斷黑塊下落有沒有觸底(通過pass屬性),觸底則游戲結束

//=========判斷黑塊觸底結束 function over() { var rows = $('con').childNodes; if ((rows.length == 5) && (rows[rows.length - 1].pass !== 1)) { fail(); } // for(let i = 0; i < rows.length; i++){ // if(rows[i].pass1 == 1) { // fail(); // } // } }
4. 點擊黑塊事件判斷輸贏:
點擊黑塊,讓其消失的主要原理不是刪除黑塊,而是讓黑塊的顏色變成白色,讓玩家以為黑塊被刪除了 ,其實黑塊還在,只是我們“看不見”了,
當黑塊移動到底端時,判斷包含黑塊的這一行有沒有被點擊過(通過pass屬性)
點到黑塊,讓黑塊的顏色變成白色,分數+1
沒有點到黑塊(點到白塊,黑塊下移觸底),游戲結束
//判斷是否為黑塊 function juge(ev){ var e = ev ||window.event; //點擊目標元素,判斷類名中是否包含 black if(e.target.className.indexOf('black')==-1){ fail();//點到白塊游戲結束 }else{ e.target.className='cell' //讓黑塊顏色變成白色 e.target.parentNode.pass=1;//定義屬性pass,表明此行row的黑塊已經被點擊 AddScore(); } } // 記分,當分數是10 的倍數時加速下移,越來越快 function AddScore() { score+=1; $('score').innerHTML = score; if (score % 10 == 0) { speed+=2; } } // =========游戲結束 function fail() { clearInterval(clock); //清除計時器 alert('Game over!'+'\n'+'Final Score:'+score); $('score').innerHTML = 0; //分數清零 $('con').innerHTML = ""; start_flag = true; $('start').innerHTML = "start"; }
以下是完整代碼:

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>別踩白塊Demo</title> </head> <link rel="stylesheet" href="css/index.css"/> <body> <h2> <span>score: </span> <span id="score">0</span> </h2> <div id="main"> <div id="con"></div> </div> <div class="btn"> <button id="start">Start</button> </div> </body> <script src="js/index.js"></script> </html>

h2 { text-align: center; } #main { width: 408px; height: 408px; margin: 0 auto; background: white; border: 2px solid gray; overflow: hidden; } #con { width: 100%; height: 400px; position: relative; border-collapse:collapse; /* top: -100px; */ } /* 行 */ .row{ height: 100px; width: 100%; } /* 一個塊 */ .cell{ height: 100px; width: 100px; float: left; border:rgb(54, 74, 129) 1px solid; } /* 黑塊 */ .black { background: black; } /* 開始暫停按鈕 */ .btn { width: 100%; text-align: center; } #start { margin: 20px auto; width: 150px; height: 50px; border-radius: 10px; background: yellowgreen; line-height: 50px; color: #fff; }

// ========工具封裝:根據id來獲取元素 function $(id) { return document.getElementById(id); } // ========創建div, className是其類名 function creatediv(className) { var div = document.createElement('div'); div.className = className; return div; } // =========創建一個類名的數組,其中一個為黑塊cell black, 其余為白塊cell function creatcell() { var temp = ['cell', 'cell', 'cell', 'cell', ]; var i = Math.floor(Math.random() * 4);//隨機產生黑塊的位置 Math.random()函數參數 0~1的隨機數 temp[i] = 'cell black'; return temp; } // 創造一個<div class="row">並且有四個子節點<div class="cell"> function createrow() { var con = $('con'); var row = creatediv('row'); //創建div className=row var arr = creatcell(); //定義div cell的類名,其中一個為cell black con.appendChild(row); // 添加row為con的子節點 for (var i = 0; i < arr.length; i++) { row.appendChild(creatediv(arr[i])); //添加row的子節點 cell } //從上面添加新的row if (con.firstChild == null) { con.appendChild(row); } else { con.insertBefore(row, con.firstChild); } } //全局變量 var score=0; //分數初始值0 var speed=4; //默認下移速度 var clock=null; //定時器 var start_flag = true;//開始按鈕的狀態 //黑塊向下移動 function move(e) { var con = $('con'); //獲取con的top值 var top = parseInt(window.getComputedStyle(con, null)['top']); if(speed + top > 0){ top = 0; }else{ top += speed; } con.style.top = top + 'px';//不斷移動top值,使它動起來 //保留的最多row的數量為5,那么當rows的length為6時就要刪除最后一個row if($('con').childNodes.length==6){ $('con').removeChild($('con').lastChild); } over(); if(top == 0){ createrow();// 下降結束一行,則在最頂部增加一行,完成下降的連續性 con.style.top = '-100px';//並重新隱藏新加的一行 }else{ top += speed; } } //=========判斷黑塊觸底結束 function over() { var rows = $('con').childNodes; if ((rows.length == 5) && (rows[rows.length - 1].pass !== 1)) { fail(); } // for(let i = 0; i < rows.length; i++){ // if(rows[i].pass1 == 1) { // fail(); // } // } } // =========游戲結束 function fail() { clearInterval(clock); //清除計時器 alert('Game over!'+'\n'+'Final Score:'+score); $('score').innerHTML = 0; //分數清零 $('con').innerHTML = ""; start_flag = true; $('start').innerHTML = "start"; } //判斷是否為黑塊 function juge(ev){ var e = ev ||window.event; //點擊目標元素,判斷類名中是否包含 black if(e.target.className.indexOf('black')==-1){ fail();//點到白塊游戲結束 }else{ e.target.className='cell' //讓黑塊顏色變成白色 e.target.parentNode.pass=1;//定義屬性pass,表明此行row的黑塊已經被點擊 AddScore(); } } // 記分,當分數是10 的倍數時加速下移,越來越快 function AddScore() { score+=1; $('score').innerHTML = score; if (score % 10 == 0) { speed+=2; } } //開始游戲 $('start').onclick=function(ev){ if(start_flag){ score=0; speed=4; clock=setInterval('move()',50); $('con').onclick=function(ev){ juge(ev); } $('start').innerHTML = "playing games"; start_flag = false; } }