美文网首页web前端前端JavaScript学习指南
JavaScript原生实现《贪吃蛇》

JavaScript原生实现《贪吃蛇》

作者: 范小饭_ | 来源:发表于2017-01-03 20:06 被阅读3734次

    贪吃蛇大家都不陌生吧~
    简单做一个。

    贪吃蛇.jpg

    因为没有图片素材,所以只能用简单的样式代替了,不要嫌弃呀~

    思路

    1.让我们的小蛇动起来
    2.随机生成食物
    3.每吃掉一个食物,蛇的身体会变长,食物会重新换位置

    html界面

    <div class="face">
        <!-- 小蛇移动的操场 -->
        <div id="playground">
            <!-- 食物 界面中的蓝色小方块-->
            <div id="food"></div>
            <!-- 小蛇 界面中的红色小方块-->
            <div id="snack"></div>
        </div>
        <!-- 计算得分 -->
        <div class="menu">
            <div>得分<span id="score"></span></div>
        </div>
    </div>
    

    css样式
    注:
    1.蓝色的小方块代表食物;
    2.红色的小方块代表小蛇;
    3.绿色的小方块代表吃掉怪物后增长的身体;

        <style type="text/css">
            .face{
                height: 400px;
                width: 600px;
                margin-left: auto;
                margin-right: auto;
                position: relative;
                background-color: pink;
            }
            #playground{
                height: 400px;
                width: 450px;
                float: left;
                position: relative;
            }
            .menu{
                height: 400px;
                width: 150px;
                float: left;
                background-color: skyblue;
            }
            #snack{
                height: 20px;
                width: 20px;
                background-color: red;
                position: absolute;
                left: 0px;
                top:0px;
            }
            #food{
                height: 20px;
                width: 20px;
                background: blue;
                position: absolute;
            }
            .body{
                height: 20px;
                width: 20px;
                background: green;
                position: absolute;
                left: 0px;
                top:0px;
            }
            #score{
                font-size: 30px;
                font-weight: bold;
                color: red;
            }
            .menu div{
                font-size: 20px;
                font-weight: bold;
            }
        </style>
    
    准备工作

    获取元素节点、设置全局变量;

        //获取元素节点
        var jsDiv = document.getElementById("playground");
        var jsSnack = document.getElementById("snack"); 
        var jsFood = document.getElementById("food");
        var jsBody = document.getElementById("playground");
        var jsScore = document.getElementById("score");
        //设置全局变量
        var timer;//创建定时器为全局变量
        var timer1 = setInterval(eat,10);//检测位置碰撞,并且吃掉食物;
        var srr = [];//记录蛇行动的位置
        var num = 0 ;//记录数组的长度
        var jsSnackBody ;//么米吃掉一个食物,蛇的身体
    
    让我们的小蛇动起来

    通过按键盘的上下左右键,控制小蛇的移动方向,并记录小蛇走过的位置。
    我们通过什么来获取我们按下的是哪个键??
    我们当然通过ASCII码值;

    信息在计算机上是用二进制表示的,这种表示法让人理解就很困难。因此计算机上都配有输入和输出设备,这些设备的主要目的就是,以一种人类可阅读的形式将信息在这些设备上显示出来供人阅读理解。为保证人类和设备,设备和计算机之间能进行正确的信息交换,人们编制的统一的信息交换代码,这就是ASCII码表,它的全称是“美国信息交换标准代码”

    左-------》对应的ASCII码值是 37;
    上-------》对应的ASCII码值是 38;
    右-------》对应的ASCII码值是 39;
    下-------》对应的ASCII码值是 40;

        //开始游戏
        document.onkeydown = function(e){
            var evt = e || window.event;    
                switch(evt.keyCode) {
                //向左移动
                case 37:
                    clearInterval(timer);
                    timer=window.setInterval(runLeft,10)
                    function runLeft(){
                        if (jsSnack.offsetLeft > 0) {
                            jsSnack.style.left = jsSnack.offsetLeft - 1+ "px";
                            jsSnack.style.top = jsSnack.offsetTop + "px";   
                            //记录小蛇的位置
                            srr.push([jsSnack.offsetLeft, jsSnack.offsetTop]);
                            num++;//记录数组的长度
                        }                       
                    }
                break;
                //向上移动
                case 38:
                    clearInterval(timer);
                    timer=window.setInterval(runTop,10);    
                    function runTop(){
                        if (jsSnack.offsetTop > 0) {
                            jsSnack.style.top = jsSnack.offsetTop - 1 + "px";
                            jsSnack.style.left = jsSnack.offsetLeft + "px";
                            //记录小蛇的位置
                            srr.push([jsSnack.offsetLeft, jsSnack.offsetTop]);
                            num++;//记录数组的长度
                        }                       
                    }
    
                break;
                //向右移动
                case 39:
                    clearInterval(timer);
                    timer=window.setInterval(runRight,10);
                    function runRight(){
                        if (jsSnack.offsetLeft + jsSnack.offsetWidth <= 450) {
                            jsSnack.style.left = jsSnack.offsetLeft + 1 + "px";
                            jsSnack.style.top = jsSnack.offsetTop + "px";
                            //记录小蛇的位置
                            srr.push([jsSnack.offsetLeft, jsSnack.offsetTop]);
                            num++;//记录数组的长度
                        }                       
                    }                   
                break;
                //向下移动  
                case 40:
                    clearInterval(timer);
                    timer=window.setInterval(runBottom,10);         
                    function runBottom(){
                        if (jsSnack.offsetTop + jsSnack.offsetHeight <= 400) {
                            jsSnack.style.top = jsSnack.offsetTop + 1 + "px";
                            jsSnack.style.left = jsSnack.offsetLeft + "px";
                            //记录小蛇的位置
                            srr.push([jsSnack.offsetLeft, jsSnack.offsetTop]);
                            num++;//记录数组的长度
                        }                       
                    }                   
                break;
            }
        }
    
    GIF.gif

    检验碰撞详解
    这里笔者觉得语言的描述太空洞,还是弄几张图吧,图是笔者手绘的,不要嫌丑,画的是没有碰撞的情况,那取反,就说明碰撞到了

    01.jpg 04.jpg 03.jpg 02.jpg
    食物随机出现

    把食物的随机出现封装在一个函数里,那么我们后续需要的时候可以直接调用。
    利用随机数来让食物的位置随机出现。

        //食物随机出现
        function Pos(){
            jsFood.style.left=parseInt(Math.random() * (430 - 20 + 1) + 20) + "px";
            jsFood.style.top=parseInt(Math.random() * (380 - 20 + 1) + 20) + "px";
        }
        Pos();
    
    GIF1.gif
    创建定时器、检验碰撞

    碰撞检测原理:
    蛇在实物的左边、右边、上边、下边的时候,说明没有发生碰撞,那么我们取反,就说明发生碰撞

    function eat(){
            rectangleCrashExamine(jsSnack,jsFood);
            function rectangleCrashExamine(obj1, obj2) {
                var obj1Left = obj1.offsetLeft;
                var obj1Width = obj1.offsetLeft + obj1.offsetWidth;
                var obj1Top = obj1.offsetTop;
                var obj1Height = obj1.offsetTop + obj1.offsetHeight;
                var obj2Left = obj2.offsetLeft;
                var obj2Width = obj2.offsetLeft + obj2.offsetWidth;
                var obj2Top = obj2.offsetTop;
                var obj2Height = obj2.offsetTop + obj2.offsetHeight;
                //检测碰撞
                //碰撞检测原理:
                    //蛇在实物的左边、右边、上边、下边的时候,说明没有发生碰撞,那么我们取反,就说明发生碰撞
                if ( !(obj1Left > obj2Width || obj1Width < obj2Left || obj1Top > obj2Height || obj1Height < obj2Top) ) {
                    //碰撞后身体
                    jsSnackBody = document.createElement("div");
                    jsSnackBody.setAttribute("class","body");
                    jsBody.appendChild(jsSnackBody);
                    Pos();//怪物的位置随机变换
                    setInterval(follow,10);//身体跟随的定时器
                }
            }
        }
    
    身体跟随

    每吃掉一个食物,小蛇的长度发生变化

        function follow(){
            //检查一共添加了多少身体
            var bodyNum = document.getElementsByClassName("body");
            //记录得分
            jsScore.innerHTML = bodyNum.length;
            //蛇每次移动1个像素,那么新的身体应该跟随在当前数组的倒数第20个数组的位置;依次加等;
            var place = 0 ;
            for( var i = 0 ; i<bodyNum.length ; i++){
                place += 20;
                bodyNum[i].style.left=srr[num-place][0] + 'px';
                bodyNum[i].style.top=srr[num-place][1] + 'px';  
            }
        }
    
    

    好了,现在我们的游戏可以玩了

    GIF.gif
    这是一个简单的贪吃蛇,并没有做死亡碰撞,喜欢的小伙伴可以继续放下做。
    任何时候不要吝啬您的赞美,喜欢就点赞拉~,互粉互粉

    相关文章

      网友评论

      • huang伟鸿wh:我一直不知道怎么改。。。。。。。
      • huang伟鸿wh:为什么我在向下的时候同时左上,或者向上的时候同时右下会出错。。。。。。
      • 萌酷萌酷的兔:好棒啊,感觉好长哦,我见过一个28行代码的,不过你的更详细,原理都介绍了,顶!
      • cf076a1ff8fd:姐啊,复制粘贴上去后咋运行不出来呢
      • 丶无心之恋:小白在此膜拜。。。。
      • 744bb97e6c1a:定义全局变量的时候楼主设置了一个jsStart。我没发现他的作用啊:disappointed_relieved:
        范小饭_:@744bb97e6c1a 不要意思啦,我现在更新一下文章,哈哈
        744bb97e6c1a:@范小饭_ 作为一个新手。哦通篇去找了一遍。。。:joy:
        范小饭_:@744bb97e6c1a 嗯,因为当时想点击的时候开始游戏,后来没有做点击,然后又忘了删掉了,:smile:、谢谢提醒
      • 旧丶时候:厉害👍
        范小饭_:@Mr_森哥 憋闹,你也会
      • 冯走心:牛B 收藏先~`
        范小饭_:@饥人谷_冯泽民 :grin::grin:谢谢
      • assassian_zj:屌屌的,还是个妹子吧。自叹不如:scream:
        范小饭_:@assassian_zj 新手上路而已:smile:
      • 吴小臭:字蛮漂亮的哦
        范小饭_:@44205697c532 不要埋汰我~:grin:
      • 麦田里的Demian:关注你之后收获好多,下学期就出去找实习了,谢谢你最近的分享!
        范小饭_:@麦田里的Demian :smile::smile:不客气,互相帮助
      • 语小落:持续关注作者的更新哦:yum:,开始学习不久,这种项目能更好的提升兴趣,作者加油哦:fist:
        范小饭_:@渐近线 谢谢啦,会加油的~ :smile:
      • ciqulover:看到了自己初学js时候的影子,怀念哈。
        范小饭_:@ycwalker 哈哈 我就是初学者,哇哈哈
      • smartphp:好啊!正想看看这样的代码
        范小饭_:@smartphp 喜欢就好~ :stuck_out_tongue_winking_eye:
      • ghwaphon:拐弯的时候那个豁口像马赛克,不过作者还是棒棒的
        范小饭_:说的对,哪个地方我看了一下,确实可以完善,有时间的话修改一下,谢谢提醒啦
      • FromThenOn:厉害啊,我要试一下,先收藏
        范小饭_:@FromThenOn :smile: 你肯定比我强
      • 聪少Jeff::+1:
        范小饭_:@聪少Harry :smile:

      本文标题:JavaScript原生实现《贪吃蛇》

      本文链接:https://www.haomeiwen.com/subject/vnsnvttx.html