原生js实现贪吃蛇小游戏

先上图:

贪吃蛇

废话不多说,直接奉上代码



<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title></title>

    <style>

        * {

            margin: 0;

            padding: 0;

        }

        .l {

            float: left;

        }

        .r {

            float: right;

        }

        .clear_fix::after {

            content: '';

            height: 0;

            width: 100%;

            display: block;

            clear: both;

            overflow: hidden;

            visibility: hidden;

        }

        .body {

            margin: 50px 0 0 50px;

            width: 700px;

        }

        .cont {

            width: 500px;

            height: 500px;

            border: 1px solid green;

            margin-right: 8px;

            position: relative;

        }

        .cont div {

            position: absolute;

            width: 10px;

            height: 10px;

            background-color: orange;

            border: 1px solid #000;

            box-sizing: border-box;

        }

        .cont .snakeHead {

            border-radius: 50%;

        }

        .cont span {

            position: absolute;

            display: inline-block;

            width: 10px;

            height: 10px;

            border: 1px solid #000;

            box-sizing: border-box;

            border-radius: 50%;

            background: green;

        }

        .score {

            width: 188px;

            height: 500px;

            border: 1px solid red;

        }

        .score p {

            text-align: center;

            height: 50px;

            line-height: 50px;

            font-size: 30px;

            margin: 20px 0;

            color: brown

        }

        .score .time{

            color: chartreuse;

            font-size: 20px;

        }

        .btn {

            margin-left: 50px

        }

        .btn .active {

            background-color: green;

        }

        button {

            width: 100px;

            height: 30px;

            font-size: 24px;

        }

    </style>

</head>

