js高级面向对象之贪吃蛇

时间:2019-01-23
本文章向大家介绍js高级面向对象之贪吃蛇,主要包括js高级面向对象之贪吃蛇使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

html 部分
给一张地图 蛇活动的范围就在这个地图之内

<body>
<div id="map"></div>
</body>

css部分

地图的样式

 <style>
        #map {
            width: 800px;
            height: 600px;
            background-color: grey;;
            position: relative;
        }
    </style>

js部分
我们可以先分析下有哪几个对象

  1. 食物
  2. 游戏

一.食物的对象

 ((function () {
        //保存每一个小方块,好删除小方块
        var elements = [];

        //食物的构造函数
        function Food(width, height, color, x, y) {
            this.width = width || 20;//食物的宽度  用户没有传入参数的话,默认20px
            this.height = height || 20;//食物的高度 用户没有传入参数的话,默认20px
            this.color = color || "yellow";//食物的颜色 用户没有传入参数的话,默认yellow
            //随机的横纵坐标
            this.x = x || 0;//食物的横坐标  用户没有传入参数的话,默认为0
            this.y = y || 0;//食物的纵坐标  用户没有传入参数的话,默认为0
        }

        //在原型对象上添加方法---把食物显示在地图上
        Food.prototype.init = function (map) {
            //先删除在创建
            remove();
            //1.创建一个小盒子 -- 食物
            var div = document.createElement("div");
            //2.把div添加到map中去
            map.appendChild(div);
            //3.给小盒子设置样式
            div.style.width = this.width + "px";
            div.style.height = this.height + "px";
            div.style.backgroundColor = this.color;
            div.style.position = "absolute";
            //随机数的坐标  不能超出地图的范围
            this.x = parseInt(Math.random() * (map.offsetWidth / this.width)) * this.width;//食物的随机横坐标  
            this.y = parseInt(Math.random() * (map.offsetHeight / this.height)) * this.height;//食物的随机纵坐标
            // console.log(this.x);
            // console.log(this.y);
            //设置食物随机出现的位置
            div.style.left = this.x + "px";
            div.style.top = this.y + "px";
            //把div添加到数组中去
            elements.push(div);
        }

        //封装删除食物的函数
        function remove() {
            for (var i = 0; i < elements.length; i++) {
                //获取每一个小方块
                var ele = elements[i]
                //删除map中的小方块
                ele.parentElement.removeChild(ele);
                //删除数组中的小方块
                elements.splice(i, 1)
            }
        }

        //把Food暴露给window
        window.Food = Food;
    })());

二.小蛇的对象

 ((function () {
        //用来存放小蛇的数组
        var elements = [];
        //1.小蛇的构造函数
        function Snake(width, height, direnction) {
            //小蛇每个部位的宽度
            this.width = width || 20;
            this.height = width || 20;
            //小蛇的方向
            this.direction = direnction || "right";
            //小蛇每个部位在那个坐标点-----小蛇吃食物会变长
            this.body = [
                {x: 3, y: 1, color: "white"},//小蛇的头部
                {x: 2, y: 1, color: "black"},//身体
                {x: 1, y: 1, color: "black"}
            ]
        }

        //2.在原型中添加发方法---小蛇初始化---需要地图参数
        Snake.prototype.init = function (map) {
        	//先删除小蛇
            remove();
            //遍历的创建div---小蛇的每个部位
            for (var i = 0; i < this.body.length; i++) {
                //1.创建div
                var div = document.createElement("div");
                //2.添加到地图中
                map.appendChild(div);
                var obj = this.body[i];//储存的是数组的每一个元素,也是对象
                //3.设置div的样式
                div.style.width = this.width + "px";
                div.style.height = this.height + "px";
                div.style.backgroundColor = this.body[i].color;
                div.style.position = "absolute";
                //横纵坐标
                div.style.left = obj.x * this.width + "px";
                div.style.top = obj.y * this.height + "px";              
                //把小蛇添加到数组
                elements.push(div);
            }
        }
        //暴露给window
        window.Snack = Snake;

        //3.添加一个让小蛇 移动的方法
        Snake.prototype.move = function (map, food) {
            //改变小蛇的身体坐标----》要循环小蛇的身体部位,头部要判断方向
            for (var i = this.body.length - 1; i > 0; i--) {
                //当i=2的时候,此时是第三块的坐标,把第2块的坐标给第3块的坐标
                this.body[i].x = this.body[i - 1].x;
                this.body[i].y = this.body[i - 1].y;
            }
            //判断小蛇头部坐标的位置
            switch (this.direction) {
                case "right":
                    this.body[0].x += 1;
                    break;
                case "left":
                    this.body[0].x -= 1;
                    break;
                case "top":
                    this.body[0].y -= 1;
                    break;
                case "bottom":
                    this.body[0].y += 1;
                    break;
            }

            //最后:要判断小蛇是否吃到食物,----即判断蛇头的坐标
            //获取蛇头的坐标
            var headX = this.body[0].x * this.width;
            var headY = this.body[0].y * this.height;
            //食物的坐标
            var foodX = food.x;
            var foodY = food.y;

            if (headX == foodX && headY == foodY) {
                //1.重新初始化食物
                food.init(map);
                //2.获取小蛇最后的尾巴
                var last = this.body[this.body.length - 1];
                //3.添加到数组中
                this.body.push({
                    x: last.x,
                    y: last.y,
                    color: last.color
                })
            }
        };

        //4.删除小蛇的函数
        function remove() {
            for (var i = elements.length - 1; i >= 0; i--) {
                //存放每一个小蛇
                var ele = elements[i];
                //删除地图上面的
                ele.parentNode.removeChild(ele);
                //删除数组中的
                elements.splice(i, 1);
            }
        }
    })());

三.游戏的对象–显示小蛇,显示食物,并自动的跑起来

 ((function () {
        //1.游戏的构造函数
        function Game() {
            this.food = new Food();//食物的对象
            this.snake = new Snack();//小蛇的对象
            this.map = document.getElementById("map");//地图对象
        };
        //2.初始化游戏对象---
        Game.prototype.init = function () {
            //显示食物和小蛇
            this.food.init(this.map);
            this.snake.init(this.map);
            //调用自动移动的小蛇
            this.runSnake(this.map, this.food);
            //调用方向的方法
            this.keyDown(this.map);
        };
        //3.添加原型的方法---是小蛇自动跑起来
        Game.prototype.runSnake = function (map, food) {
            //函数嵌套,this指向发生变化
            var that = this;
            //自动的移动
            var timeId = setInterval(function () {
                // console.log(this);//指向的window
                this.snake.move(map, food)//移动
                this.snake.init(map);//显示

                //判断横纵坐标最大值
                var maxX = map.offsetWidth / this.snake.width;
                // console.log(maxX);
                var maxY = map.offsetHeight / this.snake.height;

                //获取蛇头坐标
                var headX = this.snake.body[0].x;
                // console.log(headX);
                var headY = this.snake.body[0].y;
                //判断横纵坐标是否撞墙
                if (headX < 0 || headX >= maxX || headY < 0 || headY >= maxY) {
                    clearInterval(timeId);
                    alert("game over!");
                }
                ;


                //把这个函数的指向绑定在that的指向上面
            }.bind(that), 200);
        };

        //4.添加原型方法--设置用户的按键,改变小蛇的移动方向
        Game.prototype.keyDown = function () {
            document.addEventListener("keydown", function (e) {
                console.log(e.keyCode);//按键的值
                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(this));
        }

        //暴露给window
        window.Game = Game;
    })());

最后调用游戏的方法就可以了

 var game = new Game();
    game.init();