1. 程式人生 > 程式設計 >基於JavaScript實現貪吃蛇遊戲

基於JavaScript實現貪吃蛇遊戲

本文例項為大家分享了JavaScript實現貪吃蛇遊戲的具體程式碼,供大家參考,具體內容如下

1.結構

建立一個盒子box作為蛇的身體,當前盒子中只有一個子元素,代表此時蛇的長度為1.
在建立一個盒子food作為貪吃蛇的食物。

<div id="box">
  <div></div>
</div>
<div id="food"></div>

2.CSS

設定蛇和食物的樣式,這裡注意蛇和食物都是絕對定位。

<style>
 *{
  padding: 0px;
  margin: 0px;
 }
 #box div{
  width: 30px;
  height: 30px;
  box-sizing: border-box;
  background: green;
  border: 1px solid black;
  position: absolute;
 }
 #food{
  width: 30px;
  height: 30px;
  background: brown;
  position: absolute;
 }
 </style>

3.指令碼

獲取蛇的身體和每一個子元素

var box = document.getElementById("box");
var boxs = document.getElementById("box").children;

定義蛇頭的位置

var snackX = 0;
var snackY = 0;

獲取螢幕寬度和高度,以此來設定牆的邊界,以限制蛇的移動範圍。

var cw = document.documentElement.clientWidth;
 var ch = document.documentElement.clientHeight;
 var minsnackX = 0;
 var maxsnackX = Math.floor(cw / boxs[0].offsetWidth)*boxs[0].offsetWidth;
 var minsnackY = 0;
 var maxsnackY = Math.floor(ch / boxs[0].offsetHeight)*boxs[0].offsetHeight;

定義初始的移動方向。

var turn = "right";

獲取食物元素,並設定食物的位置座標。

 var foodele = document.getElementById("food");
 var foodX,foodY;

蛇的初始化

for(var i = 0; i <6 ; i++){
  box.appendChild(boxs[0].cloneNode(true));
 }

重新整理食物

function food(){
 //此處的座標要先獲取頁面最大支援的蛇身體的塊數,然後在塊數中隨機,然後乘以塊數的大小,
 //因為蛇的移動每一步都是固定的,想要判定食物和蛇頭重合就必須座標是整塊的倍數。
  foodX = parseInt( Math.random()*Math.floor(cw / boxs[0].offsetWidth))*boxs[0].offsetWidth;
  foodY = parseInt( Math.random()*Math.floor(ch / boxs[0].offsetHeight))*boxs[0].offsetHeight;
  //判定當食物的產生位置和蛇的任何一個位置重合時就重新生成食物。
  for(var i = 0;i<boxs.length;i++){
   if(foodX + "px" === boxs[i].style.left && foodY + "px" === boxs[i].style.top){
    food();
   }
  }
  foodele.style.left = foodX + "px";
  foodele.style.top = foodY + "px";
 }

呼叫food()方法 生成第一個食物

food();

設定定時器 每次執行一次蛇的執行方法

var timer = setInterval(function(){
  snackMOve();
 },150)

封裝一個蛇的運動方法

//移動和判定邊界
 function snackMOve(){
//此處為判定方向 根據判定的方向,向改方向前進一個方塊
  switch(turn){
   case "right":snackX +=30;break;
   case "left":snackX -=30;break;
   case "bottom":snackY +=30;break;
   case "top":snackY -=30;break;
  }
  //如果蛇越過了牆就從另一端出現
  if(snackX > maxsnackX){
   snackX = 0;
  }
  if(snackX < minsnackX){
   snackX = maxsnackX;
  }
  if(snackY > maxsnackY){
   snackY = 0;
  } 
  if(snackY < minsnackY){
   snackY = maxsnackY;
  }
  //從最後一個開始,每個元素跟隨上一個元素的位置
  for(var i = boxs.length-1; i >0 ; i--){
   boxs[i].style.left = boxs[i-1].style.left;
   boxs[i].style.top = boxs[i-1].style.top ;
  }
  //第一個也就是蛇頭的位置,永遠是根據方向獲取的位置
  boxs[0].style.left = snackX + "px";
  boxs[0].style.top = snackY + "px" ;


  //判定吃到食物 就長大和重新整理
  //當蛇頭位置移動之後與食物重合 那麼重新整理食物,並且在蛇的身體中插入一個克隆的元素,相當於長度+1
  if(snackX === foodX && snackY === foodY){
   food();
   box.appendChild(boxs[0].cloneNode(true));
  }else{
  //判定撞死 
  //當蛇頭與身體中的任何一個元素重合,那麼判定結束遊戲,停止定時器
   for(var i = 1;i<boxs.length;i++){
    if(snackX + "px" === boxs[i].style.left && snackY + "px" === boxs[i].style.top){
     clearInterval(timer);
     alert("失敗");
    }
   }
  }
 }