<body>

    <div id="wrap">

        <div class="body clear_fix">

            <div class="cont l">

            </div>

            <div class="score l">分数:

                </br>

                <p>0分</p>

                <hr>

                时间:

                <p class="time"></p>

            </div>

        </div>

        <div class="btn">

            <button>开始</button>

            <button class="active">普通</button>

            <button>困难</button>

            <button>地狱</button>

        </div>

    </div>

    <script>

        var snake = {

            /* 初始化全局属于,已经添加初始事件监听 */

            init: function () {

                this.btns = document.querySelectorAll('button');

                this.score = document.querySelector('p');

                this.cont = document.querySelector('.cont');

                //时间显示的容器

                this.time = document.querySelector('.time');

                //蛇的方向,'r'表示向右

                this.dir = 'r';

                /* 定时器 */

                this.timer = '';

                /* 初始蛇头位置 */

                this.head = {

                    l: 30,

                    t: 10

                }

                //蛇尾

                this.ender = {

                    l: '',

                    t: ''

                };

                this.foodItem = {

                    l: '',

                    t: ''

                };

                //为开始的状态

                this.isStart = false;

                /* 计分器 */

                this.counter = 0;

                //简单status为1,困难为2,地狱为3

                this.status = 1;

                this.speed = 10

                this.btns[0].onclick = this.startFn //开始或者暂停

                this.btns[1].onclick = this.simpleFn //简单模式监听

                this.btns[2].onclick = this.difcultFn //困难模式监听

                this.btns[3].onclick = this.hardFn //地狱模式监听

                this.initCreate();

                this.getTime()

                //随机一个食物

                this.getfood()

            },

            initCreate() {

                //创建一个初始蛇头和蛇身3块

                for (let i = 0; i <= 3; i++) {

                    let item = document.createElement('div');

                    Object.assign(item.style, {

                        left: this.head.l - 10 * i + 'px',

                        top: this.head.t + 'px',

                        /* borderRaduis: '50%' */

                    })

                    if (i == 0) {

                        item.className = 'snakeHead'

                    }

                    snake.cont.appendChild(item);

                }

            },

            /* 增加蛇身一节 */

            createSnake: function (obj) {

                clearInterval(snake.timer)

                var div = document.createElement('div');

                div.style.left = snake.ender.l;

                div.style.top = snake.ender.t;

                snake.cont.appendChild(div);

                console.log(snake.cont.children);

                snake.move();

                /* console.log(snake.cont); */

            },

            /* 判断是否为开始 */

            startFn: function () {

                if (!snake.isStart) {

                    snake.move();

                    snake.btns[0].innerHTML = '暂停';

                    snake.isStart = true;

                } else {

                    snake.stop();

                    snake.btns[0].innerHTML = '开始';

                    snake.isStart = false;

                }

            },

            /* 开始移动,核心模块 */

            move: function () {

                document.onkeydown = snake.controlFn;

                var itemsAll = snake.cont.children;

                /* console.log(itemsAll);

                console.log(itemsAll,itemsAll[0].nodeName); */

                /* 存储蛇身每一节的数组 */

                var items = [];

                var span;

                /* var items = Array.from(itemsAll).filter(function (v, k) {

                    return v.nodeName === 'DIV'

                }); */

                /* console.log(items); */

                /* 过滤筛选div(蛇身)与span(食物) */

                for (var j = 0; j < itemsAll.length; j++) {

                    if (itemsAll[j].nodeName == 'DIV') {

                        items.push(itemsAll[j])

                    } else {

                        span = itemsAll[j]

                    }

                }

                /* 获取蛇头的位置 */

                var l = snake.head.l;

                var t = snake.head.t;

                console.log(l, t);

                console.log(items)

                clearInterval(snake.timer)

                /* 键盘监听 */

                document.onkeydown = snake.controlFn

                /* 开始移动 */

                snake.timer = setInterval(function () {

                    /* 记录蛇尾位置,并更新至存放蛇尾对象的身上 */

                    snake.ender.l = items[items.length - 1].style.left;

                    snake.ender.t = items[items.length - 1].style.top;

                    /* 更新蛇身位置 */

                    for (var i = items.length - 1; i > 0; i--) {

                        items[i].style.left = items[i - 1].style.left;

                        items[i].style.top = items[i - 1].style.top;

                    }

                    /* 判断蛇头的方向并更新其位置 */

                    if (snake.dir == 'l') {

                        l -= snake.speed;

                    }

                    if (snake.dir == 'r') {

                        l += snake.speed;

                    }

                    if (snake.dir == 't') {

                        t -= snake.speed;

                    }

                    if (snake.dir == 'b') {

                        t += snake.speed;

                    }

                    /* 出边界y */

                    if (l < 0 || l > 490 || t < 0 || t > 490) {

                        clearInterval(snake.timer)

                        snake.reStart(confirm('蛇皮怪你撞墙了!!是否重新来过?'))

                    }

                    items[0].style.left = l + 'px';

                    items[0].style.top = t + 'px';

                    /* 更新记录蛇头的对象 */

                    snake.head.l = l

                    snake.head.t = t

                    /* console.log(items[0].style); */

                    /* 插入蛇头 */

                    snake.cont.appendChild(items[0])

                    for (var k = 1; k < items.length; k++) {

                        /* 判断蛇头是否咬到了自己 */

                        if (items[0].style.left == items[k].style.left && items[0].style.top == items[k]

                            .style.top) {

                            snake.reStart(confirm('蛇皮怪你咬死自己了,是否重新来过?'))

                            /* console.log(items[0].style.left,items[0].style.top);

                            console.log(items[0].style.left,items[0].style.top); */

                            clearInterval(snake.timer)

                            /* alert('Game Over!');

                            window.location.reload(true) */

                            return

                        }

                        /* 插入蛇身 */

                        snake.cont.appendChild(items[k])

                    }

                    /* 吃到了食物 */

                    console.log(span.style.left, span.style.top);

                    /* console.log(l, '吃到了食物'); */

                    if (l == parseInt(span.style.left) && t == parseInt(span.style.top)) {

                        snake.eat()

                    }

                }, parseInt(300 / snake.status))

            },

            eat() {

                snake.createSnake()

                snake.getfood()

                snake.counter++;

                snake.score.innerHTML = `${snake.counter*100}分`

            },

            /* 游戏结束判断是否重新开始 */

            reStart: function (value) {

                if (value) {

                    window.location.reload(true)

                }

            },

            /* 生产食物 */

            getfood: function () {

                if (document.querySelector('span')) {

                    console.log('进来了');

                    document.querySelector('span').remove();

                }

                var span = document.createElement('span');

                var l = snake.randM(0, 49) * 10

                var t = snake.randM(0, 49) * 10

                console.log('得到食物', l, t);

                span.style.left = l + 'px';

                span.style.top = t + 'px';

                snake.cont.appendChild(span);

                if (snake.isStart) {

                    snake.move()

                }

            },

            /* 产生随机数 */

            getTime() {

                let time,h,m,s


                setInterval(function () {

                    time = new Date()

                    h = time.getHours()

                    m = time.getMinutes();

                    s = time.getSeconds();

                     if (h < 10) {

                         h = '0' + h

                     }

                     if (m < 10) {

                         m = '0' + m

                     }

                     if (s < 10) {

                         s = '0' + s

                     }

                    snake.time.innerHTML = `${h}: ${m}: ${s}`

                }, 1000)

            },

            randM: function (min, max) {

                return Math.round(Math.random() * (max - min) + min)

            },

            /* 暂停 */

            stop: function () {

                clearInterval(snake.timer)

            },

            /* 简单模式 */

            simpleFn: function () {

                snake.status = 1;

                snake.btnFn()

                snake.btns[1].className = 'active'

            },

            /* 复杂模式 */

            difcultFn: function () {

                snake.status = 3;

                snake.btnFn()

                snake.btns[2].className = 'active'

            },

            /* 地狱模式 */

            hardFn: function () {

                snake.status = 5;

                snake.btnFn()

                snake.btns[3].className = 'active'

            },

            btnFn: function () {

                snake.btns.forEach(function (v, k) {

                    v.className = ''

                });

                if (snake.isStart) {

                    snake.move();

                }

            },

            /* 按键操作蛇的移动 */

            controlFn: function (el) {

                var el = el || window.event;

                var code = el.keycode || el.which;

                console.log(code);

                if ((code == 40 || code == 83)&&snake.dir !='t') {

                    snake.dir = 'b'

                }

                if ((code == 39 || code == 68)&&snake.dir !='l') {

                    snake.dir = 'r'

                }

                if ((code == 38 || code == 87)&&snake.dir !='b') {

                    snake.dir = 't'

                }

                if ((code == 37 || code == 65)&&snake.dir !='r') {

                    snake.dir = 'l'

                }

            }

        }

        snake.init();

    </script>

</body>

</html>

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容