原生js的贪吃蛇案例(附带源代码)

1,搭建页面模块

 蛇和食物都是存在于map中,所以要相对于map对象来定位 子绝父相;
#map {
    width: 800px;
    height: 600px;
    background: rgb(155, 150, 110);
    position: relative;
    margin: 20px 20px;
}
<div id="map">
    </div>

食物对象

1,先定义食物的属性和方法
       属性
          坐标(x y)
          颜色
          宽
          高
       方法 
          render
          随机在map中显示食物
       函数
       			删除食物的函数   
(function() {
    //全局变量
    var position = "absolute";
    var elements = [];

    //食物的属性
    function Food(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";
    }
    let map = document.getElementById("map");
    console.log(map.offsetWidth)
    console.log(map.offsetHeight)
        //食物的原型方法
    Food.prototype.render = function(map) {
            //调用删除方法remove()
            remove();
            //生成随机的食物=>生成随机的食物对象的x,y  tools方法不能用
            // this.x = Math.floor(Math.random() * ((map.offsetWidth / this.width - 1) * this.width)); 
            // this.y = Math.floor(Math.random() * ((map.offsetHeight / this.height - 1) * this.height));
            //console.log(map.offsetWidth);
            //console.log(map.offsetHeight);

            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);
            let div = document.createElement('div');
            map.appendChild(div);
            //将食物发到数组中来
            elements.push(div);
            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.backgroundColor = this.color;
            //将div食物放到map中

        }
        //删除食物
    function remove() {
        for (var i = elements.length - 1; i >= 0; i--) {
            //删除食物
            elements[i].parentNode.removeChild(elements[i]);
            //删除数组中的食物
            //splice方法传两个参数 第一个从什么位置删除 第二个删除几个
            elements.splice(i, 1);
        }
    }
    window.Food = Food

})()

创建蛇对象

  snake  
    属性  
     width
     height
     body 数组 
           蛇头     蛇身               
     direction 运动方向
 方法
     render  
  函数   remove删除蛇    move移动
//开启新的局部作用域
(function() {
    var position = "absolute";
    //数组记录创建的蛇
    var elements = [];

    function Snake(options) {
        options = options || {};
        //蛇节的宽高
        this.width = options.width || 20;
        this.height = options.height || 20;
        //控制蛇的方向
        this.direction = options.direction || 'right';
        //蛇的身体  蛇节加蛇头
        this.body = [{
                x: 3,
                y: 2,
                color: 'red'
            },
            {
                x: 2,
                y: 2,
                color: 'blue'
            },
            {
                x: 1,
                y: 2,
                color: 'blue'
            }
        ]
    }
    //蛇的原型方法
    Snake.prototype.render = function(map) {
            //调用删除以前的蛇
            remove();
            //把每一个蛇节加蛇头渲染到map
            //i = 0, len = this.body.length 只加载一次 提高效率
            for (var i = 0, len = this.body.length; i < len; 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.backgroundColor = object.color;
            }
        }
        //删除以前产生的蛇对象
        //用到着的循环
    function remove() {
        for (var i = elements.length - 1; i >= 0; i--) {
            elements[i].parentNode.removeChild(elements[i]);
            elements.splice(i, 1);
        }
    }
    //控制蛇移动的方法   参数food
    Snake.prototype.move = function(food, map) {
        //控制蛇的身体移动(当前蛇节 到 上一个蛇节的位置)
        for (var 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;
        }
        //控制蛇头的移动
        //控制蛇头的移动的方向
        var head = this.body[0];
        //做等值判断的时候,可以用switch 也可以用if
        switch (this.direction) {
            case 'right':
                head.x += 1;
                break;
            case 'left':
                head.x -= 1;
                break;
            case 'top':
                head.y -= 1;
                break;
            case 'bottom':
                head.y += 1;
                break;
        }
        //判断蛇头是否和食物的坐标重合
        var headx = head.x * this.width;
        var 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.render(map);
        }
    }
    window.Snake = Snake;
})()

创建游戏对象

属性
      蛇对象
      食物对象
      map
  方法
      start方法开始游戏
      函数
          bindKey()   键盘获取
          runSnake()蛇的移动
(function() {
    //定义Game对象允许该作用域中可以访问
    var that;

    function Game(map) {
        //游戏属性
        this.food = new Food();
        this.snake = new Snake();
        this.map = map;
        //允许在该作用域中访问Game
        that = this;
    }
    //定义开始游戏的原型方法
    Game.prototype.start = function() {
            //将食物和蛇渲染到map中去
            this.food.render(this.map);
            this.snake.render(this.map);

            //调用蛇运动方法
            runSnake();
            bindKey()
                //测试调用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);
        }
        //通过键盘来控制蛇的移动方向
    function bindKey() {
        //document.onkeydown = function(e) 
        document.addEventListener('keydown', (e) => {
            //获取键盘码
            // console.log(e.keyCode);
            //37==left 38==top 39==right 40==bottom
            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);
    }
    //定义蛇运动的方法 定时器
    function runSnake() {
        var timerId = setInterval(function() {
            //在定时器中的this是指向window对象的
            //获取游戏对象的蛇属性
            this.snake.move(this.food, this.map);
            this.snake.render(this.map);

            //遇到边界停下来
            let headX = this.snake.body[0].x;
            let headY = this.snake.body[0].y;
            let maxX = this.map.offsetWidth / this.snake.width;
            let maxY = this.map.offsetHeight / this.snake.height;
            //判断
            if (headX < 0 || headX >= maxX) {
                alert('Game Over')
                clearInterval(timerId);
            }
            if (headY < 0 || headY >= maxY) {
                alert('Game Over')
                clearInterval(timerId);
            }
        }.bind(that), 150)
    }
    window.Game = Game;
})()

调用主方法

(function() {
    var map = document.getElementById("map");
    var game = new Game(map);
    game.start();
})()

加载js文件的先后顺序,如果a依赖于b,b就先加载,

<script src="js/tool.js"></script>
<script src="js/food.js"></script>
<script src="js/snake.js"></script>
<script src="js/game.js"></script>
<script src="js/main.js"></script>
 自调用函数
 (function(){

})()
 自调用函数中传入window和undefined
 window的目的是让变量名能压缩
undefined 在老版本中的浏览器中,undefined 是可以被重新赋值
全局作用域下的代码。在其他js中是可以访问的
所以用自调用
开启一个新的作用域,避免命名冲突,进行代码优化

附带源代码

https://download.csdn.net/download/qq_45335128/12000267

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值