js实现网页贪吃蛇

实现一个贪吃蛇小游戏主要思路是这样:
1、创建一个20*20的地图
2、实现一个snake对象 包括snake的移动函数
3、实现一个food 对象 ,包括随机生成food坐标点
4、添加键盘方向键事件
5、在蛇的每次移动中,每一步的时间间隔之间只允许输入一次键盘方向
6、附加功能:计分 、选择难易程度、

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>JS</title>
    <style type="text/css">
    body {
        margin: 0 auto;
        display: table;
    }
    td{ /*地图的样式*/

        border: 1px solid black;
        padding: 5px;
    }
    button{
        margin: 20px;
    }
    .snake{ /*snake的样式*/
        background-color: black;
    }
    .food{/*food的样式*/
        background-color: green;
    }

    </style>
</head>
<body>
    <button id ='easy' } >简单</button>
    <button id ='normal' >普通</button>
    <button id = 'hard' >困难</button>
    <p>你的得分:</p>
    <span id = 'score'>0</span>
    <div id='map'></div>
    <script type="text/javascript">
    window.onload = function(){
        var body =document.getElementsByTagName('body')[0];
        var map=document.getElementById('map');
        var table=document.createElement('table');
        var tbody=document.createElement('tbody');
        var tr = document.createElement('tr');
        var td=document.createElement('td');
        var grid =  document.getElementsByTagName('td');
        var showscore = document.getElementById('score')
        var easy = document.getElementById('easy')
        var normal = document.getElementById('normal')
        var hard = document.getElementById('hard')
        var map = document.getElementById('map')

        function initmap(){ //初始化地图 ,在map中插入20*20个的td元素
            map.innerHTML= "";
            for (var j=0;j<20;j++){
                var col = document.createElement('tr');
                for (var i=0;i<20 ;i++){
                    var row=document.createElement('td');
                    col.appendChild(row);
                }
                table.appendChild(col);
            }
            map.appendChild(table)
        }

        var score = 0; //实现计分功能
        var snake ={
            body:[[1,1],[1,2]], //蛇的身体坐标
            dir:[0,0], //蛇的移动方向 第一个为行数 第二个为列数
            move:function(){ //snake移动函数
                var len = snake.body.length;
                delsnake();//先把上面一步绘制的蛇消去
                if(snake.dir[1]!=0||snake.dir[0]!=0){ //当方向开始移动时
                    for (var i=0 ; i<len-1;i++){
                        snake.body[i][0]=snake.body[i+1][0];
                        snake.body[i][1]=snake.body[i+1][1];
                    }//snake身体的每一个坐标赋值给下一个节点

                    snake.body[len-1][0]+=snake.dir[0];
                    snake.body[len-1][1]+=snake.dir[1];//snake的头方向的x,y左边分别加上移动方向的增量,得到新的坐标
                }
                var snakesign =(snake.body[len-1][0]-1)*20+snake.body[len-1][1]-1;
                var foodsign = food.y*20+food.x;
//用来判断snake的头部将要移动到的点是否为食物所在点
                if(snakesign == foodsign){ //如果头部和食物所在点重合
                    snake.body.push([food.y+1,food.x+1]);//snake的身体长度+1 把食物所在坐标压入body数组
                    snake.body[snake.body.length-1][0]=snake.body[snake.body.length-2][0];
                    snake.body[snake.body.length-1][0]=snake.body[snake.body.length-2][0];
                    for (var i=snake.body.length-2;i>0;i--){
                        snake.body[i][0]=snake.body[i-1][0];
                        snake.body[i][1]=snake.body[i-1][1];
                    }
                    snake.body[0][0]=snake.body[1][0];
                    snake.body[0][1]=snake.body[1][1];//snake的坐标重新计算

                    score +=1;//得分增加

                    showscore.innerHTML = score;//显示得分
                    food.initfood();//重新生成food
                }
                for(var i = 0 ;i<len-2 ;i++){ //判断头部是否撞到身体
                    var snakebody =(snake.body[i][0]-1)*20+snake.body[i][1]-1;
                    if (snakesign == snakebody){
                        alert("撞到身体啦 You lose!");
                        snake.body = [[1,1],[1,2]];
                        snake.dir = [0,0];
                    }

                }
                if(snake.body[len-1][0]<=0||snake.body[len-1][0]>20||snake.body[len-1][1]<=0||snake.body[len-1][1]>20){//判断头部是否撞到墙壁
                    alert("撞到墙啦 You lose!");
                    snake.body = [[1,1],[1,2]];
                    snake.dir = [0,0];
                }
                initsnake();//重新绘制snake
            }
        }
        var food = {
            x:0,
            y:0,
            initfood:function (){ //随机生成food坐标
                food.x=parseInt(Math.random()*20);
                food.y=parseInt(Math.random()*20);

                var foodsign = food.y*20+food.x;
                for(var flag = 0;flag<snake.body.length ;flag++){ //如果生成坐标与snake身体重合,则重新生成
                    var snakesign =(snake.body[flag][0]-1)*20+snake.body[flag][1]-1;
                    if(foodsign==snakesign){
                        food.initfood();
                        break;
                    }
                }
                grid[food.y*20+food.x].className='food';
            }
        }

        function initsnake(){ //给snake所在的坐标格数添加snake样式
            for(var flag = 0;flag<snake.body.length ;flag++){
                var sign =(snake.body[flag][0]-1)*20+snake.body[flag][1]-1;
                grid[sign].className='snake'
            }
        }
        function delsnake(){ //删除显示的snake
            for(var flag = 0;flag<snake.body.length ;flag++){
                var sign =(snake.body[flag][0]-1)*20+snake.body[flag][1]-1;
                grid[sign].className=''
            }
        }

        var flag =0; //用来判断snake一步的移动内 只允许输入一个方向键
        document.onkeydown = keyDown;
        function keyDown(e){ //给键盘方向键添加事件

            if(flag==0){
                switch(e.keyCode){
                    case 37:
                    if(snake.dir[1]!=1){ //只有输入方向和原来方向不为反方向,才能输入成功
                        snake.dir = [0,-1];
                    }
                    break;
                    case 38:
                    if(snake.dir[0]!=1){//只有输入方向和原来方向不为反方向,才能输入成功
                        snake.dir = [-1,0];
                    }
                    break;
                    case 39:
                    if(snake.dir[1]!=-1){//只有输入方向和原来方向不为反方向,才能输入成功
                        snake.dir=[0,1];
                    }
                    break;
                    case 40:
                    if(snake.dir[0]!=-1){//只有输入方向和原来方向不为反方向,才能输入成功
                        snake.dir = [1,0];
                    }
                    break;
                }
            }
            flag++;
        }

        initmap();
        food.initfood();
        var interval;
        easy.onclick = function(){ //给容易按钮添加时间
            score=0;
            showscore.innerHTML=score;
            delsnake();
            snake.body = [[1,1],[1,2]];
            snake.dir = [0,0]; //重新设置snake
            interval=clearInterval(interval)
            interval =interval =setInterval(
                function(){ 
                    flag=0; //重置flag ,可以进行下一次输入
                    snake.move()
                },500)//每隔500ms走一步

        }
        normal.onclick = function(){
            score=0;
            showscore.innerHTML=score;
            delsnake();
            snake.body = [[1,1],[1,2]];
            snake.dir = [0,0];
            interval=clearInterval(interval)
            interval =setInterval(
                function(){ 
                    flag=0;
                    snake.move()
                },300)//每隔300ms走一步
        }
        hard.onclick = function(){
            score=0;
            showscore.innerHTML=score;
            delsnake();
            snake.body = [[1,1],[1,2]];
            snake.dir = [0,0];
            interval=clearInterval(interval)
            interval =setInterval(
                function(){ 
                    flag=0;
                    snake.move()
                },100)//每隔100ms走一步
        }

    }
    </script>
</body>
</html> 

这个项目的项目地址:
github

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值