天天看點

原生js面向對象方式實作貪吃蛇---斑碼出品,必屬精品

效果圖:
原生js面向對象方式實作貪吃蛇---斑碼出品,必屬精品
index.html 入口檔案
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>貪吃蛇</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        .box {
            margin: 50px auto;
        }
    </style>
</head>
<body>
    <div class="box"></div>
    <script src="js/Food.js"></script>
    <script src="js/Game.js"></script>
    <script src="js/Map.js"></script>
    <script src="js/Snake.js"></script>
    <script src="js/Stone.js"></script>
    <script>
    // 獲得容器對象
    var container = document.querySelector('.box'); 
    // 準備參數
    var map = new Map(container, 750, 750, 15, 15);
    // 圖檔有多個,坐标有多個
    var imgsObj = {
        head: ['./imgs/1.png', './imgs/2.png', './imgs/3.png', './imgs/4.png'],
        body: './imgs/5.png',
        foot: ['./imgs/6.png', './imgs/7.png', './imgs/8.png', './imgs/9.png']
    }
    var snake = new Snake(imgsObj);
    // 石頭的坐标有多個,石頭的坐标不能超越給出的行數和列數的-1
    var stone = new Stone('./imgs/block.png', [{row:3, col:3}, {row:3, col:4}, {row:3, col:5}, {row:7, col:3}]);
    var food = new Food('./imgs/food.jpg');
    // 執行個體化遊戲類,傳入四個對象
    var game = new Game(snake, stone, map, food); 
    // 調用遊戲對象
    game.start();
    // 綁定鍵盤事件
    document.onkeydown = function(e) {
        // 調用遊戲中的按鍵
        game.keydown(e.keyCode); 
    }
    </script>
</body>
</html>
           
game類
function Game(snake, stone, map, food) {
    this.snake = snake;
    this.stone = stone;
    this.map = map;
    this.food = food;
    this.dom = this.map.dom;
    this.timer = null;
}

// 提供一個按鍵的處理函數
Game.prototype.keydown = function(v) {
    // 判斷鍵盤碼的合法性, 除了上下左右,其他的都忽略
    if (v >= 37 && v <= 40) {
        // 調用蛇頭的改變方向
        this.snake.changeDirection(v);
    }
}

// 檢測是否吃到食物
Game.prototype.checkFood = function() {
    // 檢測蛇頭的位置和食物的位置是否相同
    var snakeHead = this.snake.arr[0];
    var food = this.food.position;
    // 判斷檢測
    if (snakeHead.row == food.row && snakeHead.col == food.col) {
        // 此時吃到食物
        // alert('蛇要長大了');
        return true;
    }
}

// 檢測遊戲是否結束
Game.prototype.checkOver = function() {
    // 檢測蛇頭部的位置的合法性
    // 獲得蛇頭的位置
    var snakeHead = this.snake.arr[0];
    // 邊界
    if (snakeHead.col < 0 || snakeHead.row < 0 || snakeHead.col > this.map.col - 1 || snakeHead.row > this.map.row - 1) {
        return true;
    }
    // 石頭
    for (var i = 0; i < this.stone.arr.length; i++) {
        if (this.stone.arr[i].row == snakeHead.row && this.stone.arr[i].col == snakeHead.col) {
            return true;
        }
    }

    // 蛇的身體和尾部,除了頭部
    for (var i = 1; i < this.snake.arr.length; i++) {
        if (this.snake.arr[i].row == snakeHead.row && this.snake.arr[i].col == snakeHead.col) {
            return true;
        }
    }

}

// 遊戲結束的設定
Game.prototype.gameOver = function() {
    // 更改背景顔色
    document.body.style.backgroundColor = 'rgba(0, 0, 0, .5)';
    // 去除所有元素添加背景圖
    this.map.container.innerHTML = '';
    this.map.container.style.backgroundImage = 'url(./imgs/gameover.jpg)';
    this.map.container.style.backgroundSize = '100% 100%';

}

