教你如何用JavaScript寫個貪喫蛇出來(超詳細)

貪喫蛇大家都玩過,但你會製作嘛?聽起來好像很難的樣子,其實非常的簡單,話不多說直接上代碼
我們先把dom結構寫出來

<div id="content">
            <div id="snake">
                    <div class="box head"></div>
                    <div class="box"></div>

            </div>
    
        </div>

其中,content爲整個佈局的大盒子,snake就是蛇,裏面的box就是他的身體,爲了區分頭部我們給第一個box加了個head名字用於區分,下面我們再把css加上

<style>
        .box{
            width: 60px;
            height: 60px;
            background-color: red;
            position:absolute;
            left: 0;
            top: 0;
            line-height: 60px;
        }
        .head{
            background-color: yellowgreen;
        }
    </style>

我們給蛇的每一節的寬高設置爲60像素,並給了一個定位,因爲如果不加定位的話無法讓他脫離文檔流(在頁面中飄起來),而且後續也無法通過left和top來判斷他的座標.
在這裏插入圖片描述
好的這樣我們就得到了一條可愛的小蛇(然鵝並沒有看出來哪裏可愛- -)。什麼?你問我他的頭哪去了,很簡單,在給元素加了定位以後後面的元素會覆蓋掉前面的元素,所以只是頭部和身體重疊了你看不到而已。
隨後咱們得讓這條蛇動起來是吧,那麼我們怎麼讓他動起來呢?原理很簡單,我們可以設置一個定時器,每過一個時間就讓他動一下,而怎麼讓他動呢,只需要設置一個數值,讓這個值每動一下就+=60,然後通過判斷是上下動還是左右動,來給元素的left與top賦值。我們把邏輯寫成代碼,就出來瞭如下的代碼

<script>
        var boxs = document.querySelectorAll(".box");
        var snake_x = 0;
        var snake_y = 0;
        var turn    = "right";
        setInterval(function(){
            snakeMove();
        },100)
        function snakeMove(){ 
            switch( turn ){
                case "right": snake_x += 60;break;
                case "left" : snake_x -= 60;break;
                case "top"   : snake_y -= 60;break;
                case "bottom": snake_y += 60;break;
            }

            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[i].style.left = snake_x + "px";
            boxs[i].style.top  = snake_y + "px";

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

</script>

上述代碼中,我們給小蛇的初始位置的x和y的座標都設置爲0,並且默認初始向右走,通過鍵盤上方向鍵的輸入,來改變他的方向。其中,難點在於

   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[i].style.left = snake_x + "px";
            boxs[i].style.top  = snake_y + "px";

這一塊代碼,這塊代碼的目的是讓後面的元素跟着前面的走,也就是讓蛇的每一塊身體都跟着上一塊去運動,然後最後再給頭部設置爲snake_x和snake_y當前的值即可,這樣就形成了第一塊(頭部)座標爲
snake_x,snake_y實時變化的值,第二塊爲第一塊之前的值,第三塊爲第二塊之前的值。。。以此類推就得到了一個身體跟着頭部走的效果
在這裏插入圖片描述
但是當你把代碼輸進去以後一運行會發現,這條小蛇過於頑皮,以至於走到邊界以後還會無限的向前走,那這不行啊,總不能讓蛇跑了不是,所以得給小蛇加上一個邊界

       var snake_x_max = document.documentElement.clientWidth ;
        var snake_y_max = document.documentElement.clientHeight;
if(snake_x > snake_x_max){
                snake_x = 0;
            }
            if(snake_x < 0){
                snake_x = snake_x_max;
            }
            if(snake_y > snake_y_max){
                snake_y = 0;
            }
            if(snake_y < 0){
                snake_y = snake_y_max;
            }

這裏我們設置x和y的最大值爲當前窗口的寬高,然後通過if語句進行判斷,如果當前座標大於了最大值,就講當前座標歸0,如果小於0的話(也就是跑到了左邊的邊界),就將當前座標設置爲最大值,這樣就可以得到一個邊界啦
在這裏插入圖片描述
你以爲這樣就完事啦?nonono,沒有食物喫的蛇怎麼能叫做貪喫蛇呢,那是沒有靈魂噠。下面我們開始製作食物(不能讓蛇餓着是吧)。

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

然後給他加個css

#food{
        width: 60px;
        height: 60px;
        position: absolute;
        background: greenyellow;
    }

然後再綁定一下元素並將他的left和top值設爲範圍內隨機數,這樣可以做到隨機位置生成

var fd=document.getElementById("food");
        fd.style.left=Math.random()*snake_x_max+"px";
        fd.style.top=Math.random()*snake_y_max+"px";

好的這樣我們就得到了一個隨機生成的食物
在這裏插入圖片描述
不過我們的小蛇好像對食物並沒有什麼興趣呢,路過以後並不會喫掉,所以我們得給他加一個碰撞檢測吧,碰撞檢測的邏輯很簡單,只需要讓食物的left值與頭部的left值相減的絕對值<=食物的大小,並且食物的top值與頭部的top值相減的絕對值<=食物的大小,設置小於等於是因爲如果直接用相等來判斷的話,必須兩個元素完全重合纔行,我們需要的是碰到邊緣就算遲到,所以用兩個數值相減小於等於來做。然後判斷當頭部與食物發生碰撞時,將蛇的身體部分克隆一塊出來放到蛇的身體裏面,並讓食物的位置重新刷新(適用克隆爲偷懶方法,此偷懶方法僅適用於當小蛇開局自帶一個身體的時候,如果小蛇開局不自帶身體的話,我們無法克隆已有身體,只能通過createElement去新創建一個身體塊出來並添加className後再添加到父元素中去纔行)。下面我們把邏輯轉換爲代碼

var dl=snake_x;
        var dt=snake_y;
        var fl=fd.style.left;
        var ft=fd.style.top;
        var dv=document.querySelectorAll("#snake div");
        var sk=document.getElementById("snake");
        var a2=Number(fl.substring(0,fl.indexOf("px")));
        var b2=Number(ft.substring(0,ft.indexOf("px")));
        if(Math.abs(dl-a2)<=60&&Math.abs(dt-b2)<=60){
             fd.style.left=Math.random()*1000+"px";
             fd.style.top=Math.random()*800+"px";
             sk.appendChild(dv[1].cloneNode());
             boxs = document.querySelectorAll(".box");

        }

其中那一大長串的substring的方法是因爲獲取到的left與top的值的格式是例如”200px”這樣的數組,無法進行數學運算,所以要把px給截掉,並將剩下的字符串”200”轉換成number類型纔可以進行數學運算。
在這裏插入圖片描述
這樣一個簡單的貪喫蛇就做好啦~
啥?你問我什麼什麼類似碰到自己會死這樣更多的規則機制咋沒寫,肯定是因爲我懶啊!我連createElement都懶得用直接克隆一個出來了,咋會勤快到把剩下這麼多的機制補全呢哈哈。基礎機制我已經寫出來了,各種奇奇怪怪的機制還是留給小夥伴們自由發揮吧~
PS:大家完全可以把頭部的背景圖片改成你小夥伴的照片,再把食物改成一些你想讓ta喫的東西,可以拿來惡搞啊哈哈哈

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章