貪吃蛇大作戰(zhàn)

最近在做一個(gè)貪吃蛇的項(xiàng)目,這是我第一次用js來(lái)實(shí)現(xiàn)做一款游戲,雖然很low,但出現(xiàn)預(yù)想的效果時(shí)還是很開(kāi)心的,雖然做出了效果但還是對(duì)其中的一些還不太熟練,在后續(xù)我會(huì)將游戲開(kāi)始,地圖構(gòu)建,食物出現(xiàn),蛇的出現(xiàn)分別寫(xiě)入一個(gè)文件,這樣更便于理解。
我們先定義一個(gè)游戲引擎用來(lái)定義游戲的開(kāi)始、結(jié)束以及場(chǎng)景的布置。
用創(chuàng)建對(duì)象來(lái)定義一個(gè)游戲gGameBox其中有地圖的屬性,以及地圖的所有坐標(biāo)。

var gGameBox = {
    rows: 20,  // 行數(shù)
    cols: 20,  // 列數(shù)
    allTds: [], // 存儲(chǔ)所有的td元素對(duì)象
    food: null, // 食物對(duì)象
    snake: null, // 蛇對(duì)象
    .
    .
    .//(以下到場(chǎng)景布置都是)
}

清除蛇尾定義清除屬性clear,由于蛇的移動(dòng)是將蛇節(jié)的坐標(biāo)加++,所以蛇身會(huì)一直增加,要清除蛇的小尾巴。

clear: function(){
        for(var i = 0; i< gGameBox.allTds.length;i++){
            for(var j=0;j<gGameBox.allTds[i].length;j++){
                gGameBox.allTds[i][j].className = "";
            }
        }
    },

定義一個(gè)方法用來(lái)判斷按鍵,可以由上下左右來(lái)控制蛇的移動(dòng)。(注意蛇不能在往左走的同時(shí)往右走,同理其他一樣)

keyControl: function() {
        // onkeydown 鍵盤(pán)按下事件
        window.onkeydown = function(e) {
            // 獲取按鍵編碼
            var c = e.keyCode;
            if (c == 37){
                if (gGameBox.snake.direct == "right"){
                    // 當(dāng)前是往右走,不能掉頭,終止函數(shù)
                    return ;
                }
                gGameBox.snake.direct = "left";
            }else if (c == 38){
                if (gGameBox.snake.direct == "down"){
                    return ;
                }
                gGameBox.snake.direct = "up";
            }else if (c == 39){
                if (gGameBox.snake.direct == "left"){
                    return ;
                }
                gGameBox.snake.direct = "right";
            }else if (c == 40){
                if (gGameBox.snake.direct == "up"){
                    return ;
                }
                gGameBox.snake.direct = "down";
            }
        }
    },

定義一個(gè)方法布置場(chǎng)景,創(chuàng)建食物,創(chuàng)建蛇,分別調(diào)用了food.js文件、snake.js文件。用定時(shí)器來(lái)實(shí)現(xiàn)蛇的移動(dòng)、先清除蛇尾、判斷鍵盤(pán)按鍵來(lái)控制蛇的方向、調(diào)用蛇的移動(dòng)方法、讓食物隨機(jī)出現(xiàn)。

start: function() {
        gGameBox.init(); // 游戲初始化
        this.food = new Food();// 創(chuàng)建食物
        this.snake = new Snake(); // 創(chuàng)建蛇
        this.timer=setInterval(function(){
            gGameBox.clear();
            gGameBox.keyControl();
            gGameBox.snake.move();
            gGameBox.food.show();
        },200);
    },

init為布置場(chǎng)景的方法,在js中創(chuàng)建表格然后加入頁(yè)面中。

    // 初始化
    init: function() {
        // 場(chǎng)景布置好, 用表格來(lái)做
        var oTable = document.createElement("table");
        for (var i = 0; i < gGameBox.rows; i++)
        {
            // 創(chuàng)建tr
            var oTr = document.createElement("tr"); 
            // 每一行,定義1個(gè)空數(shù)組
            var arr = [];
            for (var j = 0; j < gGameBox.cols; j++) {
                // 創(chuàng)建td
                var oTd = document.createElement("td"); 
                oTr.appendChild(oTd);
                // 將td放到空數(shù)組中
                arr.push(oTd);
            }
            // 將當(dāng)前行所有的td,壓入到 allTds 屬性中
            gGameBox.allTds.push(arr);
            oTable.appendChild(oTr);
        }
        // 添加到body
        document.body.appendChild(oTable);
    }

