纯原生JS面向对象构造函数方法实现贪吃蛇小游戏

Posted 我是真的不会前端

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了纯原生JS面向对象构造函数方法实现贪吃蛇小游戏相关的知识,希望对你有一定的参考价值。

Demo介绍

用prototype构造函数写的贪吃蛇。直接复制代码到html文件就可以运行。学任何一门语言 练习逻辑都会写个贪吃蛇啥的,这不来了嘛
这个demo通过几个方法基本无HTML和css完全动态生成界面元素。基本注释都在代码中

源码

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>document</title>
</head>

<body>
    <button>开始</button>
</body>
<script>
    // 地图
    function Map() {
        // 创建一个div
        this.map = document.createElement('div')
        this.setStyle(this.map, {
            width: "700px",
            height: '500px',
            border: "10px solid #ccc",
            backgroundColor: "#abcdef",
            position: "relative"
        })
        // 将div放到body中
        document.body.appendChild(this.map)
    }
    // 添加一个设置样式的函数
    Map.prototype.setStyle = function (ele, styleObj) {
        for (var attr in styleObj) {
            ele.style[attr] = styleObj[attr]
        }
    }
    // 添加一个获取随机数的方法
    Map.prototype.getRandom = function (a, b = 0) {
        var max = Math.max(a, b);
        var min = Math.min(a, b)
        return Math.floor(Math.random() * (max - min)) + min
    }

    var m = new Map()
    // 食物
    function Food() {
        // 创建一个小div
        this.food = document.createElement('div')
        m.setStyle(this.food, {
            width: "10px",
            height: "10px",
            backgroundColor: "blue",
            position: "absolute",
            left: parseInt(m.getRandom(m.map.clientWidth - 10) / 10) * 10 + 'px',
            top: parseInt(m.getRandom(m.map.clientHeight - 10) / 10) * 10 + 'px',
        })
        // 放到地图中
        m.map.appendChild(this.food)
    }

    var f = new Food()
    // 蛇
    function Snake() {
        // 属性
        // 身体
        this.body = [
            {
                x: 0,
                y: 0
            },
            {
                x: 10,
                y: 0
            },
            {
                x: 20,
                y: 0
            },
            {
                x: 30,
                y: 0
            },
            {
                x: 40,
                y: 0
            },
            {
                x: 50,
                y: 0
            }
        ]

        this.direction = 'right'
        this.timer = null

        // 让蛇显示的方法
        this.show()
        // 改变蛇移动的方向方法
        this.changeDirection()

    }
    // 初始化方法
    Snake.prototype.init = function () {
        // 移动方法
        this.timer = setInterval(() => {
            this.move()
        }, 100)
    }
    // 蛇移动的方法
    Snake.prototype.move = function () {
        // 根据方向移动
        // 先移动除了蛇头的其他身体
        for (var i = 0; i < this.body.length - 1; i++) { // 少循环一次,把蛇头排除了
            // 注意:这里是复杂数据类型赋值,赋的是地址
            // this.body[i] = this.body[i+1]

            this.body[i].x = this.body[i + 1].x
            this.body[i].y = this.body[i + 1].y
        }
        // 根据方向改变蛇头
        switch (this.direction) {
            case 'right':
                this.body[this.body.length - 1].x += 10
                break;
            case 'left':
                this.body[this.body.length - 1].x -= 10;
                break;
            case 'up':
                this.body[this.body.length - 1].y -= 10
                break;
            case 'down':
                this.body[this.body.length - 1].y += 10
                break;
        }
        this.show()

        // 检测是否迟到食物
        this.eat()
        // 检测是否死亡
        this.die()
    }
    // 蛇死亡的方法
    Snake.prototype.die = function () {
        // 撞墙
        if (this.body[this.body.length - 1].x < 0 || this.body[this.body.length - 1].y < 0 || this.body[this.body.length - 1].x > m.map.clientWidth - 10 || this.body[this.body.length - 1].y > m.map.clientHeight - 10) {
            clearInterval(this.timer)
            if (confirm("GAME OVER, 是否重玩?")) {
                location.reload();
            }
        }
        // 撞自己身体
        for (var i = 0; i < this.body.length - 1; i++) {
            if (this.body[i].x === this.body[this.body.length - 1].x && this.body[i].y === this.body[this.body.length - 1].y) {
                clearInterval(this.timer)
                if (confirm("GAME OVER, 是否重玩?")) {
                    location.reload();
                }
                break;
            }
        }
    }
    // 蛇吃食物的方法
    Snake.prototype.eat = function () {
        // 蛇头和食物的坐标重合就是吃到了
        if (this.body[this.body.length - 1].x === f.food.offsetLeft && this.body[this.body.length - 1].y === f.food.offsetTop) {
            // 从开头添加一节身体
            this.body.unshift({
                x: this.body[0].x,
                y: this.body[0].y
            })
            // 让食物删除并重新创建食物
            m.map.removeChild(f.food)
            // 重新创建食物
            f = new Food()
        }
    }
    // 改变移动方向
    Snake.prototype.changeDirection = function () {
        document.onkeydown = e => {
            var e = e || window.event;
            var keycode = e.keyCode || e.which;
            // console.log(keycode);
            var keyword = String.fromCharCode(keycode).toLowerCase()
            switch (keyword) {
                case 'a':
                    this.direction = 'left';
                    break;
                case 'd':
                    this.direction = 'right';
                    break;
                case 'w':
                    this.direction = 'up';
                    break;
                case 's':
                    this.direction = 'down';
                    break;
            }

        }
    }
    // 让蛇显示的方法
    Snake.prototype.show = function () {
        // 先删除原来的身体再显示新的身体
        var snakes = document.querySelectorAll('.snake')
        if (snakes.length) {
            for (var i = 0; i < snakes.length; i++) {
                m.map.removeChild(snakes[i])
            }
        }

        // 根据身体数组创建div,设置坐标
        for (var i = 0; i < this.body.length; i++) {
            var div = document.createElement('div')
            div.className = 'snake'
            m.setStyle(div, {
                width: "10px",
                height: "10px",
                backgroundColor: "#fff",
                position: "absolute",
                left: this.body[i].x + "px",
                top: this.body[i].y + "px"
            })
            // 放到地图中
            m.map.appendChild(div)
            if (i === this.body.length - 1) {
                m.setStyle(div, {
                    backgroundColor: "red",
                    borderRadius: "50%"
                })
            }
        }
    }

    var s = new Snake()

    document.querySelector('button').onclick = function () {
        s.init()
    }
</script>

</html>

运行截图

在这里插入图片描述

需要改进的地方

应该在进行一个方向时禁用对向方向按键。
可以设置计分系统和其他难度系统
UI! UI! ui确实太丑了哈哈

其他demo

1.js打字小游戏(面向对象)
2.js扫雷小游戏(面向对象)
3.js打砖块小游戏(面向过程)

以上是关于纯原生JS面向对象构造函数方法实现贪吃蛇小游戏的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript面向对象游戏案例:贪吃蛇

JS学习——贪吃蛇代码(简易版)

JS学习——贪吃蛇代码(简易版)

点击领取专属小蛇~JS贪吃蛇来咯

11 贪吃蛇小游戏 js版本 + vue版本

11 贪吃蛇小游戏 js版本 + vue版本