菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
0
0

javaScript实战——贪吃蛇

原创
05/13 14:22
阅读数 246

功能实现:

1、地图map,我们通过在map类里面用二维数组建立行和列,实现网格状容器地图
2、食物food,功能一是蛇吃掉食物后食物消失,功能二重新生成新的食物,我们通过设置容器背景图的方式绘制食物,并获取食物和蛇头在map中的位置,如果蛇头与食物坐标一致,删除该位置容器的食物背景图。通过随机数的方式生成新的随机坐标,并将此位置的容器背景图更换为食物。
3、障碍物block,一样通过背景图绘制在地图上,功能一蛇碰到障碍物游戏结束,与蛇吃食物的方法类似,也是通过比较蛇头与障碍物的位置,坐标一致则游戏结束,功能二蛇每次吃掉食物后,重置障碍物位置,也是与重置食物的方法类似,不过因为障碍物是多个坐标,我们要通过数组控制,麻烦一点。
4、蛇snake,蛇吃掉食物后,需要增加一单位的长度,我们通过给蛇的数组末尾添加一个数据实现,此外蛇碰撞地图边界后,游戏结束。

温馨提示:

咱们这个贪吃蛇项目全程都用的面向对象的编程方式,处处涉及到对象、构造函数、原型,不建议小白食用!(把这些知识学完再看)

源码:

index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>贪吃蛇</title>
        <style>
            * {
                margin: 0;
                padding: 0;
                list-style: none;
            }
            .box {
                margin: 50px auto;
            }
            .row {
                display: flex;
            }
            .col {
                flex: 1;
                border: 1px solid #ccc;
                box-sizing: border-box;
                background-size: cover;
            }
        </style>
    </head>
    <body>
        <script src="./js/game.js"></script>
        <script src="./js/map.js"></script>
        <script src="./js/snake.js"></script>
        <script src="./js/food.js"></script>
        <script src="./js/block.js"></script>
        <script>
        var map = new Map(20, 20, 500, 500);
        var snake = new Snake({
            head: ['./img/1.png', './img/2.png', './img/3.png', './img/4.png'], //左37,上38,右39, 下40,
            body: ['./img/5.png'],
            tail: ['./img/8.png', './img/9.png', './img/6.png', './img/7.png'] //左37,上38,右39, 下40,
        });
        var food = new Food(6, 2, './img/food.jpg');
        var block = new Block();
        var game = new Game(map, snake, food, block);
        </script>
    </body>
    </html>

