mousedown + mouseup = click
image.png

html + CSS

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. <style>
  9. .wrap{
  10. position: relative;
  11. width: 500px;
  12. height: 500px;
  13. margin: 50px auto;
  14. background-color: #000;
  15. overflow: hidden;
  16. }
  17. .round{
  18. display: block;
  19. position: absolute;
  20. width: 20px;
  21. height: 20px;
  22. border-radius: 50%;
  23. background-color: green;
  24. z-index: 1;
  25. }
  26. .round.head{
  27. background-color: red;
  28. }
  29. .food{
  30. display: block;
  31. position: absolute;
  32. width: 20px;
  33. height: 20px;
  34. border-radius: 50%;
  35. background-color: yellow;
  36. z-index: 2;
  37. }
  38. </style>
  39. </head>
  40. <body>
  41. <div class="wrap"></div>
  42. <script src="./js/untils.js"></script>
  43. <script src="./js/index.js"></script>
  44. </body>
  45. </html>

JS

window.onload = function () {
    init();
}

function init() {
    initGame();
}

var initGame = (function () {
    var wrap = document.getElementsByClassName('wrap')[0],

        wrapW = getStyles(wrap, 'width'),
        wrapH = getStyles(wrap, 'height'),
        t = null;
    var Snake = function () {
        this.bodyArr = [{
                x: 0,
                y: 0
            },
            {
                x: 0,
                y: 20
            },
            {
                x: 0,
                y: 40
            },
            {
                x: 0,
                y: 60
            },
            {
                x: 0,
                y: 80
            },
            {
                x: 0,
                y: 100
            }
        ];
        this.dir = 'DOWN'
    }
    Snake.prototype = {
        init: function () {
            this.bindEvent();
            this.createFood();
            this.initSnake();
            this.run();
        },
        bindEvent: function () {
            var _self = this;
            addEvent(document, 'keydown', function () {
                _self.changeDir();
            });
        },
        initSnake: function () {
            var arr = this.bodyArr,
                len = arr.length,
                frag = document.createDocumentFragment(),
                item;
            for (var i = 0; i < len; i++) {
                item = arr[i];
                var round = document.createElement('i'); //i标签
                // console.log(round); 
                // 此处i是循坏中的i 查找数组中最后一项
                round.className = i === len - 1 ? 'round head' : 'round';

                round.style.left = item.x + 'px';
                round.style.top = item.y + 'px';
                frag.appendChild(round);
            }
            wrap.appendChild(frag);
        },
        run: function () {
            var _self = this
            t = setInterval(function () {
                _self.move();
            }, 500);
        },
        move: function () {
            var arr = this.bodyArr,
                len = arr.length;

            for (var i = 0; i < len; i++) {
                if (i === len - 1) {
                    this.setHeadXY(arr);
                } else {
                    arr[i].x = arr[i + 1].x;
                    arr[i].y = arr[i + 1].y;
                }
            }
            this.eatFood(arr);
            this.removeSnake();
            this.initSnake();
            this.headInBody(arr);
        },
        setHeadXY: function (arr) {
            var head = arr[arr.length - 1];
            switch (this.dir) {
                case 'LEFT':
                    if (head.x <= 0) {
                        head.x = wrapW - 20;
                    } else {
                        head.x -= 20;
                    }
                    break;
                case 'RIGHT':
                    if (head.x >= wrapW - 20) {
                        head.x = 0;
                    } else {
                        head.x += 20;
                    }
                    break;
                case 'UP':
                    if (head.y <= 0) {
                        head.y = wrapH - 20;
                    } else {
                        head.y -= 20;
                    }
                    break;
                case 'DOWN':
                    if (head.y >= wrapH - 20) {
                        head.y = 0;
                    } else {
                        head.y += 20;
                    }
                    break;
                default:
                    break;
            }
        },
        headInBody: function (arr) {
            var headX = arr[arr.length - 1].x,
                headY = arr[arr.length - 1].y;
            for (var i = 0; i < arr.length - 2; i++) {
                item = arr[i];
                if (headX === item.x && headY === item.y) {
                    var _self = this;
                    setTimeout(function () {
                        alert('游戏结束');
                        clearInterval(t);
                        _self.removeSnake();
                        _self.removeFood();
                    }, 100)
                }
            }
        },
        removeSnake: function () {
            var bodys = document.getElementsByClassName('round');
            while (bodys.length > 0) {
                bodys[0].remove();
            }
        },
        changeDir: function () {
            var e = e || window.event;
            code = e.keyCode;
            this.setDir(code);
        },
        setDir: function () {
            switch (code) {
                case 37:
                    if (this.dir !== 'RIGHT' && this.dir !== 'LEFT') {
                        this.dir = 'LEFT';
                    }
                    break;
                case 39:
                    if (this.dir !== 'RIGHT' && this.dir !== 'LEFT') {
                        this.dir = 'RIGHT';
                    }
                    break;
                case 38:
                    if (this.dir !== 'UP' && this.dir !== 'DOWN') {
                        this.dir = 'UP';
                    }
                    break;
                case 40:
                    if (this.dir !== 'UP' && this.dir !== 'DOWN') {
                        this.dir = 'DOWN';
                    }
                    break;
                default:
                    break;
            }
        },
        createFood: function () {
            var food = document.createElement('i');
            food.className = 'food';
            food.style.left = this.setRandomPos(wrapW) * 20 + 'px';
            food.style.top = this.setRandomPos(wrapH) * 20 + 'px';
            wrap.appendChild(food);
        },
        setRandomPos: function (size) {
            return Math.floor(Math.random() * (size / 20))
        },
        eatFood: function (arr) {
            var food = document.getElementsByClassName('food')[0],
                foodX = getStyles(food, 'left'),
                foodY = getStyles(food, 'top'),
                headX = arr[arr.length - 1].x,
                headY = arr[arr.length - 1].y,
                x,
                y;

            if (headX === foodX && headY === foodY) {
                this.removeFood();
                this.createFood();
                if (arr[0].x == arr[1].x) {
                    x = arr[0].x;
                    if (arr[0].y > arr[1].y) {
                        y = arr[0].y + 20;
                    } else if (arr[0].y < arr[1].y) {
                        y = arr[0].y - 20;
                    }

                } else if (arr[0].y === arr[1].y) {
                    y = arr[0].y;
                    if (arr[0].x > arr[1].x) {
                        x = arr[0].x + 20;
                    } else if (arr[0].x < arr[1].x) {
                        x = arr[0].x - 20;
                    }
                }
                arr.unshift({
                    x,
                    y
                })
            }
        },
        removeFood: function () {
            var food = document.getElementsByClassName('food')[0];
            food.remove();
        }
    }
    return new Snake().init();
});