網頁版“别踩白塊”項目 筆記
-
-
- js重點代碼詳解
- 所有完整代碼如下:
-
- index.html
- index.css
- index.js
- 事件對象解釋
- 參考連結
-
js重點代碼詳解
//全局變量
var clock = null;
var speed = 6;
var flag = false; //遊戲的狀态:false代表未開始,true代表已經開始
- 1.create_row()函數,首先要通過js來控制
>及它4個子節點<div class="row"
的生成和删除,友善後面删除掉使用者已經點選過的行,以及從上頂部生成新行。<div class="cell">
//建立一個<div class="row">并且包含四個子節點<div class="cell">
function create_row(){
var content = $('content');//擷取頁面中content這個元素
var row = create_div('row');//建立div,className=row
var arr = create_cell();//定義div cell的類名,其中一個為cell black->黑塊
for(var i=0;i < 4;i++){//添加row的4個子節點div
row.appendChild(create_div(arr[i]));
}
if(content.firstChild == null){
content.appendChild(row); //添加row為content的子節點
}else {
content.insertBefore(row,content.firstChild);
}
}
-
2.初始化函數init():初始建立頁面結構,建立四行四列方塊;
給main綁定點選事件來擷取使用者的點選,點選後判斷使用者點選的是白塊還是黑塊;
讓rows自動下落;
function init(){
flag = true; //标記遊戲已經開始
//1.建立四行
for(var i=0;i < 4;i++){
create_row();
}
//給整個main内容添加onclick事件,一旦裡面發生點選事件則會觸發判斷judge()
$('main').onclick = function(ev){
var ev = ev || event;//擷取事件對象.也就是點選事件
judge(ev);//标記 點中了哪一行的白塊或者黑塊
};
//定時器 每30ms調用一次move(),讓rows下落
clock = window.setInterval('move()',30);
}
- judge(ev):判斷使用者點選的是白塊還是黑塊,然後對應标記那一行pass1=1 or pass=1;此函數标記
,是為了讓每次下落時,都能判斷一下底部一行的黑塊是否被點選。最新的點選狀态
//判斷是否點選白塊、黑塊,點選了則把該行标記pass(黑塊),pass1(白塊) 屬性==1
function judge(ev){
//ev.target擷取的是使用者點選的那一個元素
//檢查點選的這個元素類名是否是黑塊
if(
ev.target.className.indexOf('black') == -1 &&
ev.target.className.indexOf('cell') !== -1
) {
//這裡表示沒點中黑塊,卻點中了白塊
//elementNode.parentNode ==> 擷取指定節點的父節點即<div class="row">
ev.target.parentNode.pass1 = 1; //定義屬性pass1,表示此行row的白塊已被點選
}
if(ev.target.className.indexOf('black') !== -1){
//點選到的是黑塊
ev.target.className = 'cell';//讓它變成白色
ev.target.parentNode.pass = 1;//定義屬性pass,表明此行row的黑塊已被點選
score();//清算分數
}
}
-
3.IsGameOver():規定了遊戲結束條件,結合judge()函數标記的pass,pass1來判斷是否下落到底部的黑塊沒被點選,是否點選了白塊。
此處應結合move()函數一起消化
//判斷遊戲是否結束 ==> 每下落一次,都會判斷一次遊戲是否結束
function IsGameOver(){
var rows = $('content').childNodes;//擷取所有的行
//下落到最後一行,失敗
if(rows.length == 5 && rows[rows.length - 1].pass !== 1){
//最後一行沒點選黑塊,讓遊戲結束
//整個遊戲除了遊戲初始時,是4行;
//除了使用者點選了黑塊,但被點的黑塊完全下落到不見時的瞬間top==0,添加一行後,才是6行,然後又會立馬删掉最後一行,又是5行了;
//其他時候都是5行:這時候才要判斷底行黑塊是否被點選,沒點則失敗
fail();
}
//點選白塊,失敗
for(let i=0;i < rows.length;i++) {
if(rows[i].pass1 == 1) //從上往下,隻要有白塊被點選過,就失敗
fail();
}
}
-
4.move()函數:首先讓其下落speed像素,再判斷此時遊戲是否結束,再判斷是否top==0(隐藏的全部下落到視線),是的話,就建立新行;
并且判斷底部有沒有已經被使用者點選了的隐藏住的黑塊行,有則删除,沒有則不删除。
//讓黑塊動起來
function move(){
var content = $('content');
var top = parseInt(window.getComputedStyle(content,null)['top']);
//speed是全局變量
if(top + speed > 0) {
//因為一開始是top=-408,隐藏了格子,現在要一點點下降
//然後每次消除一行之後,建立的新行也是被隐藏在頂部,top = -102px
top = 0;
}else{ //就說明,隐藏在頂部的還沒下落完,則繼續下落
top += speed;
}
content.style.top = top + 'px'; //不斷移動top值,使它動起來
IsGameOver(); //判斷遊戲是否結束
//top==0 也就是之前被隐藏在頂部的rows全部降落到使用者視線中了,
//如果不繼續建立,就會導緻沒有rows可以下落了
if(top == 0){
//也是遊戲完全開始後,每次move,都判斷top==0?
//==0就代表隐藏在頂部的一行已經完全下落到使用者視線中,然後建立新的一行
create_row();//建立新的一行在頂部
content.style.top = '-102px';//先把它這一行隐藏,再慢慢從上掉落
if(content.childNodes.length == 6){ //隻有使用者成功點選黑塊後,并且等待該行掉落底部不見,才能變成6行
//若上述代碼添加一行後,有6行了,則删除最後一行(這是删除的已被使用者點選過的黑塊行)
del_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> <!--記錄總分的,初始為0-->
<div id="main"> <!--主體塊:包括白塊黑塊内容,友善整個content定位-->
<!--4 x 4的格子 一行四個元素,一共四行 -->
<div id="content"></div>
</div>
<div class="btn">
<button class="start" onclick="start()">
開始遊戲
</button>
</div>
</body>
<script type="text/javascript" src="js/index.js"></script>
</html>
index.css
#main{
width: 408px; /*400是格子,8是格子之間的border*/
height: 408px;
background: white;
border: 2px solid gray;
margin: 0 auto;
overflow: hidden;
}
h2{
text-align: center;
}
#content{
width: 100%;
height: 400px;
position: relative;
top: -408px; /*使用者點選開始前隐藏所有格子*/
border-collapse: collapse;/*表格設定合并邊框模型*/
}
/*行*/
.row{
width: 100%;height: 100px;
}
/*一個塊*/
.cell{
width: 100px;height: 100px;float: left;
border: solid 1px rgb(54, 74, 129);
}
.black{
background: #000;
}
.btn{
width: 100%;
text-align: center;
}
.start{
margin: 20px auto;
width: 150px;
height: 50px;
border-radius: 10px;
background: yellowgreen;
line-height: 50px;
color: #fff;
}
index.js
/*
* 使用者每點選一個黑塊消失其實是删除了一行<div class="row"></div>
* 然後從上面添加一個新的<div class="row"></div>
*
**/
//全局變量
var clock = null;
var speed = 6;
var flag = false; //遊戲的狀态:false代表未開始,true代表已經開始
//根據id來擷取元素
function $(id){
return document.getElementById(id);
}
//建立div,className是其類名
function create_div(className){
var div = document.createElement('div');
div.className = className;
return div;
}
//建立一個類名的數組,其中一個為cell black,其餘為cell
function create_cell(){
var temp = ['cell','cell','cell','cell'];
var i = Math.floor(Math.random()*4);//随機産生黑塊的位置
temp[i] = 'cell black';
return temp;
}
//建立一個<div class="row">并且包含四個子節點<div class="cell">
function create_row(){
var content = $('content');//擷取頁面中content這個元素
var row = create_div('row');//建立div className=row
var arr = create_cell();//定義div cell的類名,其中一個為cell black
//content.appendChild(row); //添加row為con的子節點
for(var i=0;i < 4;i++){//添加row的4個子節點
row.appendChild(create_div(arr[i]));
}
if(content.firstChild == null){
content.appendChild(row);
}else {
content.insertBefore(row,content.firstChild);
}
}
//删除div#content的子節點中最後那個<div class="row">
function del_row(){
var content = $('content');
content.removeChild(content.lastChild);
}
//點選開始遊戲按鈕,開始遊戲
function start(){
if(flag == false) {
init();//進入遊戲初始化
}else {
alert('遊戲已經開始,無須再次點選!');
}
}
/*
* 遊戲初始化函數 init
* */
function init(){
flag = true; //标記遊戲已經開始
//1.建立四行
for(var i=0;i < 4;i++){
create_row();
}
//給整個main内容添加onclick事件,一旦裡面發生點選事件則會觸發判斷judge()
$('main').onclick = function(ev){
var ev = ev || event;//擷取事件對象.也就是點選事件
judge(ev);//标記 點中了哪一行的白塊或者黑塊
};
//定時器 每30ms調用一次move(),讓row下落
clock = window.setInterval('move()',30);
}
//判斷是否點選白塊、黑塊,點選了則把該行标記pass屬性==1
function judge(ev){
//ev.target擷取的是使用者點選的那一塊元素
//對比點選的這個元素類名是否是黑塊
if(
ev.target.className.indexOf('black') == -1 &&
ev.target.className.indexOf('cell') !== -1
) {
//這裡表示沒點中黑塊,卻點中了白塊
//elementNode.parentNode ==> 擷取指定節點的父節點即<div class="row">
ev.target.parentNode.pass1 = 1; //定義屬性pass1,表示此行row的白塊已被點選
}
if(ev.target.className.indexOf('black') !== -1){
//點選到的是黑塊
ev.target.className = 'cell';//讓它變成白色
ev.target.parentNode.pass = 1;//定義屬性pass,表明此行row的黑塊已被點選
score();//清算分數
}
}
//判斷遊戲是否結束 ==> 每下落一次,都會判斷一次遊戲是否結束
function IsGameOver(){
var rows = $('content').childNodes;//擷取所有的行
//下落到最後一行,失敗
if(rows.length == 5 && rows[rows.length - 1].pass !== 1){
//rows.length==5 && 最後一行的pass !==1
//最後一行沒點選黑塊,讓遊戲結束
fail();
}
//點選白塊,失敗
for(let i=0;i < rows.length;i++) {
if(rows[i].pass1 == 1) //從上往下,隻要有白塊被點選過,就失敗
fail();
}
}
//遊戲結束
function fail(){
clearInterval(clock);//關閉定時器
flag = false;
speed = 6;
confirm('你的最終得分為' + parseInt($('score').innerHTML));
var content = $('content');
content.innerHTML = ''; //清除所有的白塊黑塊
$('score').innerHTML = 0;//分數歸零
content.style.top = '-408px'; //又重新隐藏在頂部
}
//讓黑塊動起來
function move(){
var content = $('content');
var top = parseInt(window.getComputedStyle(content,null)['top']);
//speed是全局變量
if(top + speed > 0) {
//因為一開始是top=-408,隐藏了格子,現在要一點點下降
//然後每次消除一行之後,建立的新行也是被隐藏在頂部,top = -102px
top = 0;
}else{ //就說明,隐藏在頂部的還沒下落完,則繼續下落
top += speed;
}
content.style.top = top + 'px'; //不斷移動top值,使它動起來
IsGameOver(); //判斷遊戲是否結束
//top==0 也就是之前被隐藏在頂部的rows全部降落到使用者視線中了,
//如果不繼續建立,就會導緻沒有rows可以下落了
if(top == 0){
//也是遊戲完全開始後,每次move,都判斷top==0?
//==0就代表隐藏在頂部的一行已經完全下落到使用者視線中,然後建立新的一行
create_row();//建立新的一行在頂部
content.style.top = '-102px';//先把它這一行隐藏,再慢慢從上掉落
if(content.childNodes.length == 6){ //隻有使用者成功點選黑塊後,并且等待該行掉落底部不見,才能變成6行
//若上述代碼添加一行後,有6行了,則删除最後一行(這是删除的已被使用者點選過的黑塊行)
del_row();//删除末尾一行
}
}
}
//加速函數
function speed_up(){
speed += 2;
if(speed == 20) {
alert("你超神了");
}
}
function score(){
var newscore = parseInt($('score').innerHTML) + 1;//分數+1
$('score').innerHTML = newscore;//修改分數
if(newscore % 10 == 0) {
//當分數是10的倍數時,使用加速函數,越來越快
speed_up();
}
}
事件對象解釋
事件對象
• 什麼是事件對象?
• 就是當你觸發了一個事件以後,對該事件的一些描述資訊
• 例如:
- 你觸發一個點選事件的時候,你點在哪個位置了,坐标是多少
- 你觸發一個鍵盤事件的時候,你按的是哪個按鈕
• 每一個事件都會有一個對應的對象來描述這些資訊,我們就把這個對象叫做 事件對象
• 我們就得用一種方式來擷取 事件對象,在每一個事件處理函數的行參位置,預設第一個就是 事件對象(ev)
function init(){
flag = true; //标記遊戲已經開始
//1.建立四行
for(var i=0;i < 4;i++){
create_row();
}
//添加onclick事件
$('main').onclick = function(ev){
var ev = ev || event;//擷取事件對象
judge(ev);
};
//定時器 每30ms調用一次move()
clock = window.setInterval('move()',30);
}
3.關于event對象
- 在觸發的事件的函數裡面我們會接收到一個event對象,通過該對象我們需要的一些參數,比如說我們需要知道此事件作用到誰身上了,就可以通過event的屬性
來擷取到(IE暫且不談),或者想阻止浏覽器的預設行為可以通過方法target
來進行阻止.以下是event對象的一些屬性和方法preventDefault()
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TPn5kMZRFZ6x2ViFjTzwEMW1mY1RzRapnTtxkb5ckYplTeMZTTINGMShUYfRHelRHLwEzX39GZhh2css2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3Pn5GcuczNzMTNycTM1ITMwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
參考連結
1.【js】event(事件對象)詳解.
2. js中(event)事件對象.