game.js

    // 游戏类,控制地图、蛇、食物、障碍物的交互
    function Game(map, snake, food, block) {
        this.map = map;
        this.snake = snake;
        this.food = food;
        this.block = block;
        this.timebar;
        this.state = true;
        this.init();
        this.gameStart();
        this.bindEvent();
    }
    //初始化
    Game.prototype.init = function() {
        this.renderMap();
        this.renderFood();
        this.renderBlock();
        this.renderSnake();
    }
    Game.prototype.renderMap = function() {
        this.map.init();
    }
    Game.prototype.renderFood = function() {
        this.map.arr[this.food.y][this.food.x].style.backgroundImage = 'url(' + this.food.img + ')';
    }
    Game.prototype.renderBlock = function() {
        for (var i = 0; i < this.block.arr.length; i++) {
            this.map.arr[this.block.arr[i].y][this.block.arr[i].x].style.backgroundImage = 'url(' + this.block.img + ')';
        };
    };
    Game.prototype.renderSnake = function() {
        //绘制头
        var snakeHead = this.snake.arr[0];
        this.map.arr[snakeHead.y][snakeHead.x].style.backgroundImage = 'url(' + this.snake.headImg + ')';
        //绘制尾
        var snakeTail = this.snake.arr[this.snake.arr.length - 1];
        this.map.arr[snakeTail.y][snakeTail.x].style.backgroundImage = 'url(' + this.snake.tailImg + ')';
        //绘制身体
        for (var i = 1; i < this.snake.arr.length - 1; i++) {
            var snakeBody = this.snake.arr[i];
            this.map.arr[snakeBody.y][snakeBody.x].style.backgroundImage = 'url(' + this.snake.bodyImg + ')';
        }
    }
    // 游戏启动
    Game.prototype.gameStart = function() {
        var me = this;
        this.timebar = setInterval(function() {
            me.snake.move();
            me.checkMap();
            me.checkBlock();
            if (me.state) {
                me.map.clear();
                me.renderFood();
                me.renderBlock();
                me.renderSnake();
            };
            me.checkFood();
        },400)
    }
    // 绑定键盘事件,通过键盘的上下左右控制蛇运动的方向
    Game.prototype.bindEvent = function() {
        var me = this;
        window.onkeydown = function(e) {
            me.snake.change(e.keyCode);
        }
    }
    // 边界处理,当蛇碰撞到地图边界时,结束游戏
    Game.prototype.checkMap = function() {
        var head = this.snake.arr[0];
        if (head.x < 0 || head.y < 0 || head.x > this.map.col - 1 || head.y > this.map.row - 1) {
            this.gameOver();
            console.log('边界');
        }
    }
    // 障碍物处理,当蛇碰撞到障碍物时,结束游戏
    Game.prototype.checkBlock = function() {
        var head = this.snake.arr[0];
        for (var i = 0; i < this.block.arr.length; i++) {
            if (head.x === this.block.arr[i].x && head.y === this.block.arr[i].y) {
                this.gameOver();
                console.log('障碍物');
            }
        }
    }
    // 食物处理,当蛇吃到食物时,蛇的长度+1,同时重置食物和障碍物的位置,游戏继续
    Game.prototype.checkFood = function() {
        var head = this.snake.arr[0];
        if (head.x === this.food.x && head.y === this.food.y) {
            this.snake.snakeGrow();
            this.resetBlock();
            this.resetFood();
        }
    }
    // 重置食物位置
    Game.prototype.resetFood = function() {
        let x = parseInt(this.map.col * Math.random());
        let y = parseInt(this.map.row * Math.random());
        // 食物重置的位置不能在障碍物内
        for (var i = 0; i < this.block.arr.length; i++) {
            var block = this.block.arr[i];
            if (x === block.x && y === block.y) {
                this.resetFood();
                return;
            }
        }
        // 食物重置的位置不能在蛇身上
        for (var i = 0; i < this.snake.arr.length; i++) {
            var snake = this.snake.arr[i];
            if (x === snake.x && y === snake.y) {
                this.resetFood();
                return;
            }
        }
        this.food.reset(x, y);
    }
    // 重置障碍物位置
    Game.prototype.resetBlock = function() {
        let x = parseInt((this.map.col - this.block.arr.length) * Math.random());
        let y = parseInt((this.map.row - this.block.arr.length) * Math.random());
        // 重置障碍物第一个位置不能在蛇身上
        for (var i = 0; i < this.snake.arr.length; i++) {
            var snake = this.snake.arr[i];
            if (x === snake.x && y === snake.y) {
                this.resetBlock();
                return;
            }
        }
        this.block.reset(x, y);
    }
    // 结束游戏,弹框告知玩家游戏分数即贪吃蛇的长度。
    Game.prototype.gameOver = function() {
            clearInterval(this.timebar);
            this.state = false;
            alert('亲爱的玩家,游戏结束啦,您的分数为' + this.snake.arr.length + '分')
    }

map.js

    // 地图类
    function Map(row, col, width, height) {
        this.row = row;
        this.col = col;
        this.width = width;
        this.height = height;
        this.dom = document.createElement('div');
        this.arr = [];
    }
    // 初始化地图
    Map.prototype.init = function() {
        for (var i = 0; i < this.row; i++) {
            // console.log(i);
            var rowDom = document.createElement('div');
            rowDom.className = 'row';
            var rowArr = [];
            for (var j = 0; j < this.col; j++) {
                var colDom = document.createElement('div');
                colDom.className = 'col';
                colDom.style.width = this.width / this.col + 'px';
                colDom.style.height = this.height / this.row + 'px';
                rowDom.appendChild(colDom);
                rowArr.push(colDom);
            }
            this.dom.appendChild(rowDom);
            this.arr.push(rowArr);
        }
        this.dom.className = 'box';
        this.dom.style.width = this.width + 'px';
        this.dom.style.height = this.height + 'px';
        document.body.appendChild(this.dom);
    }
    // 当蛇移动时,清除蛇,重新绘制蛇
    Map.prototype.clear = function() {
        for (var i = 0; i < this.arr.length; i++) {
            for (var j = 0; j < this.arr[i].length; j++) {
                this.arr[i][j].style.backgroundImage = '';
            }
        }
    }

