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

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

貪吃蛇.jpg

因為沒有圖片素材,所以只能用簡單的樣式代替了,不要嫌棄呀~

思路

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

html界面

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

css樣式
注:
1.藍色的小方塊代表食物;
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>
準備工作

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

    //獲取元素節(jié)點
    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)建定時器為全局變量
    var timer1 = setInterval(eat,10);//檢測位置碰撞,并且吃掉食物;
    var srr = [];//記錄蛇行動的位置
    var num = 0 ;//記錄數(shù)組的長度
    var jsSnackBody ;//么米吃掉一個食物,蛇的身體
讓我們的小蛇動起來

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

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

左-------》對應(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

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

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

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

    //食物隨機出現(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)建定時器、檢驗碰撞

碰撞檢測原理:
蛇在實物的左邊、右邊、上邊、下邊的時候,說明沒有發(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;
            //檢測碰撞
            //碰撞檢測原理:
                //蛇在實物的左邊、右邊、上邊、下邊的時候,說明沒有發(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();//怪物的位置隨機變換
                setInterval(follow,10);//身體跟隨的定時器
            }
        }
    }
身體跟隨

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

    function follow(){
        //檢查一共添加了多少身體
        var bodyNum = document.getElementsByClassName("body");
        //記錄得分
        jsScore.innerHTML = bodyNum.length;
        //蛇每次移動1個像素,那么新的身體應(yīng)該跟隨在當前數(shù)組的倒數(shù)第20個數(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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,908評論 6 541
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,324評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,018評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,675評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,417評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,783評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,779評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,960評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,522評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,267評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,471評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,009評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,698評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,099評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,386評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,204評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,436評論 2 378

推薦閱讀更多精彩內(nèi)容

  • github代碼地址:https://github.com/McRayFE/snake 涉及到的知識點: 鍵盤事件...
    McRay閱讀 828評論 0 4
  • pygame 是python的一個游戲開發(fā)的框架,使用起來非常的簡單,用于開發(fā)小游戲再適合不過了。官方網(wǎng)站是 py...
    lovetianyats閱讀 1,903評論 0 11
  • 1. 創(chuàng)建一個canvas 定制區(qū)域:地圖面積(400*400),單位面積(20*20)共20個單位面積 三種區(qū)域...
    _v_xw閱讀 243評論 0 0
  • 構(gòu)建Block構(gòu)造方法 我們將定義一個Block 構(gòu)造方法,它會創(chuàng)建對象來表示不可見的游戲網(wǎng)格中的單個的塊。每個塊...
    suhuanzhen閱讀 1,455評論 1 1
  • 多多少少寫些關(guān)于他的文字
    16ad070a70ba閱讀 79評論 0 0