JavaScript原生實(shí)現(xiàn)《貪吃蛇》

貪吃蛇大家都不陌生吧~
簡單做一個(gè)。

貪吃蛇.jpg

因?yàn)闆]有圖片素材,所以只能用簡單的樣式代替了,不要嫌棄呀~

思路

1.讓我們的小蛇動起來
2.隨機(jī)生成食物
3.每吃掉一個(gè)食物,蛇的身體會變長,食物會重新?lián)Q位置

html界面

<div class="face">
    <!-- 小蛇移動的操場 -->
    <div id="playground">
        <!-- 食物 界面中的藍(lán)色小方塊-->
        <div id="food"></div>
        <!-- 小蛇 界面中的紅色小方塊-->
        <div id="snack"></div>
    </div>
    <!-- 計(jì)算得分 -->
    <div class="menu">
        <div>得分<span id="score"></span></div>
    </div>
</div>

css樣式
注:
1.藍(lán)色的小方塊代表食物;
2.紅色的小方塊代表小蛇;
3.綠色的小方塊代表吃掉怪物后增長的身體;

    <style type="text/css">
        .face{
            height: 400px;
            width: 600px;
            margin-left: auto;
            margin-right: auto;
            position: relative;
            background-color: pink;
        }
        #playground{
            height: 400px;
            width: 450px;
            float: left;
            position: relative;
        }
        .menu{
            height: 400px;
            width: 150px;
            float: left;
            background-color: skyblue;
        }
        #snack{
            height: 20px;
            width: 20px;
            background-color: red;
            position: absolute;
            left: 0px;
            top:0px;
        }
        #food{
            height: 20px;
            width: 20px;
            background: blue;
            position: absolute;
        }
        .body{
            height: 20px;
            width: 20px;
            background: green;
            position: absolute;
            left: 0px;
            top:0px;
        }
        #score{
            font-size: 30px;
            font-weight: bold;
            color: red;
        }
        .menu div{
            font-size: 20px;
            font-weight: bold;
        }
    </style>
準(zhǔn)備工作

獲取元素節(jié)點(diǎn)、設(shè)置全局變量;

    //獲取元素節(jié)點(diǎn)
    var jsDiv = document.getElementById("playground");
    var jsSnack = document.getElementById("snack"); 
    var jsFood = document.getElementById("food");
    var jsBody = document.getElementById("playground");
    var jsScore = document.getElementById("score");
    //設(shè)置全局變量
    var timer;//創(chuàng)建定時(shí)器為全局變量
    var timer1 = setInterval(eat,10);//檢測位置碰撞,并且吃掉食物;
    var srr = [];//記錄蛇行動的位置
    var num = 0 ;//記錄數(shù)組的長度
    var jsSnackBody ;//么米吃掉一個(gè)食物,蛇的身體
讓我們的小蛇動起來

通過按鍵盤的上下左右鍵,控制小蛇的移動方向,并記錄小蛇走過的位置。
我們通過什么來獲取我們按下的是哪個(gè)鍵??
我們當(dāng)然通過ASCII碼值;

信息在計(jì)算機(jī)上是用二進(jìn)制表示的,這種表示法讓人理解就很困難。因此計(jì)算機(jī)上都配有輸入和輸出設(shè)備,這些設(shè)備的主要目的就是,以一種人類可閱讀的形式將信息在這些設(shè)備上顯示出來供人閱讀理解。為保證人類和設(shè)備,設(shè)備和計(jì)算機(jī)之間能進(jìn)行正確的信息交換,人們編制的統(tǒng)一的信息交換代碼,這就是ASCII碼表,它的全稱是“美國信息交換標(biāo)準(zhǔn)代碼”

左-------》對應(yīng)的ASCII碼值是 37;
上-------》對應(yīng)的ASCII碼值是 38;
右-------》對應(yīng)的ASCII碼值是 39;
下-------》對應(yīng)的ASCII碼值是 40;

    //開始游戲
    document.onkeydown = function(e){
        var evt = e || window.event;    
            switch(evt.keyCode) {
            //向左移動
            case 37:
                clearInterval(timer);
                timer=window.setInterval(runLeft,10)
                function runLeft(){
                    if (jsSnack.offsetLeft > 0) {
                        jsSnack.style.left = jsSnack.offsetLeft - 1+ "px";
                        jsSnack.style.top = jsSnack.offsetTop + "px";   
                        //記錄小蛇的位置
                        srr.push([jsSnack.offsetLeft, jsSnack.offsetTop]);
                        num++;//記錄數(shù)組的長度
                    }                       
                }
            break;
            //向上移動
            case 38:
                clearInterval(timer);
                timer=window.setInterval(runTop,10);    
                function runTop(){
                    if (jsSnack.offsetTop > 0) {
                        jsSnack.style.top = jsSnack.offsetTop - 1 + "px";
                        jsSnack.style.left = jsSnack.offsetLeft + "px";
                        //記錄小蛇的位置
                        srr.push([jsSnack.offsetLeft, jsSnack.offsetTop]);
                        num++;//記錄數(shù)組的長度
                    }                       
                }

            break;
            //向右移動
            case 39:
                clearInterval(timer);
                timer=window.setInterval(runRight,10);
                function runRight(){
                    if (jsSnack.offsetLeft + jsSnack.offsetWidth <= 450) {
                        jsSnack.style.left = jsSnack.offsetLeft + 1 + "px";
                        jsSnack.style.top = jsSnack.offsetTop + "px";
                        //記錄小蛇的位置
                        srr.push([jsSnack.offsetLeft, jsSnack.offsetTop]);
                        num++;//記錄數(shù)組的長度
                    }                       
                }                   
            break;
            //向下移動  
            case 40:
                clearInterval(timer);
                timer=window.setInterval(runBottom,10);         
                function runBottom(){
                    if (jsSnack.offsetTop + jsSnack.offsetHeight <= 400) {
                        jsSnack.style.top = jsSnack.offsetTop + 1 + "px";
                        jsSnack.style.left = jsSnack.offsetLeft + "px";
                        //記錄小蛇的位置
                        srr.push([jsSnack.offsetLeft, jsSnack.offsetTop]);
                        num++;//記錄數(shù)組的長度
                    }                       
                }                   
            break;
        }
    }