Food.js文件
我們用外接文件來(lái)寫(xiě)貪吃蛇中的食物。
先給食物的屬性橫坐標(biāo)x,縱坐標(biāo)y,并讓食物一開(kāi)始的坐標(biāo)就是隨機(jī)出現(xiàn)的(調(diào)用函數(shù)change())。

function Food() {
    // 坐標(biāo)
    this.x = 0;
    this.y = 0;
    // 一開(kāi)始就隨機(jī)位置
    this.change();
}

在食物的原型中加入食物的方法(show為食物出現(xiàn)在頁(yè)面中定義了食物的樣式,change為食物出現(xiàn)的位置為隨機(jī)的)。

// 方法1: 出現(xiàn)在環(huán)境中
Food.prototype.show = function() {
    gGameBox.allTds[this.y][this.x].className = "food";
}
// 方法2: 改變位置, 隨機(jī)的
Food.prototype.change = function() {
    this.x = parseInt(Math.random() * gGameBox.cols);
    this.y = parseInt(Math.random() * gGameBox.rows);
    this.show();
}

snake.js文件
我們用外接文件來(lái)寫(xiě)貪吃蛇中的蛇(注意蛇很有靈性需要特別小心)。
先定義了一個(gè)arr數(shù)組用來(lái)存放蛇節(jié)的坐標(biāo)。x其實(shí)為表格的列數(shù),y為表格的行數(shù)。
direct為讓蛇一開(kāi)始便讓其往右邊移動(dòng)。
fresh為讓蛇出現(xiàn)在地圖中。

function Snake(){
    this.arr = [
        {x: 5, y: 1},
        {x: 4, y: 1},
        {x: 3, y: 1},
        {x: 2, y: 1},
        {x: 1, y: 1},
    ];
    this.direct = "right";
    this.fresh();
}

在蛇的原型中加入讓蛇顯示的行為。

Snake.prototype.fresh = function(){
    for(var i = 0; i<this.arr.length; i++){
       var x = this.arr[i].x;
       var y = this.arr[i].y;
       gGameBox.allTds[y][x].className = "snake" 
    }
}

在蛇的原型中加入蛇的移動(dòng)行為move,并判斷按鍵后改變蛇的移動(dòng)方向,給出判斷游戲結(jié)束(蛇死亡)的條件。給出判斷是否吃到食物的條件,如果吃到就在蛇尾增加一節(jié)讓食物再隨機(jī)出現(xiàn)一個(gè),更新蛇的位置。蛇的移動(dòng)是通過(guò)在蛇頭加一個(gè)表格,蛇尾減去一個(gè)表格實(shí)現(xiàn)的unshift加一個(gè)蛇頭,pop刪除一個(gè)蛇尾然后更新蛇的位置。

Snake.prototype.move = function(){
        var x=this.arr[0].x;
        var y=this.arr[0].y;
    if(this.direct == "right"){
        x++; 
    }else if (this.direct =="down"){
        y++;
    }else if (this.direct == "left"){
        x--;
    }else if (this.direct =="up"){
        y--;
    }
    //判斷蛇是否over
    if(x >=gGameBox.cols|| y>=gGameBox.rows||x<0||y<0){ 
        clearInterval(gGameBox.timer);
        alert("GG");
        return;
    }
    //判斷蛇是否吃到food
    if(x == gGameBox.food.x && y==gGameBox.food.y){
        this.arr.unshift({x:x,y:y});
        gGameBox.food.change();
        this.fresh();
         return;
    }
    this.arr.unshift({x: x, y: y});
    this.arr.pop();
    this.fresh();
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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