1. 程式人生 > 其它 >使用原生js編寫貪吃蛇小遊戲

使用原生js編寫貪吃蛇小遊戲

貪吃蛇小遊戲大家都不陌生,基本上都玩過,而使用js,也能夠編寫出各種各樣的小遊戲,今天就寫一下貪吃蛇這個經典小遊戲

效果圖:

html程式碼

程式碼沒啥可說的,兩個下拉框分別對應著遊戲棋盤大小和貪吃的速度

css程式碼

原本還用彈性佈局將#box居中的,但截不了那麼長的圖,就省略了,如果感覺不好看,可以自己編寫樣式

下面是加上程式碼,提醒一句,js程式碼太多了(兩百多行),最好單獨寫一個檔案,這裡為了方便,就不更改了,一篇文章寫下來了

js程式碼
// 第一步寫的東西 把遊戲中的 一些公共的資料值 封裝在一個公共的物件裡
var Common = new function () {
this.width = 20; //x方向的格子數 預設是20 可以根據後面的程式中需要改變
this.height = 20;
// speed 速度
this.speed = 250; //這個值越小 蛇跑的越快
this.workThread = null;

}

// 對蛇的行走方向進行封裝
var Direction = new function () {
// 左鍵
this.LEFT = 37;
// 上鍵
this.UP = 38;
// 右鍵
this.RIGHT = 39;
// 下鍵
this.DOWN = 40;
}
// 把位置封裝為一個建構函式
var Position = function (x, y) {
this.X = 0;
this.Y = 0;
if (arguments.length >= 1) this.X = x;
if (arguments.length >= 2) this.Y = y;
}
// 食物的建構函式
function Food() {
// 食物的位置
this.pos = new Position(); //初始化 食物的位置 在0.0; 在後面的程式中要實現位置是隨機的
// 下面的是真正的實現創造食物,建立的過程中必須要考慮三個限制
// 食物的位置是隨機的
// 食物的位置不能出界
// 食物的位置不能在蛇的身上
this.Create = function (snakePos) { //蛇的身體佔據的位置引數的形式傳進來
// 建立食物的第一個步驟 消除上一個食物 消除上一個食物的背景顏色
document.getElementById('box_' + this.pos.X + '' + this.pos.Y).className = '';
var x = 0;
var y = 0;
var flag = false;
// 生成的食物不能在蛇的身上出現
do {
// 搞兩個隨機數座標值
x = Math.round(Math.random() * (Common.width - 1));
y = Math.round(Math.random() * (Common.height - 1));
// 把上面生成的隨機數排除出蛇的身體
if (snakePos instanceof Array) {
for (var i = 0; i < snakePos.length; i++) {
if (x == snakePos[i].X && y == snakePos[i].Y) {
flag = true;
break // 這裡結束的是for迴圈
}
}
}
} while (flag);
// 最後跳出了do while 迴圈得到的x y值就一定不是蛇身上的位置 座標 也是隨機的 也是不出界的
this.pos = new Position(x, y);
document.getElementById('box

' + x + '' + y).className = 'food';
}
}
// 定義蛇的建構函式
function Snake() {
// 判斷蛇動的過程中 還是剛剛動完
this.isDone = false;
// 預設蛇移動方向是右邊
this.dir = Direction.RIGHT;
// 預設蛇初始的情況 身體長度為1個格子 位置(0,0)
this.pos = new Array(new Position());
// 實現蛇的移動
this.Move = function () {
// 第一步擦屁股
document.getElementById('box
' + this.pos[0].X + '_' + this.pos[0].Y).className = '';

    // 第二步 除了蛇頭野外 每一個蛇的身體部分 向前蠕動一步
    for (var i = 0; i < this.pos.length - 1; i++) {
        console.log(this.pos);
        this.pos[i].X = this.pos[i + 1].X;
        this.pos[i].Y = this.pos[i + 1].Y;
    }
    var head = this.pos[this.pos.length - 1]
    // 第三步重新給蛇整一個頭
    switch (this.dir) {
        case Direction.LEFT:
            head.X--;
            break;
        case Direction.RIGHT:
            head.X++;
            break;
        case Direction.UP:
            head.Y--;
            break;
        case Direction.DOWN:
            head.Y++;
            break;
    }
    this.pos[this.pos.length - 1] = head;

    // 畫蛇  如果蛇在上一步的移動中死掉了 就沒有畫的必要了
    // 在畫蛇之前 判斷蛇死沒死
    // 1.蛇跑出界 2.咬到自己
    for (var i = 0; i < this.pos.length; i++) {
        var idExits = false; //蛇有沒有 有沒有咬到自己的標記  true 表示咬到了
        for (var j = i + 1; j < this.pos.length; j++) {
            if (this.pos[i].X == this.pos[j].X && this.pos[i].Y == this.pos[j].Y) {
                idExits = true;
                break;
            }
        }
        if (idExits) {
            // game  over  蛇咬到自己 遊戲結束
            this.Over();
            break;
        }
        // 再迴圈中  遊戲沒有結束 證明蛇沒有咬到自己
        // 繼續判斷 蛇有沒有跑出界
        var std = document.getElementById('box_' + this.pos[i].X + '_' + this.pos[i].Y);
        if (std) {
            // 表示蛇沒有出界
            // 畫出蛇的身體
            std.className = "snake";
        } else {
            // 蛇出界了
            this.Over();
            break
        }
    }
    this.isDone = true;
}
// 此方法表示遊戲結束
this.Over = function () {
    clearInterval(Common.workThread);
    alert('遊戲結束')
}
this.isDone = true;
// 設定蛇新的方向
this.setDir = function (dir) {
    switch (dir) {
        case Direction.UP:
            if (this.isDone && this.dir != Direction.DOWN) {
                this.dir = Direction.UP;
                this.isDone = false;
            }
            break;
        case Direction.DOWN:
            if (this.isDone && this.dir != Direction.UP) {
                this.dir = Direction.DOWN;
                this.isDone = false;
            }
            break;
        case Direction.LEFT:
            if (this.isDone && this.dir != Direction.RIGHT) {
                this.dir = Direction.LEFT;
                this.isDone = false;
            }
            break;
        case Direction.RIGHT:
            if (this.isDone && this.dir != Direction.LEFT) {
                this.dir = Direction.RIGHT;
                this.isDone = false;
            }
            break;
    }



}
this.Eat = function (food) {

    var head = this.pos[this.pos.length - 1];
    var isEat = false; //false  表示蛇沒得吃 true 表示 蛇有的吃
    switch (this.dir) {
        case Direction.UP:
            console.log(head.X);
            console.log(food.pos);

            if (head.X == food.pos.X && head.Y == food.pos.Y + 1) {
                // console.log(000);
                isEat = true;
            }
            break;
        case Direction.RIGHT:
            if (head.X == food.pos.X - 1 && head.Y == food.pos.Y) {
                // console.log(000);
                isEat = true;
                console.log(true);
            }
            break;
        case Direction.DOWN:
            if (head.X == food.pos.X && head.Y == food.pos.Y - 1) {
                // console.log(000);
                isEat = true;
                console.log(true);
            }
            break;
        case Direction.LEFT:
            if (head.X - 1 == food.pos.X && head.Y == food.pos.Y) {
                // console.log(000);
                isEat = true;
                console.log(true);
            }
            break;

    }
    if (isEat) {
        // 實現吃的動作
        // console.log(0);
        this.pos[this.pos.length] = new Position(food.pos.X, food.pos.Y)
        food.Create(this.pos)
    }
}

}

function init() {
var html = [];
html.push("");
for (var y = 0; y < Common.height; y++) {
html.push('')
for (var x = 0; x < Common.width; x++) {
html.push('<td id=box_' + x + '_' + y + '>');
}
html.push('')
}
html.push('
')
var tableStr = html.join('')
var panel = document.getElementById('panel');
panel.innerHTML = tableStr
}

// window.onload 函式在頁面以及頁面資源剛剛載入完成後立即執行的函式體
window.onload = function () {
// addEventListener() 方法用於向指定元素新增事件控制代碼。
// document.addEventListener('keydown', function (ev) {
// var evt = window.event || ev;
// })
// 初始化格子
init();

document.getElementById('btnSart').onclick = function () {
    var snakePos = [new Position(0, 0)];
    var food = new Food();
    food.Create(snakePos);
    var snake = new Snake();
    Common.workThread = setInterval(function () {
        snake.Eat(food);
        snake.Move();
        document.addEventListener('keydown', function (evt) {
            var evnt = window.event || evt;
            snake.setDir(evnt.keyCode);
        }, false)
    }, Common.speed)
}
document.getElementById('selSize').onchange = function () {
    Common.width = this.value;
    Common.height = this.value;
    init()
}
document.getElementById('selSpeed').onchange = function () {
    Common.speed = this.value;

    init()
}

}