前端全栈学习第十五天-js高级-第二天-贪吃蛇项目

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        #map {
            width: 400px;
            height: 400px;
            background-color: #ccc;
            position: relative;
        }
    </style>
</head>
<body>
<!--画出地图设置属性-->
<!--1:地图-->
<!--1)地图的基本特征:宽,高,背景颜色-->
<!--2)小蛇和食物要在地图上面随机显示(位置是变化的),所以地图的定位是相对定位(标准流,占位置),食物和小蛇是绝对定位(脱离文档流,不占位置)-->
<!--父级(地图先占一块地方)子级(食物和蛇在地图里面随便折腾),口诀:子绝父相-->
<div id="map"></div>
<script src="../../common.js"></script>
<script>
    //    自调用函数---食物的
    //食物部分
    //1:为什么要用自调用函数(一次性函数):因为比较安全,内部使用一次就作废(除非把他暴露给window对象),而且不会有变量命名冲突的问题
    //2:食物的基本属性:食物也是一个对象,有宽,有高,有横纵坐标,有颜色,--要想创建对象,最好的办法是用构造函数
    //3:食物的方法 :怎样生成食物,食物的样式,食物出现的位置(逃不出map的范围,这里就说明方法里面需要传map形参)---通过原型的方式来实现
    //    4:每次生成的食物都会占用内存,虽然后期食物会被蛇吃掉,但是那只是一种假象。所有的食物还是存在的,这就需要在食物初始化的时候先把食物删除
    //    自调用函数 -------食物对象
    (function () {
        var elements = [];
        //        食物就是一个对象,有坐标,有宽,有高,有颜色,要想创建对象,得有构造函数
        //        食物的基本属性
        function Food(x, y, width, height, color) {
            this.x = x || 0;
            this.y = y || 0;
            this.width = width || 20;
            this.height = height || 20;
            this.color = color || "green";
        }

        //var d = new Food();
        //        console.log(d.color);
        //        食物的方法---怎么生成,具体样式的设置出现的位置,但是逃不出map的范围
        Food.prototype.init = function (map) {
            remove();
            //            创建div
            console.log(map.offsetWidth);
            var div = document.createElement("div");
            //            调加到map中
            map.appendChild(div);
            //            设置div的属性
            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;
            div.style.left = this.x + "px"
            div.style.top = this.y + "px"
            //       把div加到数组elements里面去
            elements.push(div);
        }

        //私有的函数,删除食物的
        function remove() {
            //    elements数组中有食物
            for (var i = 0; i < elements.length; i++) {
                var ele = elements[i];
                ele.parentNode.removeChild(ele); //自杀
                //再次把elements中的这个子元素也删掉
                elements.splice(i, 1);
            }
        }


        //        window.Food = new Food();
        window.Food = Food;
    }());
    //自调用函数---小蛇的
    //    food.init(my$("map")); //注意,在写方法的时候,传入的是形参,所有直接id名就可以,但是实参部分传实参,
    //小蛇部分
    //    1:小蛇也是一个对象,有自己的属性,长宽,方向--要想创建对象---最好的方式是构造函数
    //    1.1:由于小蛇的身体最基本是三个小部分,所以身体用数组的形式存放数据(包括大小,颜色)
    //    2:小蛇出现的方法
    //    小蛇的数据存在body数组里面,所以要通过循环的方式为body一一的添加数据
    //    自调用函数-------小蛇对象
    (function () {
        var elements = [];

        function Snake(width, height, direction) {
            this.width = width || 20;
            this.height = height || 20;
            this.body = [
                {x: 3, y: 3, color: "red"},
                {x: 2, y: 3, color: "orange"},
                {x: 1, y: 3, color: "orange"}
            ]
            this.direction = direction || "bottom";
        }

//        小蛇的方法--初始化方法
        Snake.prototype.init = function (map) {
            removeSnake();
            for (var i = 0; i < this.body.length; i++) {
                var obj = this.body[i];
//                创建div
                var div = document.createElement("div");
//                将div添加到地图里面
                map.appendChild(div);
//                设置蛇的样式
                div.style.width = this.width + "px";
                div.style.height = this.height + "px";
                div.style.backgroundColor = obj.color;
                div.style.position = "absolute";
//                横纵坐标
                div.style.left = obj.x * this.width + "px";
                div.style.top = obj.y * this.height + "px";

//                把蛇放到elements里面
                elements.push(div);
            }
        }
        //        小蛇的方法--动起来
        Snake.prototype.move = function (food, map) {
//改变小蛇身体位置的坐标
            var i = this.body.length - 1;
            for (; i > 0; i--) {
                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;
//            console.log(foodX + "==========" + headX);
//            console.log(foodY + "==========" + headY);
            if (headX == foodX && headY == foodY) {
//获取小蛇最后的尾巴
                var last = this.body[this.body.length - 1];
                //把最后一个的蛇尾复制,加到小蛇的body里面
                this.body.push({
                    x: last.x,
                    y: last.y,
                    color: last.color
                });
                //把食物删除,初始化食物
                food.init(map);
            }
        }
        //            私有函数,删除蛇的
        function removeSnake() {
//                elements中有蛇
            var i = elements.length - 1;
            for (; i >= 0; i--) {
                var ele = elements[i];
                ele.parentNode.removeChild(ele);
                elements.splice(i, 1);
            }
        }

        window.Snake = Snake;
//        window.Snake = new Snake();
    }());
    //    自调用函数,游戏对象
    (function () {
        var that = null;
//        游戏的构造函数
        function Game(map) {

            this.snake = new Snake();
            this.map = map;
            this.food = new Food();
            that = this;
        }

        Game.prototype.init = function () {
//           初始化游戏
//            食物初始化
            this.food.init(this.map);
            //小蛇初始化
            this.snake.init(this.map);
//            调用自动移动
            this.runSnake(this.food, this.map);
            //调用按键的方法
            this.bindKey();
//            this.snake.move(this.food, this.map);
//            this.snake.init(this.map);
//setInterval(function(){
//    that.snake.move(that.food,that.map);
//    that.snake.init(that.map);
//},150)
        }
        //添加原型方法,设置小蛇可以自动跑起来
        Game.prototype.runSnake = function (food, map) {
//自动去动
//            this是实例对象
            var timeId = setInterval(function () {
                //移动小蛇,这的this是window对象
                this.snake.move(food, map);
//                舒适化小蛇
                this.snake.init(map);
//横坐标最最大值
                var maxX = map.offsetWidth / this.snake.width;
                console.log(maxX); //30
//纵坐标最大值
                var maxY = map.offsetHeight / this.snake.height;

                //小蛇头的坐标
                var headX = this.snake.body[0].x;
                var headY = this.snake.body[0].y;
                if (headX < 0 || headX >= maxX) {
                    clearInterval(timeId);
                    alert("游戏结束");
                }
                if (headY < 0 || headY >= maxY) {
                    clearInterval(timeId);
                    alert("游戏结束");
                }

//                e.init(map);
            }.bind(that), 150)  //bind改变了this的指向
        }
//添加原型方法------设置用户按键,改变小蛇移动方向
        Game.prototype.bindKey = function () {
            //获取用户的键值,改变小蛇的方向
            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.Game     =new Game();
    }());

    var gm = new Game(my$("map"))
    gm.init();

    //    外部测试
    //    console.log(Food.color);
    //    食物
    //    Food.init(my$("map"));
    //蛇
    //    Snake.init(my$("map")); //先在地图上看到蛇
    //    setInterval(function(){
    //        Snake.move(Food,my$("map"));
    //        Snake.init(my$("map"));
    //    },150)
    //    Snake.move(Food, my$("map")) //走一步
    //    Snake.init(my$("map"));//走完一步重新画一条蛇,画的时候,先删除之前的蛇
    //    Snake.move(Food, my$("map"))
    //    Snake.init(my$("map"));
    //    Snake.move(Food, my$("map"))
    //    Snake.init(my$("map"));

    //    console.log(Food.x + "==========" + Food.y);
</script>
</body>
</html>

运行效果

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值