1. 程式人生 > >前端遊戲之初步貪吃蛇

前端遊戲之初步貪吃蛇

剛看完關於js的視訊,迫不急待的想試驗下成果,所以試寫了下貪吃蛇的效果:
在這裡插入圖片描述
上面就是我寫的一個簡易的貪吃蛇截圖,紅色的為蛇頭—.—。。。。
下面來記錄下我的程式碼過程
html程式碼

 <div style="width:30px;height:30px;background-color:red;position:absolute;left:0px;top:0px;"></div>
 <div></div>

首先先附上js程式碼中的打包函式

 function getStyle(elem,prop){       //elem是元素,prop是元素的屬性,這表示從我需要的元素中提取出我需要的屬性,打包在函式裡是因為需要解決相容性問題
        if(window.getComputedStyle){
            return window.getComputedStyle(elem,null)[prop];
        }else{
            return elem.currentStyle[prop]; 
        }
    }
       
 function bg3(){          //給我的貪吃蛇的食物新增隨機顏色 
                 var r=Math.floor(Math.random()*256);
                 var g=Math.floor(Math.random()*256);
                 var b=Math.floor(Math.random()*256);
                 return "rgb("+r+','+g+','+b+")";//所有方法的拼接都可以用ES6新特性`其他字串{$變數名}`替換
             }
   
 function lt(){            //食物的隨機左右位置
        return Math.floor(Math.random()*20) * 30 + 'px' ;
    }
 function tp(){             //食物的隨機上下位置
        return Math.floor(Math.random()*10) * 30 + 'px';
    }   
 function tt(){         //組織隨機食物的特性  
                var div9 = document.createElement('div');
                document.body.appendChild(div9);
                div9.style.width = 30 + 'px';
                 div9.style.height = 30 + 'px';
                 div9.style.backgroundColor = bg3();
                 div9.style.position = 'absolute';
                 div9.style.left = lt() ;
                 div9.style.top = tp() ;  
       }
    //d1表示的是對蛇頭的移動位置的封裝
  function d1(elem,keyCode){         //elem表示元素,keyCode的表示傳過來對應鍵盤按鍵的數字
                if(keyCode == 37){        //37表示鍵盤的左鍵
                     elem.style.left = parseInt(getStyle(elem,'left')) - 30 + "px" ;     //表示向左移30px
                 }else if(keyCode == 38){        //38表示鍵盤的上鍵
                     elem.style.top = parseInt(getStyle(elem,'top')) - 30 + "px" ;     //表示向上移30px
                 }else if(keyCode == 39){        //39表示鍵盤的右鍵
                     elem.style.left = parseInt(getStyle(elem,'left')) + 30 + "px" ;     //表示向右移30px
                 }else if(keyCode == 40){        //40表示鍵盤的下鍵
                    elem.style.top = parseInt(getStyle(elem,'top')) + 30 + "px" ;     //表示向下移30px
                 }
    }
//d2表示的是第一個食物被吃後變成蛇身的首次位置移動
  function d2(elem,keyCode){        //elem表示元素,keyCode的表示傳過來對應鍵盤按鍵的數字
            if(keyCode == 38){ 
                elem.style.top = parseInt(getStyle(elem.previousElementSibling,'top')) + 30 + "px";
                     elem.style.left = elem.previousElementSibling.style.left;
                 }else if(keyCode == 37){
                    elem.style.left = parseInt(getStyle(elem.previousElementSibling,'left')) + 30 + "px";
                elem.style.top = elem.previousElementSibling.style.top;
                     
                 }else if(keyCode == 40){
                    elem.style.top =  parseInt(getStyle(elem.previousElementSibling,'top')) - 30 + "px" ;
                     elem.style.left = elem.previousElementSibling.style.left;
                     
                 }else if(keyCode == 39){
                    elem.style.left = parseInt(getStyle(elem.previousElementSibling,'left')) - 30 + "px";
                    elem.style.top = elem.previousElementSibling.style.top;
                 }                
                 }