蛇的運動方向

document.onkeydown = function(eve){
 var e = eve||event;
 var keyCode = e.keyCode||e.which;
 switch(keyCode){
  case 37:if(turn === "right"){break;}turn = "left";break;
  case 38:if(turn === "bottom"){break;}turn = "top";break;
  case 39:if(turn === "left"){break;}turn = "right";break;
  case 40:if(turn === "top"){break;}turn = "bottom";break;
 }  
}

全部程式碼

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width,initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
 <style>
 *{
  padding: 0px;
  margin: 0px;
 }
 #box div{
  width: 30px;
  height: 30px;
  box-sizing: border-box;
  background: green;
  border: 1px solid black;
  position: absolute;
 }
 #food{
  width: 30px;
  height: 30px;
  background: brown;
  position: absolute;
 }
 </style>
</head>
<body>
 <div id="box">
  <div></div>
 </div>
 <div id="food"></div>
 <script>
  var box = document.getElementById("box");
  var boxs = document.getElementById("box").children;
  var snackX = 0;
  var snackY = 0;
  var cw = document.documentElement.clientWidth;
  var ch = document.documentElement.clientHeight;
  var minsnackX = 0;
  var maxsnackX = Math.floor(cw / boxs[0].offsetWidth)*boxs[0].offsetWidth;
  var minsnackY = 0;
  var maxsnackY = Math.floor(ch / boxs[0].offsetHeight)*boxs[0].offsetHeight;
  var turn = "right";
  var foodele = document.getElementById("food");
  var foodX,foodY;

  for(var i = 0; i <6 ; i++){
   box.appendChild(boxs[0].cloneNode(true));
  }


  //隨機食物
  function food(){
   foodX = parseInt( Math.random()*Math.floor(cw / boxs[0].offsetWidth))*boxs[0].offsetWidth;
   foodY = parseInt( Math.random()*Math.floor(ch / boxs[0].offsetHeight))*boxs[0].offsetHeight;
   for(var i = 0;i<boxs.length;i++){
    if(foodX + "px" === boxs[i].style.left && foodY + "px" === boxs[i].style.top){
     food();
    }
   }
   foodele.style.left = foodX + "px";
   foodele.style.top = foodY + "px";
  }
  food();

  //設定定時器 移動
  var timer = setInterval(function(){
   snackMOve();
  },150)


  //移動和判定邊界
  function snackMOve(){
   switch(turn){
    case "right":snackX +=30;break;
    case "left":snackX -=30;break;
    case "bottom":snackY +=30;break;
    case "top":snackY -=30;break;
   }
   //根據邊界歸零
   if(snackX > maxsnackX){
    snackX = 0;
   }
   if(snackX < minsnackX){
    snackX = maxsnackX;
   }
   if(snackY > maxsnackY){
    snackY = 0;
   } 
   if(snackY < minsnackY){
    snackY = maxsnackY;
   }
   for(var i = boxs.length-1; i >0 ; i--){
    boxs[i].style.left = boxs[i-1].style.left;
    boxs[i].style.top = boxs[i-1].style.top ;
   }
   boxs[0].style.left = snackX + "px";
   boxs[0].style.top = snackY + "px" ;


   //判定吃到食物 就長大和重新整理
   if(snackX === foodX && snackY === foodY){
    food();
    box.appendChild(boxs[0].cloneNode(true));
   }else{
   //判定撞死 暫停計時器 重新整理
    for(var i = 1;i<boxs.length;i++){
     // console.log(boxs[i].style.left);
     if(snackX + "px" === boxs[i].style.left && snackY + "px" === boxs[i].style.top){
      clearInterval(timer);
      alert("失敗");
      // console.log(1)
     }
    }
   }
  }


  //方向
  document.onkeydown = function(eve){
   var e = eve||event;
   var keyCode = e.keyCode||e.which;
   switch(keyCode){
    case 37:if(turn === "right"){break;}turn = "left";break;
    case 38:if(turn === "bottom"){break;}turn = "top";break;
    case 39:if(turn === "left"){break;}turn = "right";break;
    case 40:if(turn === "top"){break;}turn = "bottom";break;
   }  
  }
 </script>
</body>
</html>

總結

貪吃蛇的思路主要是有以下幾個部分

1.食物的隨機出現(不能隨機在蛇身上)
2.定時器控制蛇的移動
3.牆的判定
4.蛇的運動邏輯
5.運動方向的判定
6.吃到食物的判定
7.蛇頭與身體的判定(即遊戲結束的判定)

小編還為大家準備了精彩的專題:javascript經典小遊戲彙總

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。