偶然想到曾經在無智能手機時代,玩過的一款遊戲,遊戲名忘了,只記得內容,遊戲內容是一個猴子在樹木之間跳躍,喫水果,躲炸彈,防蟲子,其他的記不太清,大致是這樣的玩法,似乎是某款諾基亞上的遊戲。。。。。。-_-!!。。。。。。由於執念太強,所以試着用html和原生js寫下,倒是寫出了個半吊子,唔----算是有個小樣子吧。。。先看下游戲展示圖:
接下來是html代碼:
<div class="startGame"> <!-- 遊戲開始大頁面 -->
<img src="img/start.png" alt="" id="startGame"> <!-- 加入遊戲開始按鈕,這裏用圖片代替 -->
</div>
<div class="wrapper" id="wrapper"> <!-- 遊戲開始後進入的主頁面的大頁面 -->
<div class="backgroundTree"> <!-- 在大頁面裏裝入背景—三棵樹 -->
<div class="tree1"></div> <!-- 這裏的樹用圖片表示,在css中寫入,下面的樹相同 -->
<div class="tree2"></div>
<div class="tree3"></div>
</div>
<div class="move" id="move"> <!-- 在大頁面中加入動態因子(猴子,水果,炸彈),由於是動態的,所以在js裏生成顯示,不再這裏直接顯示 -->
<!-- <div class="monkey" id="monkey"></div> --> <!--注: 這是在執行js後,會自動生成的三個節點 -->
<!-- <div class="fruits" id="fruits"></div> -->
<!-- <div class="boom" id="boom"></div> -->
</div>
<div class="scoreBox" id="scoreBox"> <!-- 顯示分數的大頁面 -->
<div class="score">計分:<p id="score">0</p> <!-- 動態計入分數,在js裏寫入變化的分數值 -->
</div>
</div>
</div>
<div class="gameOver" id="gameOver"> <!-- 當遊戲失敗後,顯示的遊戲結束大頁面 -->
<div class="over" id="over"> <!-- 在大頁面中的遊戲結束彈出框,這裏用圖片表示(在css裏寫入圖片) -->
<div class="close" id="close"></div> <!-- 在遊戲結束框里加入關閉按鈕,這裏也用圖片表示(css加入圖片) -->
<div class="scoreOver"><p id="scoreOver"></p></div> <!-- 在遊戲結束框中加入最後的計分 -->
</div>
</div>
接下來css代碼:
*{ /* 寫代碼的習慣,先將所有默認的margin和padding都清0 */
margin: 0;
padding: 0;
}
.startGame{ /* 設置遊戲開始的大頁面 */
width: 100%; /* 100%的寬度 */
height: 609px; /* 根據自己的電腦瀏覽器顯示大小設置的高度 */
position: absolute; /* 設置絕對定位 */
top: 0;
left: 0;
z-index: 1000; /* 顯示在其他頁面的最前面 */
}
.startGame img{ /* 在大頁面中顯示的遊戲開始按鈕 */
width: 300px; /* 根據圖片設置寬高 */
height: 100px;
position: absolute; /* 設置絕對定位,從這裏到下面的margin:auto的設置表示該內容基於父級定位到正中心位置 */
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
.wrapper{ /* 遊戲開始後的主界面的大界面 */
width: 100%; /* 和上述一樣是設置寬高和絕對定位 */
height: 609px;
position: absolute;
top: 0;
left: 0;
}
.backgroundTree{ /* 在大界面中顯示樹的頁面 */
width: 100%; /* 這裏的值和上述設置的一樣,原因往上看,這裏不解釋了 */
height: 609px;
position: absolute;
top: 0;
left: 0;
background-image: url('img/bg1.jpg'); /* 加入背景圖片,記得要和你的樹看起來和諧一點哦 */
background-size: 100% 100%; /* 100%平鋪圖片 */
}
.tree1{ /* 在背景圖片中加入樹的圖片 */
width: 25%; /* 設置樹的寬高,寬佔背景圖片的25% */
height: 609px;
background-image: url('img/tree.png'); /* 加入樹的圖片 */
background-size: 100% 100%; /* 平鋪 */
position: absolute; /* 絕對定位 */
top: 0;
left: 5%; /* 位置距離左邊5% */
}
.tree2{ /* 加入第二個樹的圖片 */
width: 25%; /* 和上述一樣 */
height: 609px;
background-image: url('img/tree.png');
background-size: 100% 100%;
position: absolute;
top: 0;
left: 37.5%; /* 位置距離左邊37.5% */
}
.tree3{ /* 加入第三個樹的圖片 */
width: 25%;
height: 609px;
background-image: url('img/tree.png');
background-size: 100% 100%;
position: absolute;
top: 0;
left: 70%; /* 位置距離左邊70% */
}
.move{ /* 設置動態因子的大頁面 */
width: 100%;
height: 520px; /* 設置你希望的遊戲活動區域大小 */
position: absolute;
top: 60px; /* 設置位置距離上邊60px */
left: 0;
display: none; /* 剛開始時爲不顯示,觸發js(即點擊遊戲開始按鈕後)後更改爲顯示 */
}
.monkey{ /* 設置猴子的大小和初始位置 */
width: 100px;
height: 100px;
background-image: url('img/monkey.png'); /* 加入猴子圖片 */
background-size: 100% 100%;
position: absolute; /* 設置基於父級的絕對定位,距上80px,距左150px */
top: 80px;
left: 150px;
}
.fruits{ /* 設置水果的大小,至於位置在js裏規定 */
width: 150px;
height: 50px;
background-image: url('img/fruits.png'); /* 水果圖片 */
background-size: 100% 100%;
}
.boom{ /* 設置炸彈的大小 ,和上述一樣解釋*/
width: 150px;
height: 50px;
background-image: url('img/zd.png');
background-size: 100% 100%;
display: block; /* 設置顯示爲block */
}
.scoreBox{ /* 在大頁面上的分數顯示盒子 */
width: 100%;
height: 30px;
position: absolute;
top: 0;
left: 0;
}
.score{ /* 在分數盒子裏顯示分數的大小和位置 */
width: 80px;
height: 30px;
line-height: 30px; /* 垂直居中顯示 */
text-align: center;
color: #222; /* 字體爲黑色 */
font-size: 18px; /* 字體大小 */
font-weight: bolder; /* 字體加粗 */
position: absolute; /* 在盒子裏居中顯示 */
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
float: left; /* 向左浮動 */
}
.score p{ /* 動態分數值 */
float: right; /* 向右浮動,使數字和漢字在同一行 */
}
.gameOver{ /* 遊戲結束大頁面 */
width: 100%;
height: 609px;
z-index: 10000; /* 顯示在所有其他頁面的最前面 */
position: absolute;
top: 0;
left: 0;
display: none; /* 剛開始時不顯示,直到js裏的相關事件被觸發 */
}
.over{ /* 在遊戲結束大頁面中顯示遊戲結束圖片框 */
width: 320px; /* 圖片大小自己按需求寫 */
height: 180px;
position: absolute; /* 在大頁面中居中顯示 */
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
background-image: url('img/gameOver.png'); /* 加入遊戲結束的圖片 */
background-size: 100% 100%;
}
.close{ /* 在遊戲結束框里加入關閉按鈕 */
width: 30px; /* 大小自己按需設置 */
height: 30px;
background-image: url('img/shanchu.png'); /* 加入關閉按鈕的圖片 */
background-size: 100% 100%;
position: absolute; /* 設置圖片位置爲基於父級的絕對定位 */
top: 18px; /* 距上邊18px */
right: 18px; /* 距右邊18px */
cursor: pointer; /* 當鼠標移到圖片,原鼠標指示變成小手圖片 */
}
.scoreOver{ /* 設置遊戲結束圖片上所顯示的最終分數 */
width: 80px; /* 分數顯示的範圍寬高 */
height: 30px;
position: absolute; /* 依據圖片設置分數顯示位置 */
top: 118px;
left: 170px;
font-size: 20px; /* 分數大小 */
font-weight: bolder; /* 分數字體加粗 */
color: #000; /* 分數字體顏色白色 */
}
接下是js代碼:
var startGame = document.getElementById('startGame'); //獲取在html中的id = ‘startGame’的節點
var move = document.getElementById('move'); //以下同上解釋
var score = document.getElementById('score');
var over = document.getElementById('over');
var gameOver = document.getElementById('gameOver');
var close = document.getElementById('close');
var scoreOver = document.getElementById('scoreOver');
var scoreBox = document.getElementById('score');
var boom = document.getElementsByClassName('boom');
var k = true; //設置鎖
var number = [150,210,593,653,1036,1096];
var key = 1;
var speed1 = 100;
var speed2 = 80;
var timerf;
var timerb;
begin(); //執行函數begin()
function begin(){ //遊戲開始的默認值設置
this.monkey_top = 80; // 設置this.monkey_top爲(假)猴子位置的高度
this.monkey_left = 150; //設置猴子位置的左邊距離
this.score = 0; //設置初始的分數爲0
monkey = document.createElement("div"); //創建一個(真)猴子(div)
monkey.setAttribute('id','monkey'); //給猴子一個id = 'monkey'
monkey.classList.add('monkey'); //給猴子一個class = “monkey”,用在css設置裏
move.appendChild(monkey); //把猴子插入move節點下,成爲move節點下的子節點,注:這的move是上述從var move裏獲取的id=“move”的節點
bindEvent(); //觸發bindEvent()函數
}
function bindEvent(){ //用來裝所有按鍵鼠標事件
startGame.onclick = function(){ //當點擊遊戲開始按鈕時觸發該事件(注:startGame也是從上述的var startGame裏得到的id節點,以下類似的不再說明)
startGame.style.display = 'none'; // id=‘startGame’的節點display爲none時,表示不顯示該節點內容以及其下的子節點
move.style.display = 'block'; //表示move節點包括其子節點都顯示
food(); //觸發food()函數
bomb(); //觸發bom()函數
}
document.onkeydown = function(e){ //鍵盤事件,用來控制猴子的移動事件
var code = e.keyCode; //用code獲取你所按的按鍵的代表的值
setDerict(code); //將code的值返給setDerict()函數,觸發該函數
}
close.onclick = function(){ //遊戲結束後出現在遊戲結束框右上方的叉叉按鈕的點擊事件
gameOver.style.display = 'none'; //遊戲結束框消失
k = true; //鑰匙k爲true
reStart(); //觸發重新開始遊戲的函數,即reStart()
}
}
function reStart(){ //遊戲重新開始函數
this.monkey_top = 80; //與上述的begin()一樣,重新設置初始值
this.monkey_left = 150;
this.score = 0;
scoreBox.innerHTML = this.score; //將遊戲主界面的分數清0
monkey = document.createElement("div"); //創建一個新的猴子
monkey.setAttribute('id','monkey');
monkey.classList.add('monkey');
move.appendChild(monkey);
key = 1; //鑰匙key初始值爲1
bindEvent(); //重新觸發bindEvent等一系列函數
food();
bomb();
}
function setDerict(code){ //猴子移動方向的控制
switch(code){ //獲取到code的值
case 37: //表示按鍵的方向鍵左
if(key == 2||key == 4||key == 6){ //當key爲2,4,6時引發的事件,注:這裏的key的用意是:由於一顆樹木分左右,而兩顆樹間又有距離,所有的樹左右距離一樣,所有的樹與樹間隔也一樣,但左右和間隔的距離不一樣,所以這裏將其猴子的跳躍分成樹1左,樹1右,樹間,樹2左,樹2右,樹間…,不難找到規律,猴子從左到右爲奇數,從右到樹間爲偶數,因此需要一個key來計入數字
monkey.style.left = this.monkey_left - 60 + 'px'; //當key爲偶數時,猴子的右距離爲原始值右距離減60(這個60是樹的左右直徑)
this.monkey_left = parseInt(getComputedStyle(monkey).left); //此時的原始值要同步改變爲當前的猴子位置的右距
monkey.style.backgroundImage = 'url("img/monkey.png")'; //加入猴子面朝左的圖片
key --; //key減1,變奇數
}else if(key == 3 || key == 5){ //key爲奇數時執行,注這裏沒有1,是因爲這個按鍵是向左的,而猴子剛開始爲的位置就在最左邊,所以key爲1時不能操作向左的按鍵
monkey.style.left = this.monkey_left - 383 + 'px'; //猴子右距-383,這裏的383是兩顆樹之間的距離
this.monkey_left = parseInt(getComputedStyle(monkey).left); //同上
monkey.style.backgroundImage = 'url("img/monkey2.png")'; //面朝右的猴子圖片
key --; //key減1,變偶數
}else{ //因爲樹只有三顆,所以可設置的範圍也就在1-5之間,所以當key爲其他數值時,不觸發事件
;
}
break;
case 38: //上
monkey.style.top = parseInt(getComputedStyle(monkey).top) - 10 + 'px'; //控制猴子向上運動時的移動距離,爲當前距離-10
this.monkey_top = parseInt(getComputedStyle(monkey).top); //實時獲得更改後的猴子上距離
break;
case 39: //右
if(key == 1||key == 3||key == 5){ //這裏的解釋和上述37的一樣,不再不說明,注:這裏有1是由於該按鍵向右,因此可以操作
monkey.style.left = this.monkey_left + 60 + 'px';
this.monkey_left = parseInt(getComputedStyle(monkey).left);
monkey.style.backgroundImage = 'url("img/monkey2.png")';
key ++; //變偶數
}else if(key == 2 || key == 4){ //與上述一樣,不多解釋了
monkey.style.left = this.monkey_left + 383 + 'px';
this.monkey_left = parseInt(getComputedStyle(monkey).left);
monkey.style.backgroundImage = 'url("img/monkey.png")';
key ++;
}else{
;
}
break;
case 40: //下
monkey.style.top = parseInt(getComputedStyle(monkey).top) + 10 + 'px'; //同上含義
this.monkey_top = parseInt(getComputedStyle(monkey).top);
break;
default:
break;
}
}
function food(){ //設置水果函數
var f = Math.floor(Math.random()*6); 先用f來獲取一個0-6的一個隨機數
var monkey_l1 = parseInt(getComputedStyle(monkey).left); //爲下述過程方便,因此將猴子的位置賦給新變量
var monkey_t1 = parseInt(getComputedStyle(monkey).top);
var fruits = document.createElement('div'); //做一個水果(div)
fruits.style.position = 'absolute'; //水果設置絕對定位
fruits.style.left = number[f] + 'px'; //水果的右距爲數組number裏的第隨機f個數,number[]數組的具體數值在開頭設置了
fruits.style.top = 0 + 'px'; //水果的初始上距離爲0
move.appendChild(fruits); //在move下加入水果節點,是水果節點成爲move下的子節點
fruits.setAttribute('id','fruits'); //爲水果節點加入id = ‘fruits’
fruits.classList.add('fruits'); //加入class = ‘fruits’
timerf = setInterval(function(){ //設置每隔speed1分鐘執行一次的事件
var monkey_l1 = parseInt(getComputedStyle(monkey).left); //這裏同上述的猴子裏的一樣意思,不再多解釋
var monkey_t1 = parseInt(getComputedStyle(monkey).top);
var f_l = parseInt(getComputedStyle(fruits).left); //這裏也是爲方便,將水果的左距離賦給f_l
var f_t = parseInt(getComputedStyle(fruits).top); //同
fruits.style.top = f_t + 10 + 'px'; //水果的上距離+10
if(f_t > 450){ //根據遊戲界面設置數值,這裏的450是我界面上的底部距離
fruits.remove(); //當水果到達450以後,水果消失(刪除節點)
food(); //上個水果消失,下個水果出現
}else if((monkey_l1 == f_l)&&((monkey_t1 == f_t)||(monkey_t1 == f_t + 30)||(monkey_t1 == f_t - 50))){ //前面爲圖方便就用在這裏,這裏表示的是當猴子喫到水果時,執行的事件,而猴子要喫到水果的要求就是,猴子的位置要和水果的位置一樣,就表示喫到了,因爲我的猴子設置的是100的寬高,而水果是50,所以這裏我把猴子分成了三段,以便猴子喫水果的時候能夠正常點顯示(什麼是正常顯示,,,嗯,,就是水果碰到猴子頭或者猴子身體或者猴子尾巴時,都表示喫到水果,都能得分)
this.score += 1; //喫到水果得分+1
scoreBox.innerHTML = this.score; //更新給界面上的分數
fruits.remove(); //喫到水果後,水果自然要消失
food(); //喫完,就要生成下個水果的出現,以便遊戲繼續
bomb(); //爲了增加遊戲難度,所以當猴子喫到一個水果後,就要同步增加一個炸彈
}else{ //其他情況不執行事件
;
}
},speed1);
}
function bomb(){ //設置炸彈
var b = Math.floor(Math.random()*6); //與上述水果一致,其目的是爲了隨機出現在樹的頂端六個位置
var zd = document.createElement('div'); //創建一個炸彈
zd.style.position = 'absolute'; //設置絕對定位
zd.style.left = number[b] + 'px'; //取到隨機位置
zd.style.top = 0 + 'px'; //與上述一致,不多解釋
move.appendChild(zd);
zd.setAttribute('id','zd');
zd.classList.add('boom');
timerb = setInterval(function(){ //設置每隔speed2執行一次事件
var monkey_l = parseInt(getComputedStyle(monkey).left); //與上述水果一致不多解釋
var monkey_t = parseInt(getComputedStyle(monkey).top);
var b_t =parseInt(getComputedStyle(zd).top);
var b_l =parseInt(getComputedStyle(zd).left);
zd.style.display = 'block'; //設置display = ‘block’
zd.style.top = b_t + 10 + 'px'; //設置上距離+10
if(b_t > 450){ /同上述解釋
if(k == true){ //這裏設置的k,在下面解釋
zd.remove(); //炸彈消失
bomb(); //重新生成炸彈
}else{ //在這裏解釋下k的作用,因爲遊戲的難度是靠不斷增加的炸彈爲障礙,所以就出現了個問題,由於這裏的zd.move()只能刪除當前的炸彈(1個),不能刪除所有的炸彈,因此對於重新開始遊戲就麻煩了,炸彈會重失敗時的個數開始顯示,也就是遊戲不能再從簡單的開始玩,所以這裏爲設置所有炸彈都消失,而添加了這步操作
for(var l = 0;l<document.getElementsByClassName('boom').length;l++){ //for循環的是當前html裏顯示的所有class爲boom的節點,該節點表示的就是炸彈
var long = document.getElementsByClassName('boom')[l]; //獲取每個boom節點
long.remove(); //循環刪除每個boom節點
}
}
}else if((monkey_l == b_l) && ((monkey_t == b_t) || (monkey_t == b_t - 50) ||( monkey_t == b_l + 30))){ //這裏的含義同上述的水果,只是將水果替換爲炸彈,也就是猴子喫到炸彈時引發的事件
scoreOver.innerHTML = this.score; //遊戲結束最終得分
gameOver.style.display = 'block'; //顯示遊戲結束界面
k = false; //這裏控制所有正在掉落的炸彈,使它不會再觸發上述的事件,而轉觸發刪除節點事件
fruits.remove(); //遊戲結束所以水果也需要消失
monkey.remove(); //猴子消失
zd.remove(); //這個碰到的炸彈也消失
}else{;}
if((monkey_l == b_l) && ((monkey_t == b_t) || (monkey_t == b_t - 50))){ //不用懷疑,這裏也和上面的一致,是猴子碰到炸彈觸發事件,而作用也是爲了雙重保險刪除所有炸彈節點,,,,,不知道這步是不是多餘了。。。。等會試試
for(var l = 0;l<document.getElementsByClassName('boom').length;l++){
var long = document.getElementsByClassName('boom')[l];
long.remove();
}
}
},speed2);
}
好了,現在所有的代碼都寫完了,這遊戲有個小缺點,就是當遊戲失敗後,你需要等界面上的所有炸彈都掉落完畢,再重新開始,才能從簡單的開始(即剛開始只掉落一個炸彈)。。。。
總算是完成了記憶中的那個遊戲,有點小激動,咳咳。。。雖然是挺low的,不過算是滿足了下回憶吧。。。有空會繼續升級這個遊戲,畢竟還沒有把向上爬的金龜子加入,,,
那個有感興趣的大佬們,可以寫寫,寫個更好的,希望最終作品能夠分享給我,謝謝了。。。
注:上述代碼解釋有誤的,幫我指出,謝謝。當然如果上述代碼有不理解的也可以聯繫我