为了账号安全,请及时绑定邮箱和手机立即绑定

canvas 之 简易版贪吃蛇

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>snake</title>
        <style type="text/css">
            *{
                margin: 0;
                padding: 0;
            }
            #myCanvas{
                display: block;
                margin: 50px auto;
                background: dodgerblue;
            }
        </style>
    </head>
    <body>
        <canvas id="myCanvas" width="500" height="500"></canvas>
    </body>
    <script type="text/javascript">
        var canvas = document.getElementById('myCanvas');
        var context = canvas.getContext('2d');

        //创建蛇类
        function Snake() {
            //位置以及宽高
            this.x = 0;
            this.y = 0;
            this.w = 50;
            this.h = 50;

            //确定蛇头的颜色
            this.colorHead = 'red';

            //确定蛇身的颜色
            this.colorBody = 'green';

            //设置初始的移动方向
            this.left = false;
            this.right = true;
            this.top = false;
            this.bottom = false;

            //创建数组来记录蛇头的位置信息
            this.positions = [];

            //是否停止删除数组中的位置
            this.isShift = true;

            //绘制蛇头
            this.drawHead = function () {
                context.fillStyle = 'red';
                context.fillRect(this.x,this.y,this.w,this.h);
            }

            //绘制蛇身
            this.drawBody = function () {
                //将蛇头的位置放入数组中
                this.positions.push({x:this.x,y:this.y,w:this.w,h:this.h});

                //没存进去一个点,都要检查数组长度有木有超过预设长度,防止蛇身自动增长
                if (this.positions.length > 4 && this.isShift) {
                    //如果超出预设长度,就从数组头部删除一个值
                    this.positions.shift();
                }else {
                    this.isShift = true;
                }

                //遍历 positions 数组,绘制蛇身
                for (var i = 0;i < this.positions.length;i++) {
                    var x = this.positions[i].x; 
                    var y = this.positions[i].y; 

                    context.beginPath();
                    context.rect(x,y,this.w,this.h);
                    context.strokeStyle = "#ccc";
                    context.stroke();
                    context.fillStyle = this.colorBody;
                    context.fill();
//                  context.fillRect(x,y,this.w,this.h);
                }
            }

            //添加移动方法
            this.move = function () {
                //对当前的移动的方向进行判断
                if (this.left) {
                    this.x -= this.w;
                }else if (this.right) {
                    this.x += this.w;
                }else if (this.top) {
                    this.y -= this.h;
                }else if (this.bottom) {
                    this.y += this.h;
                }
            }
        }

        //创建地图类
        var mapsArr = [
                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                        0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
                        0, 1, 1, 1, 0, 0, 0, 0, 0, 0,
                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                        0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
                        0, 1, 1, 0, 0, 0, 1, 0, 0, 0,
                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                        0, 0, 0, 0, 0, 0, 1, 1, 1, 0,
                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0
                   ];
        function Maps (x,y) {
            this.x = x;
            this.y = y;
            this.w = 50;
            this.h = 50;

            //引入地图图片
            var img = new Image();
            img.src = '../5-/map.jpg';

            //添加绘制方法
            this.draw = function () {
                context.drawImage(img,0,0,this.w,this.h,this.x,this.y,this.w,this.h);
            }
        }

        //创建数组存放地图对象
        var maps = [];

        //遍历地图数组,实例化出地图对象
        //行数 i
        for (var i = 0 ;i < 10;i++) {
            //列数 j
            for (var j = 0;j < 10;j++) {
                if (mapsArr[i * 10 + j] == 1) {
                    //创建出具体的地图对象,将具体的坐标位置传入
                    var mapn = new Maps(j * 50,i * 50);
                    maps.push(mapn);
                }
            }
        }

        //创建食物类
        function Food() {
            this.x = ranNum(0,9) * 50;
            this.y = ranNum(0,9) * 50;
            this.w = 50;
            this.h = 50;
            //食物颜色
            this.color = 'yellow';
            //添加绘制方法
            this.draw = function () {
                //判断食物是否在蛇的身上
                for (var i = 0;i < snake.positions.length;i++) {
                    if (this.x == snake.positions[i].x && this.y == snake.positions[i].y) {
                        //如果位置重叠,重新随机食物的位置
                        this.x = ranNum(0,9) * 50;
                        this.y = ranNum(0,9) * 50;
                        this.draw();

                        //如果出现重合终止循环
                        return;
                    }
                }

                //判断食物是否随即在地图上
                for (var i = 0;i < maps.length;i++) {
                    //判断每一块地图的坐标与食物坐标是否重合
                    if (maps[i].x == this.x && maps[i].y == this.y) {
                        //如果位置重叠,重新随机食物的位置
                        this.x = ranNum(0,9) * 50;
                        this.y = ranNum(0,9) * 50;
                        this.draw();

                        //如果出现重合终止循环
                        return;                     
                    }
                }

                //绘制出食物
                context.fillStyle = this.color;
                context.fillRect(this.x,this.y,this.w,this.h);
            }
        }

        //创建随机函数
        function ranNum (min,max) {
            return Math.floor(Math.random() * (max - min + 1) + min);
        }

        //创建碰撞函数
        function crash (obj1,obj2) {
            var l1 = obj1.x;
            var r1 = obj1.w + l1;
            var t1 = obj1.y;
            var b1 = obj1.h + t1;

            var l2 = obj2.x;
            var r2 = obj2.w + l2;
            var t2 = obj2.y;
            var b2 = obj2.h + t2;

            if (l1 < r2 && r1 > l2 && t1 < b2 && b1 > t2) {
                return true;
            }else {
                return false;
            }
        }
        //创建蛇的对象
        var snake = new Snake();
        snake.drawBody();
        snake.drawHead();

        //创建食物对象
        var food = new Food();

        function animate () {
            snake.move();

            //检测蛇与食物的碰撞
            if (crash(snake,food)) {
                //蛇身边长
                snake.isShift = false;
            }

            //检测蛇与边界的碰撞
            if (snake.x >= canvas.width - snake.w + 1  snake.x < 0  snake.y > canvas.height - snake.h  snake.y < 0) {
                //终止游戏
                alert('你挂了')
                clearInterval(time);

            }

            //检测蛇与地图的碰撞
            for (var i = 0;i < maps.length;i++) {
                if (crash(maps[i],snake)) {
                    alert('你挂了')
                    clearInterval(time);
                }
            }

            //检测蛇与蛇身的碰撞
            for (var i = 0;i < snake.positions.length;i++) {
                if (crash(snake,snake.positions[i])) {
                    alert('你挂了')
                    clearInterval(time);
                }
            }

            //清除画布
            context.clearRect(0,0,canvas.width,canvas.height);

            //先绘制蛇身
            snake.drawBody();
            snake.drawHead();
            food.draw();

            //绘制地图
            for (var i = 0;i < maps.length;i++) {
                maps[i].draw();
            }

        }

        //设置计时器重复执行
        var time = setInterval (animate,300)

        //添加键盘事件,控制蛇的移动方向
        document.onkeydown = function (e) {
            var e = e  window.event;
            switch (e.keyCode) {
                case 37 :
                    if(!snake.right) {
                        snake.left = true;
                        snake.top = false;
                        snake.bottom = false;
                    };
                    break;
                case 38 :
                    if(!snake.bottom) {
                        snake.top = true;
                        snake.right = false;
                        snake.left = false;
                    };
                    break;
                case 39 :
                    if(!snake.left) {
                        snake.right = true;
                        snake.top = false;
                        snake.bottom = false;
                    };
                    break;
                case 40 :
                    if(!snake.top) {
                        snake.bottom = true;
                        snake.left = false;
                        snake.right = false;
                    };
                    break;
                default :
                    break;
            }
        }

    </script>
</html>
点击查看更多内容
12人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消