文章目錄
-
-
- 實驗原理:
- 實驗步驟:
-
- 1、頁面布局
- 2、添加樣式
- 3、遊戲初始化
- 4、讓黑塊動起來
- 5、點選黑塊事件
- 6、js完整代碼
-
别踩白塊這個遊戲相信很多人都在手機上玩過,今天來做一個網頁版的,主要涉及通過 javascript 操作元素節點的增删以及屬性節點(class)的操作。
先上一張遊戲效果圖:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2YfNWawNiZpdmLwUDO1QDMzAjMzEzMwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.gif)
實驗原理:
将每一個黑塊和白塊抽象成一個個的資料結構,黑塊的消失和出現其實就是資料結構的創造和銷毀。
實驗步驟:
1、頁面布局
可以用 div+css 布局來實作别踩白塊的靜态效果展示,将主界面分解成一個 4x4 的大矩形格子,每一個方塊代表其中一個小的矩形格,其中每一行的四個白塊中有一個黑塊,每一行中黑塊位于哪一列是随機生成的,但是我們這裡現在是靜态頁面就自己确定了,然後通過 css 控制樣式。
建立 index.html 檔案,并輸入以下代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>别踩白塊</title>
<link rel="stylesheet" href="css/index.css" />
</head>
<body>
<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>
</body>
<script src="js/index.js"></script>
</html>
2、添加樣式
建立 css/index.css 檔案,并輸入以下代碼:
#main {
width: 408px;
height: 408px;
background: white;
border: 2px solid gray;
margin: 0 auto;
overflow: hidden;
}
h2 {
text-align: center;
}
#con {
width: 100%;
height: 400px;
position: relative;
top: -408px; /*隐藏所有格子*/
border-collapse: collapse;
}
/* 行 */
.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;
}
3、遊戲初始化
根據前面的 HTML 部分我們可以知道,每個 < div class=“cell”> 就代表一個白塊,< div class=“cell black”> 就代表一個黑塊,每點選一個黑塊消失其實是删除了一個 < div class=“row”> 然後從上面添加一個新的 < div class=“row”> 是以我們首先要通過 js 來控制 < div class=“row”> 的創造和生成(記得删除在編寫靜态頁面時候指定生成的 4 個 div.row)。具體方法如下:
删除之前寫的 4 個 div.row,将 index.html 檔案改為以下代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>别踩白塊</title>
<link rel="stylesheet" href="css/index.css" />
</head>
<body>
<h2>score</h2>
<h2 id="score">0</h2>
<div id="main">
<div id="con"></div>
</div>
<div class="btn">
<button class="start" onclick="start()">
開始遊戲
</button>
</div>
</body>
<script src="js/index.js"></script>
</html>
對遊戲進行初始化,在 js/index.js 檔案中寫入以下代碼:
// 建立div, className是其類名
function creatediv(className) {
var div = document.createElement('div');
div.className = className;
return div;
}
// 創造一個<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 < 4; i++) {
row.appendChild(creatediv(arr[i])); //添加row的子節點 cell
}
if (con.firstChild == null) {
con.appendChild(row);
} else {
con.insertBefore(row, con.firstChild);
}
}
//删除div#con的子節點中最後那個<div class="row">
function delrow() {
var con = $('con');
if (con.childNodes.length == 6) {
con.removeChild(con.lastChild);
}
}
// 建立一個類名的數組,其中一個為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;
}
4、讓黑塊動起來
在可以通過 js 來創造和銷毀 div 後,我們就要讓黑塊動起來,這個時候我們就用到了之前 css 提到的設定 < div id=“con”> 隐藏了一行的 < div id=“row”>,我們通過 js 的 DOM 操作使其向下方移動,并設定定時器每 30 毫秒移動一次,這樣就實作了黑塊的平滑移動,在黑塊移動的同時,我們要判斷黑塊是否已經觸底,觸底則遊戲失敗,停止調用 move(),觸底後調用函數 fail() 遊戲失敗,具體方法如下:
//讓黑塊動起來
function move() {
var con = $('con');
var top = parseInt(window.getComputedStyle(con, null)['top']);
if (speed + top > 0) {
top = 0;
} else {
top += speed;
}
con.style.top = top + 'px'; //不斷移動top值,使它動起來
over();
if (top == 0) {
createrow();
con.style.top = '-102px';
delrow();
}
}
// 加速函數
function speedup() {
speed += 2;
if (speed == 20) {
alert('你超神了');
}
}
// 判斷遊戲是否結束
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);
flag = false;
confirm('你的最終得分為 ' + parseInt($('score').innerHTML));
var con = $('con');
con.innerHTML = '';
$('score').innerHTML = 0;
con.style.top = '-408px';
}
5、點選黑塊事件
讓黑塊動起來之後,我們就來考慮怎麼判斷使用者有沒有點選到黑塊呢,同時使用者若點選到黑塊,我們要讓所在那一行消失,那麼我們需要一個 judge 方法,具體如下:
// 判斷是否點選黑塊、白塊
function judge(ev) {
if (
ev.target.className.indexOf('black') == -1 &&
ev.target.className.indexOf('cell') !== -1
) {
ev.target.parentNode.pass1 = 1; //定義屬性pass,表示此行row的白塊已經被點選
}
if (ev.target.className.indexOf('black') !== -1) {
//點選目标元素 類名中包含 black 說明是黑塊
ev.target.className = 'cell';
ev.target.parentNode.pass = 1; //定義屬性pass,表明此行row的黑塊已經被點選
score();
}
}
6、js完整代碼
// 工具封裝
// 根據id來擷取元素
function $(id) {
return document.getElementById(id);
}
// 建立div, className是其類名
function creatediv(className) {
var div = document.createElement('div');
div.className = className;
return div;
}
var clock = null;
var state = 0;
var speed = 6;
var flag = false;
//點選開始遊戲按鈕 開始遊戲
function start() {
if (!flag) {
init();
} else {
alert('遊戲已經開始,無須再次點選!');
}
}
/*
* 初始化 init
*/
function init() {
flag = true;
for (var i = 0; i < 4; i++) {
createrow();
}
// 添加onclick事件
$('main').onclick = function (ev) {
ev = ev || event;
judge(ev);
};
// 定時器 每30毫秒調用一次move()
clock = window.setInterval('move()', 30);
}
// 判斷是否點選黑塊、白塊
function judge(ev) {
if (
ev.target.className.indexOf('black') == -1 &&
ev.target.className.indexOf('cell') !== -1
) {
ev.target.parentNode.pass1 = 1; //定義屬性pass,表示此行row的白塊已經被點選
}
if (ev.target.className.indexOf('black') !== -1) {
//點選目标元素 類名中包含 black 說明是黑塊
ev.target.className = 'cell';
ev.target.parentNode.pass = 1; //定義屬性pass,表明此行row的黑塊已經被點選
score();
}
}
// 判斷遊戲是否結束
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);
flag = false;
confirm('你的最終得分為 ' + parseInt($('score').innerHTML));
var con = $('con');
con.innerHTML = '';
$('score').innerHTML = 0;
con.style.top = '-408px';
}
// 創造一個<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 < 4; i++) {
row.appendChild(creatediv(arr[i])); //添加row的子節點 cell
}
if (con.firstChild == null) {
con.appendChild(row);
} else {
con.insertBefore(row, con.firstChild);
}
}
// 建立一個類名的數組,其中一個為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;
}
//讓黑塊動起來
function move() {
var con = $('con');
var top = parseInt(window.getComputedStyle(con, null)['top']);
if (speed + top > 0) {
top = 0;
} else {
top += speed;
}
con.style.top = top + 'px'; //不斷移動top值,使它動起來
over();
if (top == 0) {
createrow();
con.style.top = '-102px';
delrow();
}
}
// 加速函數
function speedup() {
speed += 2;
if (speed == 20) {
alert('你超神了');
}
}
//删除某行
function delrow() {
var con = $('con');
if (con.childNodes.length == 6) {
con.removeChild(con.lastChild);
}
}
// 記分
function score() {
var newscore = parseInt($('score').innerHTML) + 1; //分數加一
$('score').innerHTML = newscore; //修改分數
if (newscore % 10 == 0) {
//當分數是10 的倍數時使用加速函數,越來越快
speedup();
}
}