GIF.gif

檢驗(yàn)碰撞詳解
這里筆者覺得語言的描述太空洞,還是弄幾張圖吧,圖是筆者手繪的,不要嫌丑,畫的是沒有碰撞的情況,那取反,就說明碰撞到了

01.jpg
04.jpg
03.jpg
02.jpg
食物隨機(jī)出現(xiàn)

把食物的隨機(jī)出現(xiàn)封裝在一個(gè)函數(shù)里,那么我們后續(xù)需要的時(shí)候可以直接調(diào)用。
利用隨機(jī)數(shù)來讓食物的位置隨機(jī)出現(xiàn)。

    //食物隨機(jī)出現(xiàn)
    function Pos(){
        jsFood.style.left=parseInt(Math.random() * (430 - 20 + 1) + 20) + "px";
        jsFood.style.top=parseInt(Math.random() * (380 - 20 + 1) + 20) + "px";
    }
    Pos();
GIF1.gif
創(chuàng)建定時(shí)器、檢驗(yàn)碰撞

碰撞檢測原理:
蛇在實(shí)物的左邊、右邊、上邊、下邊的時(shí)候,說明沒有發(fā)生碰撞,那么我們?nèi)》?,就說明發(fā)生碰撞

function eat(){
        rectangleCrashExamine(jsSnack,jsFood);
        function rectangleCrashExamine(obj1, obj2) {
            var obj1Left = obj1.offsetLeft;
            var obj1Width = obj1.offsetLeft + obj1.offsetWidth;
            var obj1Top = obj1.offsetTop;
            var obj1Height = obj1.offsetTop + obj1.offsetHeight;
            var obj2Left = obj2.offsetLeft;
            var obj2Width = obj2.offsetLeft + obj2.offsetWidth;
            var obj2Top = obj2.offsetTop;
            var obj2Height = obj2.offsetTop + obj2.offsetHeight;
            //檢測碰撞
            //碰撞檢測原理:
                //蛇在實(shí)物的左邊、右邊、上邊、下邊的時(shí)候,說明沒有發(fā)生碰撞,那么我們?nèi)》?,就說明發(fā)生碰撞
            if ( !(obj1Left > obj2Width || obj1Width < obj2Left || obj1Top > obj2Height || obj1Height < obj2Top) ) {
                //碰撞后身體
                jsSnackBody = document.createElement("div");
                jsSnackBody.setAttribute("class","body");
                jsBody.appendChild(jsSnackBody);
                Pos();//怪物的位置隨機(jī)變換
                setInterval(follow,10);//身體跟隨的定時(shí)器
            }
        }
    }
身體跟隨

每吃掉一個(gè)食物,小蛇的長度發(fā)生變化

    function follow(){
        //檢查一共添加了多少身體
        var bodyNum = document.getElementsByClassName("body");
        //記錄得分
        jsScore.innerHTML = bodyNum.length;
        //蛇每次移動1個(gè)像素,那么新的身體應(yīng)該跟隨在當(dāng)前數(shù)組的倒數(shù)第20個(gè)數(shù)組的位置;依次加等;
        var place = 0 ;
        for( var i = 0 ; i<bodyNum.length ; i++){
            place += 20;
            bodyNum[i].style.left=srr[num-place][0] + 'px';
            bodyNum[i].style.top=srr[num-place][1] + 'px';  
        }
    }

好了,現(xiàn)在我們的游戲可以玩了

GIF.gif

這是一個(gè)簡單的貪吃蛇,并沒有做死亡碰撞,喜歡的小伙伴可以繼續(xù)放下做。
任何時(shí)候不要吝嗇您的贊美,喜歡就點(diǎn)贊拉~,互粉互粉

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容