// 開始遊戲
Game.prototype.start = function() {
    // 繪制地圖
    this.map.render();
    // 繪制石頭
    this.stone.render(this.dom);
    // 繪制蛇
    this.snake.render(this.dom);
    // 随機食物的位置
    this.food.randPosition(this.dom, this.snake.arr, this.stone.arr);
    // 繪制食物
    this.food.render(this.dom);
    // 備份this
    var me = this;
    // 移動
    this.timer = setInterval(function() {
        // 清屏
        me.map.clear();
        // 蛇的移動
        me.snake.move();
        // 檢測是否吃到食物
        if (me.checkFood()) {
            // 蛇要長大
            me.snake.grow();
            // 食物重新随機
            me.food.randPosition(me.dom, me.snake.arr, me.stone.arr);
        }
        // 檢測是否結束遊戲
        if (me.checkOver()) {
            // 結束遊戲的設定
            me.gameOver();
            // 清除定時器
            clearInterval(me.timer);
            // 後續代碼停止執行
            return;
        }
        // 繪制石頭
        me.stone.render(me.dom);
        // 繪制蛇
        me.snake.render(me.dom);
        // 繪制食物
        me.food.render(me.dom);
       
    }, 100);
}
           
map類
/**
 * 
 * @param {*} container : 整個地圖放置的dom結構容器
 * @param {*} w : 寬度
 * @param {*} h :高度
 * @param {*} col :列數
 * @param {*} row :行數
 */
function Map(container, w, h, col, row) {
    this.container = container;
    this.w = w;
    this.h = h;
    this.col = col;
    this.row = row;
    this.dom = [];
}


// 繪制地圖的方法
Map.prototype.render = function() {
    // 建立行
    for (var i = 0; i < this.row; i++) {
        // 建立行的div
        var rowdiv = document.createElement('div');
        // 設定行的數組,用于存儲生成的coldiv
        var rowarr = [];
        // 建立列
        for (var k = 0; k < this.col; k++) {
            // 建立列的div
            var coldiv = document.createElement('div');
            // 添加樣式
            coldiv.style.boxSizing = 'border-box';
            coldiv.style.border = "1px solid grey";
            coldiv.style.float = 'left';
            coldiv.style.width = this.w / this.col + 'px';
            coldiv.style.height = this.h / this.row + 'px';
            // 讓列的div上樹
            rowdiv.appendChild(coldiv);
            // 将coldiv放入數組中
            rowarr.push(coldiv);
        }
        // 讓行的div上樹
        this.container.appendChild(rowdiv);
        // 将行的數組,放入到整個dom結構中
        this.dom.push(rowarr);

    }
    // 設定樣式
    this.container.style.width = this.w + 'px';
    this.container.style.height = this.h + 'px';
    this.container.style.border = '1px solid grey';

}

// 清屏操作
Map.prototype.clear = function() {
    for (var row = 0; row < this.dom.length; row++) {
        for (var col = 0; col < this.dom[row].length; col++) {
            this.dom[row][col].style.backgroundImage = 'none';
        }
    }
}

           
food類
function Food(url) {
    this.url = url;
    this.position = null;       
}

// 繪制食物
Food.prototype.render = function(dom) {
    // 繪制
    dom[this.position.row][this.position.col].style.backgroundImage = 'url(' + this.url + ')';
    dom[this.position.row][this.position.col].style.backgroundSize = 'cover';
}

// 随機食物的位置
Food.prototype.randPosition = function(dom, snakeArr, stoneArr) {
    // 不能再那些位置
    var stopArr = snakeArr.concat(stoneArr);
    // 确定随機值
    var rowMax = dom.length - 1;
    var colMax = dom[0].length - 1;
    // 選随機位置
    do {
        var row = Math.round(Math.random() * rowMax);
        var col = Math.round(Math.random() * colMax);
    } while((function(row, col){
        for (var i = 0; i < stopArr.length; i++) {
            // 判斷該位置是否和已經存在的位置沖突
            if (stopArr[i].row == row && stopArr[i].col == col) {
                return true;
            }
        }
    })(row, col));
    // 記錄食物的坐标
    this.position = {
        row: row,
        col: col
    }
}

           
snake類
function Snake(imgsObj) {
    // 圖檔
    this.imgsObj = imgsObj;
    // 坐标: 第一個為蛇頭,最後一個為尾部
    this.arr = [{row:5, col: 8}, {row:5, col: 7}, {row:5, col: 6}];
    // 蛇的方向:預設向右
    this.direction = 39;
    // 蛇頭的圖檔
    this.headUrl = imgsObj.head[2];
    // 蛇尾圖檔
    this.footUrl = imgsObj.foot[0];
    // 聲明鎖
    this.lock = false;
    // 聲明丢掉尾巴的變量
    this.dropTail = null;
}

