利用Canvas+js实现贪吃蛇(3)

想了想,蛇向下走的时候按上键,如果直接将蛇头变蛇身,好像不符合常理,所以处理这种情况,应当做蛇头碰到蛇身。。

另外,实现蛇头碰蛇身的功能

界面就不美化了。。。

下一步就是封装成面向对象的插件了。。。

附上js代码

window.onload = function() {
        var canvas = document.getElementById('myCanvas'),
            span_score = document.getElementById('score'),
            context = canvas.getContext('2d'),
            maxNumber = 630,   // 最大长宽,这里的画布是正方形
            stride = 15,  //每个小方块的长宽,
            snakeLength = 1,  //蛇身长度
            snake = new Array(),  //蛇身数组
            speed = 300,   // 移动速度
            direct = 37,   //移动方向
            food_x = 31,   //食物的坐标   可以改为object对象
            food_y = 121,
            score = 0,   // 得分
            timer;       //setInterval

        init();
        update();

        document.οnkeydοwn=function(event) {
            clearInterval(timer);
            // 37:左 38:上 39:右  40:下
            //  改为以下 内容 ,处理反方向的bug
            var newDir = (event.keyCode > 36 && event.keyCode < 41) ? event.keyCode : 40;
            // 处理反方向
            if(Math.abs(direct - newDir) == 2) {
                alert("头碰到身体了,Game over!");
            } else {
                direct = newDir;
                update();   
            }
        }
        // 随机生成食物
        function randFood() {          
            do{
                food_x = Math.ceil(Math.random() * 40 + 2) * 15 + 1;
                food_y = Math.ceil(Math.random() * 40 + 2) * 15 + 1;
            }while(isBody(food_x,food_y));
            
        }
        // 判断食物是否在蛇的身体上 
        function isBody(param_x,param_y) {
            // 判断蛇头是否碰到了蛇身 
            for (var i = 0; i < snakeLength - 1; i++) {
                if(snake[i].x === param_x && snake[i].y === param_y) {
                    return true;
                }
            }
            // 判断食物是否在蛇的身体上 
            var snakeLast = snake[snakeLength-1];
            if(snakeLast) {
                if(snakeLast.x === param_x && snakeLast.y === param_y) {
                    return true;
                }
            }
            return false;
        }
        // 定时更新画面
        function update() {
            timer = setInterval(function() {
                // 到达边界
                if(snake[0].x < 1 || snake[0].y < 1 || snake[0].x > maxNumber || snake[0].y > maxNumber) {
                    clearInterval(timer);
                    alert('出边界了,Game over!');
                } else {
                    // 重新绘制贪吃蛇
                    drawSnake();

                    // 检测是否吃到食物
                    checkFood();
                }
            },speed)
        }

        // 绘制贪吃蛇
        function drawSnake() {
            // 擦出蛇尾巴
            var snakeLast = snake[snakeLength-1],
                snakeHead = snake[0];                
            clear(snakeLast.x,snakeLast.y);

            // 删除尾巴
            snake.pop();
            // 增加头
            addHead(snakeHead.x,snakeHead.y);
        }
        // 增加头
        function addHead(param_x,param_y) {
            var newX,newY;
            // 37:左 38:上 39:右  40:下
            switch (direct) {
                case 37:
                    newX = param_x - stride;
                    newY = param_y;
                    break;
                case 38:
                    newY = param_y - stride;
                    newX = param_x;
                    break;
                case 39:
                    newX = param_x + stride;
                    newY = param_y;
                    break;
                case 40:
                    newY = param_y + stride;
                    newX = param_x;
                    break;
            }

            // 增加蛇头
            // 检测头是否 碰到身体
            if(snakeLength > 3 && isBody(newX,newY)) {
                clearInterval(timer);
                alert("头碰到身体了,Game over!");
            } else {
                snake.unshift({x:newX,y:newY});
                draw(snake[0].x,snake[0].y);
            }
        }

        // 检测是否吃到食物
        function checkFood() {
            if(snake[0].x === food_x && snake[0].y === food_y) {
                // 增加头
                snakeLength += 1;
                addHead(food_x,food_y);
                // 改变分数
                score += 10;
                span_score.innerHTML = score;
                // 改变速度
                speed = (speed > 100) ? (speed - 20) : speed;
                randFood();
                draw(food_x,food_y);
            }
        }

        // 清除
        function clear(param_x,param_y) {
            context.clearRect(param_x,param_y,stride - 2,stride - 2);
        }
        // 画小方块
        function draw(param_x,param_y) {
            context.fillRect(param_x,param_y,stride - 2,stride - 2);
        }
        // 初始化函数
        function init() {
            context.lineWidth = 1;
            context.fillStyle = '#69D69E';
            context.strokeStyle="#89EFA3";
            var i = 0;
            while(i <= maxNumber) {
                context.moveTo(0, i);
                context.lineTo(maxNumber,i);
                context.stroke();

                context.moveTo(i,0);
                context.lineTo(i,maxNumber);
                context.stroke();
                i += stride;
            }
            snake.push({x:31,y:61});
            randFood();
            draw(food_x,food_y);
            draw(snake[0].x,snake[0].y);
        }
    }



ps:所有测试都是在最新版本的谷歌浏览器下进行



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值