天天看点

原生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

喜欢的朋友可以点赞收藏分享哦!!!!

继续阅读