// 繪制蛇的方法
Snake.prototype.render = function(dom) {
    // 繪制蛇頭
    var row = this.arr[0].row;
    var col = this.arr[0].col;
    // 确定蛇頭的圖檔
    dom[row][col].style.backgroundImage = 'url(' + this.headUrl + ')';
    dom[row][col].style.backgroundSize = 'cover';


    // 周遊坐标數組進行繪制蛇的身體
    for (var i = 1; i < this.arr.length - 1; i++) {
        // 接收行和列的坐标
        var row = this.arr[i].row;
        var col = this.arr[i].col;
        // 繪制
        dom[row][col].style.backgroundImage = 'url(' + this.imgsObj.body + ')';
        dom[row][col].style.backgroundSize = 'cover';
    }
    // 确定蛇尾的圖檔
    var tail =  this.arr[this.arr.length - 1];
    var hip = this.arr[this.arr.length - 2];
    // 判斷屁股和尾巴的位置關系
    if (tail.row == hip.row) {
        this.footUrl = tail.col > hip.col ? this.imgsObj.foot[2]: this.imgsObj.foot[0];
    } else {
        this.footUrl = tail.row > hip.row ? this.imgsObj.foot[3]: this.imgsObj.foot[1];
    }
    // 繪制蛇尾
    var row = this.arr[this.arr.length - 1].row;
    var col = this.arr[this.arr.length - 1].col;
    // 确定蛇頭的圖檔
    dom[row][col].style.backgroundImage = 'url(' + this.footUrl + ')';
    dom[row][col].style.backgroundSize = 'cover';
}

// 蛇的移動
Snake.prototype.move = function(dom) {
    var head = {
        row: this.arr[0].row,
        col: this.arr[0].col
    };
    // 判斷方向,生成新的頭部坐标
    switch(this.direction) {
        // 向右
        case 39:
            head.col++;
        break;
        // 向左
        case 37:
            head.col--;
        break;
        // 向上
        case 38:
            head.row--;
        break;
        // 向下
        case 40:
            head.row++;
        break;
    }

    // 改變坐标的數組,将新的頭部插入到數組中,将原來的尾部彈出
    this.arr.unshift(head);
    // 接收丢掉的尾巴
    this.dropTail = this.arr.pop();
    // 重置鎖
    this.lock = false;
}

// 改變蛇的方向
Snake.prototype.changeDirection = function(v) {
    // 判斷鎖
    if (this.lock) {
        // console.log(v, '此時已經上鎖');
        return;
    }
    // 更改鎖
    this.lock = true;
    // 方向的判斷
    if (Math.abs(v - this.direction) % 2 == 1) {
        // 改變方向
        this.direction = v;
        // 改變蛇頭圖檔
        this.headUrl = this.imgsObj.head[this.direction - 37]; 
    } 
}

// 蛇生長
Snake.prototype.grow = function() {
    // 将丢掉的尾巴,放入到數組中
    this.arr.push(this.dropTail);

}
           
stone障礙物類
function Stone(url, arr) {
    this.url = url;
    this.arr = arr;
}

// 繪制石頭
Stone.prototype.render = function(dom) {
    // 周遊數組繪制的過程
    for (var i = 0; i < this.arr.length; i++) {
        // 接收對應的行和列
        var row = this.arr[i].row;
        var col = this.arr[i].col;
        // console.log(this.arr[i]);
        // 設定對應的dom
        dom[row][col].style.backgroundImage = 'url(' + this.url + ')';
        dom[row][col].style.backgroundSize = 'cover';
    }
}
           
代碼結構:
原生js面向對象方式實作貪吃蛇---斑碼出品,必屬精品
遊戲中涉及的圖檔:
原生js面向對象方式實作貪吃蛇---斑碼出品,必屬精品
原生js面向對象方式實作貪吃蛇---斑碼出品,必屬精品
原生js面向對象方式實作貪吃蛇---斑碼出品,必屬精品
原生js面向對象方式實作貪吃蛇---斑碼出品,必屬精品
原生js面向對象方式實作貪吃蛇---斑碼出品,必屬精品
原生js面向對象方式實作貪吃蛇---斑碼出品,必屬精品
原生js面向對象方式實作貪吃蛇---斑碼出品,必屬精品
原生js面向對象方式實作貪吃蛇---斑碼出品,必屬精品
原生js面向對象方式實作貪吃蛇---斑碼出品,必屬精品
原生js面向對象方式實作貪吃蛇---斑碼出品,必屬精品
原生js面向對象方式實作貪吃蛇---斑碼出品,必屬精品
原生js面向對象方式實作貪吃蛇---斑碼出品,必屬精品
圖檔的命名:
原生js面向對象方式實作貪吃蛇---斑碼出品,必屬精品

需要下載下傳源檔案的朋友可以加入QQ群:1103015245

喜歡的朋友可以點贊收藏分享哦!!!!

繼續閱讀