food.js

    // 食物类
    function Food(x, y, img) {
        this.x = x;
        this.y = y;
        this.img = img;
    }
    // 重置食物的位置
    Food.prototype.reset = function(x,y) {
        this.x = x;
        this.y = y;
        console.log(this.x, this.y);
    }

block.js

    // 障碍物类
    function Block() {
        this.x;
        this.y;
        this.arr = [
            {x: 3, y: 6},
            {x: 4, y: 6},
            {x: 5, y: 6},
            {x: 6, y: 6},
            {x: 7, y: 6},
            {x: 8, y: 6},
        ];
        this.img = './img/block.png';
    }
    // 重置障碍物位置
    Block.prototype.reset = function(x, y) {
        this.x = x;
        this.y = y;
        // 通过随机数控制障碍物方向,如果随机数<0.5,障碍物呈水平方向,否则呈垂直方向
        var toggle = Math.random();
        if (toggle < 0.5) {
            this.arr = [
                {x: this.x, y: this.y},
                {x: this.x + 1, y: this.y},
                {x: this.x + 2, y: this.y},
                {x: this.x + 3, y: this.y},
                {x: this.x + 4, y: this.y},
                {x: this.x + 5, y: this.y},
            ]
        } else {
            this.arr = [
                {x: this.x, y: this.y + 1},
                {x: this.x, y: this.y + 2},
                {x: this.x, y: this.y + 3},
                {x: this.x, y: this.y + 4},
                {x: this.x, y: this.y + 5},
                {x: this.x, y: this.y + 6},
            ] 
        }
    }

snake.js

    // 蛇类
    function Snake(img) {
        this.arr = [
            {x: 6, y: 4},
            {x: 5, y: 4},
            {x: 4, y: 4},
        ];
        this.img = img;
        this.lock = false;
        this.direction = 39;
        this.headImg = this.img.head[this.direction - 37];
        this.bodyImg = this.img.body[0];
        this.tailImg = this.img.tail[this.direction - 37];
    }
    // 通过键盘上下左右键控制蛇移动方向
    Snake.prototype.move = function() {
        //创建头对象
        var newHead = {x: this.arr[0].x, y: this.arr[0].y};
        //左37,上38,右39, 下40,
        switch (this.direction) {
            //向左,x-1,y不变
            case 37:
                newHead.x -= 1;
                break;
            //向上,y+1,x不变
            case 38:
                newHead.y -= 1;
                break;
            //向右,x+1,y不变
            case 39:
                newHead.x += 1;
                break;
            //向下,y-1,x不变
            case 40:
                newHead.y += 1;
                break;
            default:
                break;
        }
        this.arr.unshift(newHead);
        this.arr.pop();
        var last_2 = this.arr[this.arr.length - 2];
        var last_1 = this.arr[this.arr.length - 1];
        if (last_1.x === last_2.x) {
            if (last_1.y < last_2.y) {
                this.tailImg = this.img.tail[3];
            } else {
                this.tailImg = this.img.tail[1];
            }
        } else{
            if (last_1.x < last_2.x) {
                this.tailImg = this.img.tail[2];
            } else {
                this.tailImg = this.img.tail[0];
            }
        }
        this.lock = false;
    }
    // 改变蛇的方向
    Snake.prototype.change = function(code) {
        if (this.lock) {
            return;
        }
        this.lock = true;
        var num = Math.abs(code - this.direction);
        if (num === 0 || num === 2) {
            return;
        }
        this.direction = code;
        this.headImg = this.img.head[this.direction - 37];
    }
    // 蛇吃掉食物后,蛇的长度增加1
    Snake.prototype.snakeGrow = function() {
        var tail = this.arr[this.arr.length - 1];
        this.arr.push(tail);
    }

效果展示:

图片.png

项目源码及素材:

链接:https://pan.baidu.com/s/1YEx7Agcskb_p–K3YquWMw?pwd=Q7D0
提取码:Q7D0

发表评论

0/200
0 点赞
0 评论
收藏