1. 程式人生 > 其它 >前端小遊戲

前端小遊戲

技術標籤:遊戲jsjqueryhtml前端

前端小遊戲——簡易貪吃蛇

  • 概要: 使用前端基礎技術實現簡易版貪吃蛇,涉及到的技術點有:html、css、javascript、jQuery

  • 要實現的功能: ①生成蛇移動的介面,這裡使用二維陣列(矩陣);②畫出蛇;③蛇可以自動移動,並根據鍵盤的上下左右改變方向;④隨機生成食物(食物不在蛇的身上產生);⑤吃食物,當蛇吃到食物時,蛇身變長,並且重新生成一個食物;⑥吃到食物後速度變快;⑦蛇死亡,分為兩種情況,一個是吃到自己,另一個是撞牆;⑧結束遊戲並重置畫面(蛇的位置)。

  • web介面: 貪吃蛇web介面

  • html部分:

<div id="mainpanel"
class="mainpanel"></div> <div id="end" class="end">遊戲結束!</div> <p> <input id="starBtn" type="button" value="開始" /> <input id="endBtn" type="button" value="結束" /> 得分:<span id=
"point">0</span> </p>
  • css部分:
            .mainpanel{
				border: 1px solid black;
				height: 400px;
				width: 800px;
				margin: 0px auto;
				font-size: 1px;
			}
			.innerbg{
				height: 18px;
				width: 18px;
				margin: 1px;
				background-color: lightgray;
				float: left;
			}
