贪吃蛇游戏

HTML代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .map{
            width: 800px;
            height: 600px;
            background-color: #ccc;
            position: relative;
        }
    </style>
</head>
<body>
<div class="map"></div>
<script src="food.js"></script>
<script src="Snake.js"></script>
<script src="Game.js"></script>
<script>
    
    var gm = new Game(document.querySelector(".map"));
    gm.init();

    // var fd = new Food();
    // fd.init(document.querySelector(".map"));       /*初始化食物函数*/
    // var sn = new Snake();
    // sn.init(document.querySelector(".map"));
    // sn.move(fd,document.querySelector(".map"));
    // sn.init(document.querySelector(".map"));
    // setInterval(function(){
    //     sn.move(fd,document.querySelector(".map"));
    //     sn.init(document.querySelector(".map"));
    // },150);

</script>
</body>
</html>

food.js代码

//自调用函数----食物对象创建
(function () {
    var element = [];
    //食物就是一个对象,先定义构造函数吗,再创建对象
    function Food(x,y,width,height,color) {
        this.width=width || 20;      /*默认的宽*/
        this.height=height || 20;
        this.color=color || "green";
        //坐标
        this.x=x || 0;
        this.y=y || 0;
    }
    //初始化,在map上显示,传入map参数
    Food.prototype.init = function(map){
        remove();      /*初始化时会删除上一个创建的对象,这个是内部调用,外部不能访问*/

        var div = document.createElement("div");   /*小方块元素,创建div*/
        map.appendChild(div);           /*加入map中*/
        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";

        element.push(div);     /*将div添加push到自定义的数组中*/
    };
    //删除食物,通过创建对象时就把对象放在数组中,删除时就可以在数组中找到这个对象
    function remove(){
        for(var i=0;i<element.length;i++){
            var ele = element[i];               /*要删除对象先要找到这个对象*/
            ele.parentNode.removeChild(ele);    /*找到他的父级元素,通过父级元素来删除子级元素*/
            element.splice(i,1)                 /*再将数组中存储的删除*/
        }
    }

    window.Food = Food;
}());

Snake.js代码

//自调用函数----蛇对象创建
(function(){
    var elements = [];
    function Snake(width,height,direction){
        this.width = width || 20;
        this.height = height || 20;
        this.direction = direction || "right";
        this.body = [      /*蛇身体是由一个个小方块组成*/
            {x:3,y:2,color:"red"},
            {x:2,y:2,color:"orange"},
            {x:1,y:2,color:"orange"}
        ]
    }
    Snake.prototype.init = function(map){
        //循环创建div,蛇移动就是新建一个蛇,再将原先的蛇删除
        remove();
        for(var i=0;i<this.body.length;i++){
            var obj = this.body[i];       /*数组中每个元素就是一个对象*/
            var div = document.createElement("div");
            map.appendChild(div);
            div.style.position = "absolute";
            div.style.width = this.width+"px";
            div.style.height = this.height+"px";
            div.style.left = obj.x*this.width+"px";
            div.style.top = obj.y*this.height+"px";
            div.style.backgroundColor = obj.color;
            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;

        if(headX==foodX && headY==foodY){
            //吃了食物实际就是复制自身的一个div加到尾部
            var last = this.body[this.body.length-1];
            this.body.push({                /*以对象的方式添加*/
                x:last.x,y:last.y,color:last.color
            });
            //再将新的食物产生到map中
            food.init(map);
        }
    };
    function remove(){
        var i = elements.length - 1;
        for(;i>=0;i--){
            var ele = elements[i];
            ele.parentNode.removeChild(ele);
            elements.splice(i,1);
        }
    }

    window.Snake = Snake;
}());

Game.js代码

//自调用游戏对象
(function(){
    var that = null;       /**/
    function Game(map){
        this.food = new Food();
        this.snake = new Snake();
        this.map = map;
        that = this;             /*保存创建的实例对象的代指this*/
    }
    Game.prototype.init = function(){
        this.food.init(this.map);         /*初始化食物函数*/
        this.snake.init(this.map);        /*初始化蛇函数*/

        // setInterval(function(){           /*setInterval 默认是window调用,所以this代指window,改变了实例的this*/
        //     that.snake.move(that.food,that.map);     /*而这里需要实例来调用方法,所以用前面保存的this*/
        //     that.snake.init(that.map);
        // },150);
        // this.snake.move(this.map);
        // this.snake.init(this.map);
        this.runSnake(this.food,this.map);
        this.bindKey();
    };
    //添加原型方法 --- 设置小蛇可以自动的动起来
    Game.prototype.runSnake = function(food,map){
        var timeId = setInterval(function(){
            //此时this就是window
            this.snake.move(food,map);
            this.snake.init(map);

            //判断是否移动到边界
            var maxX = map.offsetWidth/this.snake.width;
            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("game over");
            }
            if(headY<0 || headY>=maxY){       /*判断头是否碰到边界*/
                clearInterval(timeId);
                alert("game over");
            }
            for (var i=this.snake.body.length-1;i>0;i--){      /*判断是否头是否碰到身体*/
                if(headX==this.snake.body[i].x && headY==this.snake.body[i].y){
                    clearInterval(timeId);
                    alert("game over");
                }
            }

        }.bind(that),100);       /*函数调用bind方法,则函数就变成bind里的参数对象的一个方法*/
        /*这里参数是that,则window.setInterval()就变成了that.setInterval(),改变了对象*/

        //设置按键改变蛇方向
        Game.prototype.bindKey = function () {
            document.addEventListener("keydown",function(e){
                //这里的this是代指document,
                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;
}());

 

posted @ 2019-08-14 20:51  saber゛  Views(285)  Comments(0Edit  收藏  举报