js实现贪吃蛇

运行截图:

源码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>贪吃蛇小游戏</title>

    <style>
        body {
            margin:0px;
            padding:0px;

        }

        #main {
           margin:100px;
        }

        .btn {
            width:100px;
            height:40px;
        }

        .gtitle {
            font-size:25px;
            font-weight: bold;

        }

        #gnum {
            color:red;
        }
    </style>
</head>

<body>

<div id="main">
    <h1>贪吃蛇</h1>
    <input class="btn" type="button" value="开始游戏" id="begin" />
    <input class="btn" type="button" value="暂停游戏" id="pause" />
    <span class="gtitle">第 <span id="gnum">1</span> 关</span>

    <script>
        var main = document.getElementById('main');
        var showcanvas = true;  //是否开启画布格子
        /**
         * 地图对象的构造方法
         * @param atom 原子大小宽和高是一样的 10
         * @param xnum 横向原子的数量
         * @param ynum 纵向原子的数量
         * @constructor
         */
        function Map(atom, xnum, ynum){
            this.atom = atom;  // 20x20
            this.xnum = xnum;  //
            this.ynum = ynum;

            this.canvas = null;

            //创建画布的方法
            this.create  = function(){
                this.canvas = document.createElement('div');
                this.canvas.style.cssText="position:relative;top:40px;border:1px solid darkred; background:#FAFAFA";
                this.canvas.style.width = this.atom * this.xnum + 'px'; //画布的宽
                this.canvas.style.height = this.atom * this.ynum + 'px'; //画布的高
                main.appendChild(this.canvas);

                if(showcanvas) {
                    for(var y=0; y<ynum; y++) {
                        for (var x = 0; x < xnum; x++) {
                            var a = document.createElement('div');
                            a.style.cssText = "border:1px solid yellow";
                            a.style.width = this.atom + 'px';
                            a.style.height = this.atom + 'px';
                            a.style.backgroundColor = "LightSkyBlue";
                            this.canvas.appendChild(a);
                            a.style.position = 'absolute';
                            a.style.left = x * this.atom + 'px';
                            a.style.top = y*this.atom+'px';
                        }
                    }
                }

            }

        }

        /**
         * 创建食物的构造方法
         * @param map  地图对象
         * @constructor
         */
        function Food(map){
            this.width = map.atom;
            this.height = map.atom;
            this.bgcolor= "rgb("+Math.floor(Math.random()*200)+", "+Math.floor(Math.random()*200)+", " + Math.floor(Math.random() * 200) +")";
            this.x = Math.floor(Math.random()*map.xnum);
            this.y = Math.floor(Math.random()*map.ynum);
            this.flag = document.createElement('div');
            this.flag.style.width = this.width + 'px';
            this.flag.style.height = this.height + 'px';
            this.flag.style.backgroundColor = this.bgcolor;
           // this.flag.style.borderRadius = '50%';
            this.flag.style.position = 'absolute';
            this.flag.style.left = this.x * this.width +'px';
            this.flag.style.top = this.y * this.height + 'px';

            map.canvas.appendChild(this.flag);
        }
        function Snake(map) {
            //设置宽,高
            this.width=map.atom;
            this.height = map.atom;
            //默认走的方向
            this.direction = 'right';

            this.body = [
                {x:2, y:0},  //蛇头, 第一点  0
                {x:1, y:0},  //蛇脖子, 第二点 1
                {x:0, y:0}  //蛇尾, 第三点   2
                //{x:null, y:null, flag:null} 3
            ];
            //显示蛇
            this.display = function(){
                for(var i=0; i<this.body.length; i++){
                    if(this.body[i].x !=null) { //当吃到食物时, x==null, 不能新建, 不然会在0,0处理新建一个
                        var s = document.createElement('div');
                        // 将节点保存到一个状态变量中, 以便以后删除使用
                        this.body[i].flag = s;

                        //设置蛇的样式
                        s.style.width = this.width + 'px';
                        s.style.height = this.height + 'px';
                        s.style.backgroundColor="rgb("+Math.floor(Math.random()*200)+", "+Math.floor(Math.random()*200)+", " + Math.floor(Math.random() * 200) +")";
                        //s.style.borderRadius = '50%';
                        //设置位置
                        s.style.position = 'absolute';
                        s.style.left = this.body[i].x * this.width + 'px';
                        s.style.top = this.body[i].y * this.height + 'px';
                        //添加到地图中
                        map.canvas.appendChild(s);
                    }

                }
            }
            //让蛇运动起来
            this.run = function() {

                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;
                }
                //默认是right  left  up down
                // 根据方向处理蛇头
                switch(this.direction) {
                      case "left": this.body[0].x -=1; break;
                      case "right": this.body[0].x +=1;break;
                      case "up": this.body[0].y -=1; break;
                      case "down": this.body[0].y +=1; break;
                }

                //判断蛇头吃到食物, xy和食物的XY重合
                if(this.body[0].x ==food.x && this.body[0].y == food.y ){
                    //蛇加一节, 根据最后节点定
                    this.body.push({x:null, y:null, flag:null});

                    //判读一下设置级别
                    if(this.body.length > l.slength) {
                        l.set();
                    }

                    map.canvas.removeChild(food.flag);
                    food = new Food(map);

                }
                //判断是否出界, 蛇头
                if(this.body[0].x <0 || this.body[0].x > map.xnum-1 || this.body[0].y <0 || this.body[0].y > map.ynum -1) {
                    clearInterval(timer); //清除定时器

                    alert("怎么这么不小心撞墙了呢,摸摸头");

                    //重新开始游戏
                    restart(map, this)

                    return false;
                }

                //判读是否和自己重合
                for(var i=4; i<this.body.length; i++){
                    if(this.body[0].x == this.body[i].x && this.body[0].y == this.body[i].y) {
                        clearInterval(timer); //清除定时器

                        alert("呀,怎么喜欢咬自己的肉肉");

                        //重新开始游戏
                        restart(map, this)

                        return false;
                    }

                }                

                for(var i=0; i<this.body.length; i++){
                    if(this.body[i].flag != null) {  //当吃到食物, flag是等null, 且不能删除
                        map.canvas.removeChild(this.body[i].flag)
                    }
                }

                this.display();
            }

        }
        //重新开始游戏
        function restart(map, snake) {
            for(var i=0; i<snake.body.length; i++) {
                map.canvas.removeChild(snake.body[i].flag);
            }

            snake.body = [
                {x:2, y:0},  //蛇头, 第一点  0
                {x:1, y:0},  //蛇脖子, 第二点 1
                {x:0, y:0}  //蛇尾, 第三点   2

            ];
            snake.direction = 'right';
            snake.display();
            map.canvas.removeChild(food.flag);
            food = new Food(map);

        }
        //设置级别对象
        function Level() {
            this.num = 1; //第几级别
            this.speed= 300; //毫秒, 每升一关, 数量减少20, 速度就加快了
            this.slength = 8; //每个关的长度判断

            this.set = function() {
                this.num++;
                if(this.speed <= 50) {
                    this.speed = 50;
                }else{
                    this.speed -=50;
                }
                this.slength += 10;  //这个可以自己定义
                this.display();
                start();  //重新开始, 速度加快
            }

            this.display = function() {
                document.getElementById('gnum').innerHTML = this.num;
            }
        }
        var l = new Level();
        l.display();

        //创建地图对象
        var map = new Map(20, 40, 20);
        map.create(); //显示画布

        //构造食物对象
        var food = new Food(map);

        //构造蛇对象
        var snake = new Snake(map);
        snake.display();

        // 组body加键盘事件, 上下左右
        window.onkeydown = function(e){
            var event = e || window.event;

           // console.log(event.keyCode);

           switch(event.keyCode) {
                case 38:
                    if(snake.direction != "down") {
                        snake.direction = "up";
                    }
                    break;
               case 40:
                   if(snake.direction != "up") {
                       snake.direction = "down";
                   }
                   break;
               case 37:
                   if(snake.direction != "right") {
                       snake.direction = "left";
                   }
                   break;
               case 39:
                   if(snake.direction != "left") {
                       snake.direction = "right";
                   }
                   break;
           }
        }

        var timer; //变量可以提升

        function start() {
            clearInterval(timer);
            timer = setInterval(function(){
                snake.run();
            },l.speed);
        }

        document.getElementById('begin').onclick=function(){
            start();
        }

        document.getElementById('pause').onclick=function() {
            clearInterval(timer);
        }
    </script>
</div>

</body>
</html>

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值