//d3是為了簡化程式碼而寫的封裝函式,表示的是當第一個食物被吃後,食物變成蛇身,跟著蛇頭運動
  function d3(n,elem,keyCode){
       for(n ;n>1;n--){
                var div3 = document.getElementsByTagName('div')[n];//從下面傳上來一個表示被吃食物的元素
                if(keyCode == 37){           //左鍵
                    div3.style.left = parseInt(getStyle(elem,'left')) + "px" ;//食物的左右運動情況
                    div3.style.top = elem.style.top ;//當按了左鍵,蛇身(/食物)的上下和蛇頭要保持一致
                }else if(keyCode == 38){           //上鍵
                    div3.style.top = parseInt(getStyle(elem,'top')) + "px" ;//食物的左右運動情況
                    div3.style.left = elem.style.left ;;//當按了上鍵,蛇身(/食物)的左右和蛇頭要保持一致
                }else if(keyCode == 39){           //右鍵
                    div3.style.left = parseInt(getStyle(elem,'left')) + "px" ;//食物的左右運動情況
                    div3.style.top = elem.style.top ;;//當按了右鍵,蛇身(/食物)的上下和蛇頭要保持一致
                }else if(keyCode == 40){           //下鍵
                    div3.style.top = parseInt(getStyle(elem,'top')) + "px" ;//食物的左右運動情況
                    div3.style.left = elem.style.left ;;//當按了下鍵,蛇身(/食物)的左右和蛇頭要保持一致
                }
           }
       }
       
//d4也是為了程式碼簡潔而封裝的,表示的是第二個食物及之後的食物的運動情況
       function d4(n,keyCode){
        for(n ;n>2;n--){
                var div3 = document.getElementsByTagName('div')[n];
                if(keyCode == 37){
                    div3.style.left = parseInt(getStyle(div3.previousElementSibling,'left')) + "px" ;
                    div3.style.top = div3.previousElementSibling.style.top ;
                }else if(keyCode == 38){
                    div3.style.top = parseInt(getStyle(div3.previousElementSibling,'top')) + "px" ;
                    div3.style.left = div3.previousElementSibling.style.left ;
                }else if(keyCode == 39){
                    div3.style.left = parseInt(getStyle(div3.previousElementSibling,'left')) + "px" ;
                    div3.style.top = div3.previousElementSibling.style.top ;
                }else if(keyCode == 40){
                    div3.style.top = parseInt(getStyle(div3.previousElementSibling,'top')) + "px" ;
                    div3.style.left = div3.previousElementSibling.style.left ;
                }    
           }
       }
    //上面的div3.previousElementSibling.style.left ;表示的是div3元素的前一個位置的元素(previousElementSibling)的左邊(left)位置的取值,top同理

