JavaScript写贪吃蛇

分析:

游戏中有三个对象:地图(map), 食物(food), 蛇(snake)

地图很简单就是一个div盒子,给样式即可,蛇,和食物都是属于地图中的元素,相对于地图不断改变自己的坐标值,不要忘了给地图定位

食物

1,食物的构造函数,  属性===width,height,backgroundColor,left,top,

2,方法======init()初始化方法, 食物的位置在map中是随机的,要给 left,top设定随机值,设定完成后将食物div 追加到map中

值得注意的是:要定义一个数组来存储食物,写一个私有函数通过遍历这个数组,找到食物div,并将它们从map中移除,同时清空数组,方便在此使用

1,蛇的构造函数 

属性====蛇是由一连串的div组成,这些div又分别是对象,它们有width,height,backgroundColor,left,top direction(蛇前进的方向) 将这些小div的样式放在json数据中,并将json储存在一个数组snakeBody中,在初始化蛇时,遍历数组,获得小div的样式json数据包,将这些样式分别给div,这些div组成一条初始的蛇;

2,方法====init()初始化,遍历snakeBody数组,获得样式的json数据包,将样式值给新创建的div,将div追加到map中,小蛇创建成功,

值得注意的是:初始化之前要删除之前map内的小蛇,跟食物类似,事先创建一个数组,储存小蛇body的div,写一个移除小蛇私有函数,遍历该数组,找到所有div,将它们从map中移除,并清空数组,方便下次使用

===move()  让蛇动起来的方法:除了蛇头(蛇头通过改变left,top的值来移动),剩下的组成蛇身体的每个小div的位置等于前面一个div的位置,这样蛇就移动了.   下面我们来解决蛇头怎么动的问题: 蛇头要根据方向东,通过switch  case 语句,判断对应的方向该往哪里动一格.    

移动的同时要考虑蛇吃到食物,通过判断食物的位置和蛇头的坐标相同来确定蛇吃到食物,这时向snakBody的样式json数据的数组中,添加一个样式json数据包,让数据包中的属性和蛇尾的div的样式属性相同即可,然后初始化snake,初始化食物;

游戏对象:

将前面封装的对象添加到游戏对象中

1,构造函数  属性===food对象,snake对象,map对象

2,方法=====初始化init(); 这个方法主要完成四件事: 初始化food, 初始化snake, 让蛇动起来, 开启键盘监听

===让蛇动起来:要添加定时器,定时器中不断调用snake对象的move方法,和init()方法,这样蛇就动起来了,什么时候停止?  蛇撞墙了,什么是撞墙了? 蛇头越界, 蛇头坐标小于最小值,或则大于最大值,这时清除定时器,弹出对话框,告诉用户游戏结束.

===开启键盘监听:用户要操作,,改变蛇的移动方向,监听上下左右键,来改变snake对象中direction属性的值,从而改变蛇的移动方向

所有对象写完,实例化 对象,调用初始化函数,游戏开始................

代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>贪吃蛇</title>
    <style>
        .map {
            width: 800px;
            height: 800px;
            background-color: #ccc;
            margin: 0 auto;
            position: relative;
        }
    </style>
</head>
<body>
<div class="map">
</div>

