Javascript贪吃蛇

代码如下(每一步都有详细的解释):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>贪吃蛇地图的 绘制</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        h1{
            margin-left: 20px;
        }
        #bts{
            margin-left: 20px;
        }
        button{
            font-size: 20px;
        }
        #map{
            width: 500px;
            height: 500px;
            background-color: pink;
            position: relative;
            /* 给粉色背景色一个相对定位 */
        }
        td{
            width: 48px;
            height: 48px;
        }
        table{
            position: absolute;
            top: 67px;
            left: 0px;
            /* 给表格设置一个绝对定位,相对定位到粉色的背景色上 */
        }
    </style>
</head>
<body>
    <h1 id="Score">Score: 0</h1>
    <div id="bts">
         <button id="bt1"></button>
         <button id="bt2"></button>
         <button id="bt3"></button>
    </div>
    <div id="map"></div>
    <script>
        // 利用for循环创建一个10*10的表格
        document.write("<table border='1' cellspacing='0'>")
            for(var n=0;n<10;n++){
                document.write("<tr>")
                    for(var j=0;j<10;j++){
                        document.write("<td></td>")
                    }
                    document.write("</tr>")
            }
        document.write("</table>")
        // // 蛇头的随机生成
        // var head=document.createElement("div")
        // head.style.width="50px"
        // head.style.height="50px"
        // head.style.backgroundColor="red"
        // head.style.position="absolute"
        // head.style.top=parseInt(Math.random()*10)*50+"px"
        // head.style.left=parseInt(Math.random()*10)*50+"px"
        // //使用随机数的概念来 随机产生对应的位置
        // //Math.random() 0-1随机数  小数
        // //发现left和top必须为50的整数倍 ,0-9
        // //产生一个0-9随机数,*50
        // //Math.random() 0-1*10  0-10随机数   parseInt()
        // var map=document.getElementById("map")
        // map.appendChild(head)
        // // 食物的随机生成
        // var food=document.createElement("div")
        // food.style.width="50px"
        // food.style.height="50px"
        // food.style.backgroundColor="blue"
        // food.style.position="absolute"
        // food.style.top=parseInt(Math.random()*10)*50+"px"
        // food.style.left=parseInt(Math.random()*10)*50+"px"
        // map.appendChild(food)

        //将这个蛇头和食物的随机生成封装成函数
        function createDiv(Color){
            // 创建一个div标签并放到div这个变量里
            var div=document.createElement("div")
            // 创建的这个标签宽度为50px,高度50px
            div.style.width="50px"
            div.style.height="50px"
            // 设置新创建的这个div的颜色
            div.style.backgroundColor=Color
            // 给这个新创建的元素一个绝对定位,以body为圆点设置
            div.style.position="absolute"
            // 每次刷新,蛇头和食物都会随机出现在地图上
            div.style.top=parseInt(Math.random()*10)*50+"px"
            div.style.left=parseInt(Math.random()*10)*50+"px"
            // 找到map,并在map里创建新的div
            var map=document.getElementById("map")
            map.appendChild(div)
            // 返回div,就可以在函数外部调用了
            // 通过变量来使用,当前对应的div标签
            return div
        }
        // 蛇头调用这个函数,并且背景色设置为红色
        var head=createDiv("red")
        // 食物调用这个函数,并且背景色设置为蓝色
        var food=createDiv("blue")
        // 将蛇头默认移动的方向设置为向上移动
        head.direction="上"
        // 找到这三个启动按钮
        // 快
        var bt1=document.getElementById("bt1")
        // 中
        var bt2=document.getElementById("bt2")
        //慢
        var bt3=document.getElementById("bt3")
        // 给这三个按钮添加事件
        var t
        bt1.onclick=function(){
          window.t=setInterval(function(){
             move()
          },200)
  
        }
        bt2.onclick=function(){
            window.t=setInterval(function(){
            move()
          },500)
     
        }
        bt3.onclick=function(){
            window.t=setInterval(function(){
            move()
          },700)
         
        }
        var bodyNodes=[]  // var一个空数组用来放置,生成的身体
        var s=0 //用来计算分数
        // 启动自动移动的定时器中的内容
        function move(){
            switch(head.direction){
                case "左":
                   var t=parseInt(head.style.left)
                   head.style.left=t-50+"px"
                break
                case "右":
                   var t=parseInt(head.style.left)
                   head.style.left=t+50+"px"
                break
                case "上":
                   var t=parseInt(head.style.top)
                   head.style.top=t-50+"px"
                break
                case "下":
                   var t=parseInt(head.style.top)
                   head.style.top=t+50+"px"
                break
            }
            // 身体的移动,永远跟随前一块移动
            // 身体有长度,才可以控制他的移动
            if(bodyNodes.length>0){
            // 因为bodyNodes这个数组没有最后一个元素所以拿不到bodyNodes[n]
            // 因为length长度是1 索引值又从零开始 没有这个1 所以需要bodyNodes.length-1                
            for(var n=bodyNodes.length-1;n>=0;n--){
                    // 检查报错
                    // console.log(n)
                    // console.log(bodyNodes[n])
                    // 碰撞检测,检测蛇头有没有碰撞到身体,如果碰撞到身体,就游戏结束,终止定时器
                     if(bodyNodes[n].style.left==head.style.left&&bodyNodes[n].style.top==head.style.top){
                        alert("咬到本座的尾巴了,你是🐖吗?")
                        clearInterval(window.t)
                     }
                     switch(bodyNodes[n].direction){
                        case "左":
                        var t=parseInt(bodyNodes[n].style.left)
                        bodyNodes[n].style.left=t-50+"px"
                        break
                        case "右":
                        var t=parseInt(bodyNodes[n].style.left)
                        bodyNodes[n].style.left=t+50+"px"
                        break
                        case "上":
                        var t=parseInt(bodyNodes[n].style.top)
                        bodyNodes[n].style.top=t-50+"px"
                        break
                        case "下":
                        var t=parseInt(bodyNodes[n].style.top)
                        bodyNodes[n].style.top=t+50+"px"
                        break
                     }
                     // 判断当前的是不是生成的第一块身体,如果是,跟随蛇头的移动方向移动
                     // 其他的身体跟随前一块移动
                        if(n==0){
                          bodyNodes[n].direction=head.direction
                        }else{
                            bodyNodes[n].direction=bodyNodes[n-1].direction
                        }
                 }
            }
            // 食物碰撞检测
            if(head.style.left==food.style.left&&head.style.top==food.style.top){
                console.log("碰撞成功")
                // 蛇头每吃一块食物,产生一个黄色的身体,在蛇头的后方
                // 身体更在最后一块后边,明确谁是最后一块,操作每一块身体
                var body=createDiv("yellow")
                // 蛇头每吃一个食物就生成一个身体
                // 目前产生的身体位置是随机的,要求是跟在最后一块的后边移动
                // 数组中最后一个内容,数组中如果是空,蛇头就是最后一块内容
                var lastNode  //var 一个新变量,表示最后一块
                if(bodyNodes.length==0){
                // 蛇头是最后一块
                     lastNode=head
                }else{
                // 因为要跟在最后一块后边移动,所以需要bodyNodes中的数组长度-1
                     lastNode=bodyNodes[bodyNodes.length-1]
                }
                // body的位置,要根据最后一块的移动方向来决定的,
                // 在最后一块移动方向的后边创建新的身体.
                switch(lastNode.direction){
                // 当最后一块的移动方向为上,下的时
                // 新生成的身体左,右保持一致
                // 在移动方向的相反方向生成身体(如果在相同方向,直接咬死自己)
                    case "上":
                        body.style.left=lastNode.style.left
                        body.style.top=parseInt(lastNode.style.top)+50+"px"
                    break
                    case "下":
                        body.style.left=lastNode.style.left
                        body.style.top=parseInt(lastNode.style.top)-50+"px"
                    break
                // 当最后一块的移动方向为左,右时
                // 新生成的身体上,下保持一致
                //在移动方向的相反方向生成身体(如果在相同方向,直接咬死自己)
                    case "左":
                        body.style.top=lastNode.style.top
                        body.style.left=parseInt(lastNode.style.left)+50+"px"
                    break
                    case "右":
                        body.style.top=lastNode.style.top
                        body.style.left=parseInt(lastNode.style.left)-50+"px"
                    break
                }

                // 新产生的身体 移动方向,和最后一块的移动方向保持一致
                body.direction=lastNode.direction
                //将新产生的身体放入数组中
                bodyNodes.push(body)
                console.log(body)

                //食物的位置随之更新
                food.style.top=parseInt(Math.random()*10)*50+"px"
                food.style.left=parseInt(Math.random()*10)*50+"px"

                // 计算分数,每吃一个食物,分数加10
                // 用id找到这个分数
                var Score=document.getElementById("Score")
                s=s+10
                Score.innerHTML="Score:"+s
            }

            if(parseInt(head.style.top)>=500||parseInt(head.style.top)<0||parseInt(head.style.left)>=500||parseInt(head.style.left)<0){
                  console.log("撞墙死亡")
                  clearInterval(window.t)
                  alert("撞到本座的头了,你眼瞎吗?")
            }
        }
        // 按键控制div移动
        document.onkeydown=function(event){
            var e = event || window.event
            console.log(e.keyCode)
            switch(e.keyCode){
                case 38:
                  head.direction="上"
                break
                case 40:
                  head.direction="下"
                break
                case 37:
                  head.direction="左"
                break
                case 39:
                  head.direction="右"
                break
            }
        }
    </script>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

油、东西

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值