.snake{ background-color: goldenrod; } .food{ background-color: lightgreen; } .end{ width: 200px; height: 100px; border: 5px solid darkgray; background-color: #D3D3D3; border-radius: 10px; position: absolute; top: 30%; left: 50%; margin-left: -100px; display: none; text-align: center; line-height: 100px; } p{ text-align: center; }

- JS部分:
定義全域性變數


        //蛇橫縱座標
   		var snakeX = [4,5,6,7];
   		var snakeY = [4,4,4,4];
   		
   		//初始蛇頭的位置
   		var snakeXHead = 7;
   		var snakeYHead = 4;
   		
        /*
        蛇頭的初始朝向
   		37左
   		38上
   		39右
   		40下
   		 */
   	    var direction = 39;
   		 
   		//食物的橫縱座標
   		var foodX;
   		var foodY;
   		
   		var moveTime = 100; //蛇移動的初始速度
   		var score = 0; //分數
   		var startGame; //計時函式返回的物件名
   		
   		var state = true; //判斷是否生成食物
   		var turn = true; //判斷是否繼續接受鍵盤的輸入

基礎陣列:

       var basearr = new Array(40);
   		for(var i = 0;i<40;i++){
   			basearr[i] = new Array(20);
   		}

畫蛇:

function drawSnake(){
   		for(var i = 0;i<snakeX.length;i++){
   			if(snakeX[i]<=39&&snakeX[i]>=0&&snakeY[i]<=19&&snakeY[i]>=0){ //判斷是否超出畫面
   			basearr[snakeX[i]][snakeY[i]].addClass("snake");
   	    	}
    	}
   }

清除蛇:

function clearSnake(){
				for(var i = 0;i<snakeX.length;i++){
					basearr[snakeX[i]][snakeY[i]].removeClass("snake");
				}
			}

蛇移動:
①每次畫蛇前,先清除原有的陣列;
②根據鍵盤的輸入判斷蛇頭的方向後移動;
③每次移動後用shift()函式清楚陣列中的第一個元素;
④其他功能函式。eat()–>吃食物;death()–>死亡;drawSnake()–>畫蛇

function snakeMove(){
				clearSnake();
				turn = true;
				
				switch(direction){
					case 39:snakeX.push(++snakeXHead);snakeY.push(snakeYHead);break;					
					case 37:snakeX.push(--snakeXHead);snakeY.push(snakeYHead);break;
					case 38:snakeX.push(snakeXHead);snakeY.push(--snakeYHead);break;
					case 40:snakeX.push(snakeXHead);snakeY.push(++snakeYHead);break;
				}
				
				snakeX.shift();
				snakeY.shift();
				
				eat();
				death();
				drawSnake();
			}

食物出現:
①用random函式隨機生成食物的X、Y座標;
②遍歷迴圈蛇身陣列,判斷當隨機生成的食物在蛇身上時不生成食物,並繼續迴圈直到不在為止。

function foodShow(){
				
				do{
					foodX = Math.floor(Math.random()*39+0);
					foodY = Math.floor(Math.random()*19+0);
					state = false;
					for(var i = 0;i<snakeX.length;i++){
						if(snakeX[i]==foodX&&snakeY[i]==foodY){
							console.log("在蛇身上出現!不生成!")
							state = true;
						}
					}
				}while(state)
				
				basearr[foodX][foodY].addClass("food");
				console.log("食物座標:"+foodX,foodY);
			}

吃食物動作: 當蛇頭的XY座標與食物的XY座標一致時,吃到食物(碰撞事件)。
①分數+1;
②蛇速度變快,重置計時函式的時間,而後重新呼叫計時函式;
③移除當前食物,再次生成食物;
④使用unshift()函式給陣列的開頭新增一個新的元素並返回新的長度。

function eat(){
				
				if(snakeXHead==foodX&&snakeYHead==foodY){
					
					score += 1;
					moveTime -= 2;
					clearTimeout(startGame);
					startGame = setInterval(snakeMove,moveTime);
					
					$("#point").html(score);
					console.log("蛇移動速度"+moveTime);
					$(".food").removeClass('food');
					foodShow();
					
					snakeX.unshift(foodX);
					snakeY.unshift(foodY);
				}
			}

死亡:
①當蛇頭的XY座標和自身XY座標重合時(吃到自己),呼叫clearInterval()函式停止計時函式,遊戲結束;
②當蛇頭的XY座標超過介面長度時(撞牆),呼叫clearInterval()函式停止計時函式,遊戲結束;

function death(){
				for(var i =0;i<snakeX.length-1;i++){
					if(snakeX[i] == snakeXHead && snakeY[i] == snakeYHead){

						clearInterval(startGame);
						$("#end").show();
						
						console.log("吃到自己啦!")
					}
					if(snakeXHead>39 ||snakeXHead<0 || snakeYHead>19 || snakeYHead<0 ){
						
						clearInterval(startGame);
						$("#end").show();
						
						console.log("出界啦!")
					}
				}
			}

重置頁面:

function initGame(){

				$("#mainpanel").html("");//防止疊加介面
				
				//重置座標面板
				for(var y = 0;y<20;y++){
					for(var x = 0;x<40;x++){
						var mycontent = $('<div class = "innerbg"></div>');
						basearr[x][y] = mycontent;
						$("#mainpanel").append(basearr[x][y]);
					}
				}
				
				snakeX =[4,5,6,7];
				snakeY =[4,4,4,4];			
				drawSnake();
				snakeXHead = 7;
				snakeYHead = 4;		
				direction = 39;
				turn = true;
				moveTime = 100;
			}

- jQuery部分:

建立畫面: 40*20

for(var y = 0;y<20;y++){
					for(var x = 0;x<40;x++){
						var mycontent = $('<div class = "innerbg"></div>');
						basearr[x][y] = mycontent;
						$("#mainpanel").append(basearr[x][y]);
					}
				}
				
		drawSnake();//建立初始蛇

通過鍵盤輸入改變蛇移動的方向:
①限定接受鍵盤輸入的範圍(37-40);
Math.abs(direction-event.keyCode)!=2 用於判斷不能直接掉頭移動。例:當蛇頭右移動時不能接收←、當蛇頭向下移動時不能接收 ↑;
③turn作用:例如當蛇正在向下移動,此時快速按 → ↑,會導致蛇頭穿過自己(死亡),為了防止這種情況發生,加入一個布林變數turn,一次只接收一個按鍵的輸入,當蛇再次移動時將turn的值變更為true;

$(document).keyup(function(event){
					
	 if(turn&&event.keyCode<=40&&event.keyCode>=37&&Math.abs(direction-event.keyCode)!=2){
	 
				direction = event.keyCode;
				turn = false;
			}
		})

開始按鈕繫結監聽事件:
①禁用開始按鈕,開啟結束按鈕;
②重置畫面
③開始計時函式,生成食物

$("#starBtn").click(function(){

		          $(this).prop("disabled",true);
	              $("#endBtn").prop("disabled",false);
					
		          initGame()
				
		          $("#end").hide();
		          startGame = setInterval(snakeMove,moveTime);
		          foodShow();			
               })

結束按鈕繫結監聽事件:
①結束計時函式
②清空分數
③禁用結束按鈕,開啟開始按鈕;
④移除畫面中的食物,展示結束彈窗;

$("#endBtn").click(function(){
					
					clearInterval(startGame);
					
					score = 0;
					$("#point").html(score);
					
					$(this).prop("disabled",true);
					$("#starBtn").prop("disabled",false);
					$(".food").removeClass('food');
					$("#end").show();
				})

總結: 一週的前端技術學習後實現的貪吃蛇小遊戲。總體思路容易理通,關鍵點在於處理每個動過時的邏輯需要更細緻,否則執行時就會出一些bug。

難點歸納:
①為了實現蛇的動態移動,需要考慮到每次增加元素後要及時刪除一個元素,才能實現動態移動。
②如何防止食物不在蛇身上出現?
首先要考慮到出現在蛇身上時的食物XY座標是與蛇的XY陣列座標相重合的,使用do while迴圈並遍歷蛇身陣列進行判斷,當重合時將while迴圈條件實現為true,直到不重合fasle跳出do while迴圈生成食物。
③吃食物時如何讓蛇變長?
這個動作的實現方法很多,我是直接使用unshift()函式增加元素,也可以進行判斷,當吃到食物時不用shift()刪除元素就可以。
④怎麼讓蛇每次吃到食物後速度變快?
在吃到食物時,先要停止當前的計時函式,而後再次呼叫setInterval()函式,並將時間設為變數,每次吃到食物後做減法。