<script>

    //自调用======================================================================================  食物
    (function (window) {
        var element = [];

        function Food(width, height, color, left, top) {
            this.width = width || 20;
            this.height = height || 20;
            this.color = color || 'green';
            this.left = left || 0;
            this.top = top || 0;
        }

        //添加初始化方法
        Food.prototype.init = function (map) {
            console.log('初始化食物');
            //初始化,清除数组中的元素,私有函数,方法外定义
            remove();
            //创建小盒子元素
            var div = document.createElement('div');
            //获得随机左右值
            this.left = Math.floor(Math.random() * map.offsetWidth / this.width) * this.width;
            this.top = Math.floor(Math.random() * map.offsetHeight / this.height) * this.height;
            //为div添加样式
            div.style.position = 'absolute';
            div.style.width = this.width + 'px';
            div.style.height = this.height + 'px';
            div.style.left = this.left + 'px';
            div.style.top = this.top + 'px';
            div.style.backgroundColor = this.color;
            //追加到地图中
            map.appendChild(div);
            //存入数组中
            element.push(div);
        };

        //清除数组中的元素,以及map中的小方块
        function remove() {
            for (var i = 0; i < element.length; i++) {
                var ele = element[i];
                //删除map中的食物
                ele.parentElement.removeChild(ele);
                //删除数组中的元素
                element.splice(i, 1);
            }
        }

        //将变量暴露到window中
        window.Food = Food;
    })(window);


    //自调用======================================================================================  小蛇

    (function (window) {
        var element = [];//数组储存蛇
        //自定义蛇的构造函数
        function Snake(width, height, direction) {
            this.width = width || 20;
            this.height = height || 20;
            this.direction = direction || 'right';
            //蛇身体
            this.snakeBody = [
                {x: 3, y: 2, color: 'red'},
                {x: 2, y: 2, color: 'orange'},
                {x: 1, y: 2, color: 'orange'}
            ];
        }

        //让小蛇初始化
        Snake.prototype.init = function (map) {
            console.log('初始化小蛇');
            //remove()  移除之前的蛇
            remove();
            //遍历数组为蛇身体的的每一个部分添加样式
            for (var i = 0; i < this.snakeBody.length; i++) {
                var div = document.createElement('div');
                div.style.width = this.width + 'px';
                div.style.height = this.height + 'px';
                div.style.left = this.snakeBody[i].x*this.width + 'px';
                div.style.top = this.snakeBody[i].y*this.height + 'px';
                div.style.backgroundColor = this.snakeBody[i].color;
                div.style.position = 'absolute';
                //追加到map中
                map.appendChild(div);
                //添加到数组中
                element.push(div);
            }

        };
        //让小蛇移动
        Snake.prototype.move = function(food,map){
          //从蛇尾开始遍历
            var i = this.snakeBody.length - 1;
            for (;i>0;i--){
               this.snakeBody[i].x = this.snakeBody[i-1].x;
               this.snakeBody[i].y = this.snakeBody[i-1].y;
            }
            //蛇头运动
            switch(this.direction){
                case 'top':
                    this.snakeBody[0].y -= 1;break;
                case 'bottom':
                    this.snakeBody[0].y += 1; break;
                case 'left':
                    this.snakeBody[0].x -= 1; break;
                case 'right':
                    this.snakeBody[0].x += 1;
                    break;
            }

            //蛇吃食物,当蛇头和食物重合时,即蛇吃到食物
            //获得蛇头坐标
            var headX = this.snakeBody[0].x*this.width;
            // console.log(headX);
            var headY = this.snakeBody[0].y*this.height;
            // console.log(headY);
            if(headX == food.left && headY == food.top){
                //向snakeBody数组中追加一个对象,这个对象的位置和最后一个位置的样式相同
                //获取身体的最后一个div
                console.log("食用");
                var last = this.snakeBody[this.snakeBody.length - 1];
                this.snakeBody.push({
                    x:last.x,
                    y:last.y,
                    color:last.color
                });
                //初始化食物
                food.init(map);
            }
            // this.init(map);
        };


        //私有函数,删除蛇
        function remove() {
            var i = element.length - 1;
            for (; i >= 0; i--) {
                var ele = element[i];
                ele.parentElement.removeChild(ele);
                element.splice(i, 1);
            }
        }
        //暴露局部变量
        window.Snake = Snake;
    })(window);

    //自调用======================================================================================  游戏

    (function(window){
        //创建游戏对象
        var that = null;
        function Game(map){
            this.food = new Food(20,20,'black');
            this.snake = new Snake();
            this.map = map;
            that = this;
        }

        //添加方法初始化游戏
        Game.prototype.init = function(){
            this.food.init(this.map);
            this.snake.init(this.map);
            //小蛇跑起来
            this.runSnake(this.food,this.map);
            //监听键盘
            this.keyDown();
        };

        //添加runSnake方法
        Game.prototype.runSnake = function(food,map){//这里的food,map是形参  不用this,内部有效
            console.log('runSnake调用');
            var timeId = setInterval(function(){
                this.snake.move(food,map);
                this.snake.init(map);
                //判断蛇头撞墙,游戏结束
                var headX = this.snake.snakeBody[0].x*this.snake.width;
                var headY = this.snake.snakeBody[0].y*this.snake.height;
                var maxX = map.offsetWidth;
                var maxY = map.offsetHeight;
                if(headX < 0 || headX > maxX){
                    alert('游戏结束');
                    clearInterval(timeId);
                }
                if(headY < 0 || headY > maxY){
                    alert('游戏结束');
                    clearInterval(timeId);
                }
            }.bind(that),200)
        };

        //添加键盘监听
        Game.prototype.keyDown = function(){
            console.log('keyDown调用');
            document.addEventListener('keydown',function(e){
                switch(e.keyCode){
                    case 37: this.snake.direction = 'left';break;
                    case 38: this.snake.direction = 'top';break;
                    case 39: this.snake.direction = 'right';break;
                    case 40: this.snake.direction = 'bottom';break;
                }
            }.bind(that),false)
        };

        window.Game = Game;
    })(window);


    //创建游戏对象
    var gm =new Game(document.querySelector('.map'));
    //初始化游戏
    gm.init();

    //test
    // var food = new Food();
    // var map = document.querySelector('.map');
    // food.init(map); //测试通过
    //
    // var snake = new Snake(20,20,'right');
    // snake.init(map);
    // snake.move(food,map);
    // setInterval(function(){snake.move(food,map)},100);//定时器内的函数必须是匿名函数
</script>


</body>
</html>

猜你喜欢

转载自blog.csdn.net/qq_42039281/article/details/82778846