面向对象写贪吃蛇

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>贪吃蛇</title>
    <link rel="stylesheet" href="../css/style.css">
</head>
<body>
<div id="map"></div>

<script src="../js/tool.js"></script>
<script src="../js/food.js"></script>
<script src="../js/snake.js"></script>
<script src="../js/game.js"></script>
</body>
</html>
//随机数生成
let Tools = {
    getRandom: function (min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min
    },
};

//***************************面向对象编程 赞👍*********************************\\
//解决命名冲突 -自调用函数(开启一个新的作用域)
(function () {//局部作用域
    let position = 'absolute';
//存储food,方便删除
    let elements = [];

    function Food(options) {
        //options是一个对象如果没传参就是{}
        options = options || {};//如果没有传参则指向||后面的值
        //options = 传入的对象 或者 {}
        this.x = options.x || 0;
        this.y = options.y || 0;

        this.width = options.width || 20;
        this.height = options.height || 20;

        this.color = options.color || 'green';
    }

//渲染
    Food.prototype.render = function (map) {
        //删除之前创建的food
        remove();

        //随机设置x和y的值
        this.x = Tools.getRandom(0, (map.offsetWidth / this.width - 1) * this.width);
        this.y = Tools.getRandom(0, (map.offsetHeight / this.height - 1) * this.height);
        console.log(this.x);
        console.log(this.y);
        //动态创建div,页面上显示的食物
        let div = document.createElement('div');
        map.appendChild(div);
        //将创建的div放到数组中
        elements.push(div);

        //设置div样式
        // div.className = 'food';//也可以直接添加一个定义好的样式,但变化没有下面变量存储灵活
        div.style.position = position;//可以根据需求改动变量
        div.style.left = this.x + 'px';
        div.style.top = this.y + 'px';
        div.style.width = this.width + 'px';
        div.style.height = this.height + 'px';
        div.style.background = this.color;
        console.log('👍');
    };

    function remove() {
        for (let i = elements.length - 1; i >= 0; i--) {
            //删除div
            elements[i].parentNode.removeChild(elements[i]);
            //清空数组
            //splice()两个参数 1,从哪删 2,删几个
            elements.splice(i, 1);
        }
    }
    //因为这里是局部作用域,所以外部无法访问这里定义的变量,
    // 要把Food构造函数,让外部可以访问 ,将它添加到window中
    window.Food = Food;
})();

// let option = {
//     x:random(0,750)+'px',
//     y:random(0,550)+'px',
//     width:50,
//     height:50,
//     color:'pink'
// };
//测试test
//let map = document.querySelector('#map');
//let food = new Food();//不添加参数就是 || 后面设置的值
//food.render(map);//调用Food的render方法(实际是Food类的一个属性prototype)给div设置样式和添加div美其名曰:渲染
(function () {
    let position = 'absolute';
    let elements = [];//每一个蛇

    function Snake(options) {
        options = options || {};
        //蛇节的大小
        this.width = options.width || 20;
        this.height = options.height || 20;
        //蛇节的移动方向
        this.direction = options.direction || 'right';
        //蛇的身体(蛇节)的第一个元素是蛇头
        this.body = [
            {x: 2, y: 2, color: 'red'},
            {x: 1, y: 2, color: 'blue'},
            {x: 0, y: 2, color: 'blue'}
        ];
    }

    Snake.prototype.render = function (map) {
        //删除以前创建的蛇
        remove();
        //把每一个蛇节渲染到map上
        for (let i = 0; i < this.body.length; i++) {
            //蛇节
            let object = this.body[i];

            let div = document.createElement('div');
            map.appendChild(div);

            //记录当前创建的蛇
            elements.push(div);
            //设置样式
            div.style.position = position;
            div.style.width = this.width + 'px';
            div.style.height = this.height + 'px';
            div.style.left = object.x * this.width + 'px';
            div.style.top = object.y * this.height + 'px';
            div.style.background = object.color;
        }
    };

    function remove () {
        for (let i = elements.length - 1;i>=0;i--){
            //删除div
            elements[i].parentNode.removeChild(elements[i]);
            //删除数组中的元素
            elements.splice(i,1);
        }
    }

    //蛇移动方法
    Snake.prototype.move = function (food,map) {
        //1,蛇的身体移动(当前蛇节到上一个蛇节的位置)
        for (let i = this.body.length-1; i > 0; i--) {
            this.body[i].x = this.body[i - 1].x;
            this.body[i].y = this.body[i - 1].y;
        }
        //2,控制蛇移动的方向
        //   控制蛇头的移动
        let head = this.body[0];
        switch (this.direction) {
            case 'right':
                head.x += 1;
                break;
            case 'top':
                head.y -= 1;
                break;
            case 'left':
                head.x -= 1;
                break;
            case "bottom":
                head.y += 1;
                break;
            default:
                console.log("default");
        }
        //遇到food
        let headX = head.x * this.width;
        let headY = head.y * this.height;

        if (headX === food.x && headY === food.y){
            //蛇身长一节
            let last = this.body[this.body.length - 1];
            this.body.push({
               x:last.x,
               y:last.y,
               color:last.color
            });
            //随机生成food
            food.render(map);
        }
    };
    //把Snake暴露出去
    window.Snake = Snake;
})();
//test
//let snake = new window.Snake();
//snake.render(map);
(function () {
    var that;
    function Game(map) {
        that = this;
        this.food = new Food();
        this.snake = new Snake();
        this.map = map;
    }

    Game.prototype.start = function () {
        // 1,把food和snake渲染到map上
        this.food.render(this.map);
        this.snake.render(this.map);
        //测试 Snake.move方法
        // this.snake.move();
        // this.snake.render(this.map);
        // this.snake.move();
        // this.snake.render(this.map);
        // this.snake.move();
        // this.snake.render(this.map);
        //2,开始游戏的逻辑
        // 2.1,让蛇动起来
        function runSnake() {
            let timerId = setInterval(function () {
             that.snake.move(that.food,that.map);
             that.snake.render(that.map);

            //2.2 遇到边界
            //获取蛇头的坐标
            let maxX = that.map.offsetWidth / that.snake.width;
            let maxY = that.map.offsetHeight / that.snake.height;
            let headX = that.snake.body[0].x;
            let headY = that.snake.body[0].y;
            if (headX < 0 || headX >= maxX){
                alert('Game over!');
                clearInterval(timerId);
            }
            if (headY <0 ||headY >= maxY){
                alert('Game over!');
                clearInterval(timerId);
            }
            },150);
        }
        runSnake();
        //2.2,键盘控制移动方向
        function bindKey() {
            // document.onkeydown = function () {};//鼠标事件的两种添加方式
            /*
            * 37 left
            * 38 top
            * 39 right
            * 40 bottom
            * */
            document.addEventListener('keydown',function (e) {
                switch (e.keyCode) {
                    case 37:
                        that.snake.direction = 'left';
                        break;
                    case 38:
                        that.snake.direction = 'top';
                        break;
                    case 39:
                        that.snake.direction = 'right';
                        break;
                    case 40:
                        that.snake.direction = 'bottom';
                        break;
                }
            },false);
        }
        bindKey();
        //2.3,遇到food

    };
    //暴露构造函数给外部
    window.Game = Game;
})();

//test
let map = document.querySelector('#map');
let game = new Game(map);
game.start();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值