下面是js的主體部分

	  var a = new Array(true,true,true);    //充當下面的啟動開關陣列
      var div1 = document.getElementsByTagName('div')[0];//獲取表示蛇頭的元素
      var div2 = document.getElementsByTagName('div')[1];//獲取表示第一個食物的元素
      //為第一個食物設定隨機位置隨機顏色,以及固定大小
         div2.style.width = 30 + 'px';
         div2.style.height = 30 + 'px';
         div2.style.backgroundColor = 'green';
         div2.style.position = 'absolute';
         div2.style.left = lt() ;      //呼叫上述的lt函式
         div2.style.top = tp() ;      //呼叫上述的tp函式
         
        var timer;     //用來抓取每隔時間的變化
    window.onkeydown = function(e){      //當在window下觸發鍵盤按鍵時發生的事件
            clearInterval(timer);      //用來清除每次按鍵觸發的時間變換效果
            if(a[0] == true){             //當開關1為true是觸發的時間
       		 timer = setInterval(function(){            //timer抓住每隔時間的變化
         		if(parseInt(div1.style.left) == parseInt(div2.style.left) && parseInt(div1.style.top) ==  parseInt(div2.style.top)){          //當蛇頭的左邊位置和上邊位置與第一個食物的左右上下位置相等時,觸發下面事件,,,就是蛇吃到食物時
           			 d1(div1,e.keyCode);        //返回給d1函式(div1(蛇頭)元素,以及觸發鍵盤的按鍵數字)
          			 tt();              //觸發tt()函式,建立下一個隨機食物
            		 a[0] = false;       //開關1等於false,關掉這個事件
          			 a[1] = true;        //開關2等於true,開始另一個事件
       		 }else{       //沒有滿足上述的if條件時,執行下面的語句
            d1(div1,e.keyCode);        //觸發d1函式,表示蛇頭的變動
       		 }  
    	},150);      //設定了每個150ms變動一次上述的情況,使蛇頭能夠自動移動
     
    }else if(a[0] == false){           //開關1關閉後,執行下面的事件
        if(a[1] == true){                  //開關2開啟
            timer = setInterval(function(){           //timer抓住每隔時間的變化
                if(parseInt(div1.style.left) == parseInt(div2.nextElementSibling.nextElementSibling.style.left) && parseInt(div1.style.top) ==  parseInt(div2.nextElementSibling.nextElementSibling.style.top)){  //蛇頭吃到第n個食物時(具體解釋看上面的if條件說明,基本與上述雷同),注:這裡的nextElementSibling表示的是這個元素(div2)的下一個元素,兩個nextElementSibling表示下一個的下一個元素
                d1(div1,e.keyCode);
                d2(div2,e.keyCode);
                tt();
                a[1] = false;
                a[2] = true;
            }
            else{
                d1(div1,e.keyCode);
                d2(div2,e.keyCode);
            }
            },150);
        
        }else if(a[1] == false){
            if(a[2] == true){
                timer = setInterval(function(){
                    if(parseInt(div1.style.left) == parseInt(div2.nextElementSibling.nextElementSibling.nextElementSibling.style.left) && parseInt(div1.style.top) ==  parseInt(div2.nextElementSibling.nextElementSibling.nextElementSibling.style.top)){    //與上述的if解釋差不多,不明白請往上看if的解釋
                    d1(div1,e.keyCode);
                    d3(2,div2,e.keyCode);
                    d2(div2,e.keyCode);
                    tt();
                    a[2] = false;
                    a[3] = true;
                }else{
                    d1(div1,e.keyCode);
                    d3(2,div2,e.keyCode);
                    d2(div2,e.keyCode);
                }
                },150);
             
            }else if(a[2] == false){          
                if(a[3] == true){
                    timer = setInterval(function(){
                        if(parseInt(div1.style.left) == parseInt(document.getElementsByTagName('div')[4].style.left) && parseInt(div1.style.top) ==  parseInt(document.getElementsByTagName('div')[4].style.top)){    //與上述的if解釋差不多,不明白請往上看if的解釋
                    d1(div1,e.keyCode);
                    d4(3,e.keyCode);
                    d3(2,div2,e.keyCode);
                    d2(div2,e.keyCode);
                    tt();
                    a[3] = false;
                    a[4] = true;
                 }else {
                    d1(div1,e.keyCode);
                    d4(3,e.keyCode);
                    d3(2,div2,e.keyCode);
                    d2(div2,e.keyCode);
                 }
                    },150);
                
                }else if(a[3] == false){
                    if(a[4] == true){
                        timer = setInterval(function(){
                            if(parseInt(div1.style.left) == parseInt(document.getElementsByTagName('div')[5].style.left) && parseInt(div1.style.top) ==  parseInt(document.getElementsByTagName('div')[5].style.top)){    //與上述的if解釋差不多,不明白請往上看if的解釋
                            d1(div1,e.keyCode);
                            d4(4,e.keyCode);
                            d3(2,div2,e.keyCode);
                            d2(div2,e.keyCode);
                            tt();
                            a[4] = false;
                            a[5] = true;
                        }else{
                            d1(div1,e.keyCode);
                            d4(4,e.keyCode);
                            d3(2,div2,e.keyCode);
                            d2(div2,e.keyCode);
                        }
                        },150);
                   
                    }else if(a[4] == false){
                        timer = setInterval(function(){
                            d1(div1,e.keyCode);
                            d4(5,e.keyCode);
                            d3(2,div2,e.keyCode);
                            d2(div2,e.keyCode);
                        },150);
                       
                    }
                    
                }
            }
        }
    }  
    }
    
    window.onkeyup = function(){          //當按鍵鬆開是觸發的事件
        if( parseInt(div1.style.left) < 0 || parseInt(div1.style.top) < 0 ||parseInt(div1.style.left) > 600||parseInt(div1.style.top) > 600){      //給蛇頭制定了一個運動範圍,當超出範圍會觸發警告視窗
            alert('你輸了');
            clearInterval(timer);//清除所有每隔150ms的運動狀態
        }
    }
    

上述就是全部的貪吃蛇程式碼,寫的不是很理想:
致命問題是,上述程式碼只實現了貪吃蛇只能吃六個食物,之後的食物無法吃,也就是我暫時想不到什麼方法可以將上述的if/else if不斷的觸發生成另一個if/else if,然後再生成另一個if/else if,現階段如果想加食物,就不得不在主js程式碼後再加上段if/else if和開關,才能使蛇吃到下一個食物。
如果哪位大佬會的話,請留下你珍貴的解決方案,在下感激不盡!!!當然也歡迎和我一樣的技術白來這留下疑問,或者願意的一起交流,加Q281668672