使用H5+CSS+JS实现贪吃蛇小游戏

看了超哥的课后总结贪吃蛇的布局及实现。

大部分代码标注了注释,欢迎大家一起探讨。

一、思路分析:

1、移动时:

    首先判断用户的按键是否为你规定的上下左右;
    根据当前蛇头位置的x,y的位置,得到将要移动到的x,y的位置;
    蛇的每一次移动是将蛇尾放到将要移动到的x,y位置上,而不是移动所有的div;

    蛇不能掉头,通过在每一次的定时器内只能进行一次更改方向实现。

2、吃食物后:

    判断蛇头是否和随机生成的食物的x,y位置相同,相同则视为吃到食物;
    蛇需要生成一个新的div;
    食物需要再次随机一个x,y并移动;
    加分数,判断是否加等级。

3、游戏结束:

    蛇不能撞到四边的边框;
    蛇不能撞到自己,遍历整个蛇的div,判断蛇头下次移动的x,y是否和当前的div重合;注意:不需要判断第一个和最后一个div,因为不会碰到。

二、H5部分:

    <div id="main">
        <div id="stage">
            <div id="snake">
                <div></div>
            </div>

            <div id="food">
                <div></div>
                <div></div>
                <div></div>
                <div></div>
            </div>
        </div>

        <div id="info">
            <div>SCORE:<span id="score">0</span></div>
            <div>LEVEL:<span id="level">1</span></div>
        </div>
    </div>

三、CSS样式:

    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        #main {
            height: 420px;
            width: 360px;
            border: 10px #000 solid;
            background-color: #b7d4a8;
            border-radius: 20px;
            margin: 50px auto;
        }

        #stage {
            width: 304px;
            height: 304px;
            border: 2px solid #000;
            margin: 20px auto;
            position: relative;
        }

        #snake>div {
            width: 10px;
            height: 10px;
            background-color: #000;
            position: absolute;
            border: 1px solid #b7d4a8;
        }

        #food {
            width: 10px;
            height: 10px;
            position: absolute;
            top: 100px;
            left: 120px;
            display: flex;
            flex-flow: wrap;
        }

        #food>div {
            width: 5px;
            height: 5px;
            background-color: #000;
            transform: rotate(45deg);
        }

        #info {
            width: 304px;
            margin: 0px auto;
            display: flex;
            justify-content: space-between;
            font: bold 20px courier;
        }
    </style>

四、JS代码:

    <script>
        const scoreSpan = document.getElementById("score");
        const levelSpan = document.getElementById("level");
        const snake = document.getElementById("snake");
        const snakes = snake.getElementsByTagName("div");
        //存放上下左右按键
        const keyArr = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"];
        //根据reObj判断蛇掉头
        const reObj = {
            ArrowUp: "ArrowDown",
            ArrowDown: "ArrowUp",
            ArrowLeft: "ArrowRight",
            ArrowRight: "ArrowLeft"
        }
        const food = document.getElementById("food")
        //定义更改方向
        let dir;
        //在一次定时器内只能改变一次方向开关
        let keyActive = true;
        let score = 0;
        let level = 0;
        //键盘事件
        document.addEventListener("keydown", (event) => {
            if (keyActive && keyArr.indexOf(event.key) !== -1) {
                if (snakes.length < 2 || reObj[dir] !== event.key) {
                    dir = event.key;
                    keyActive = false;
                }
            }
        })

        //根据边框大小,随机生成食物坐标
        function changeFood() {
            //食物的坐标应该在x:0-290 y:0-290
            const x = Math.floor(Math.random() * 30) * 10
            const y = Math.floor(Math.random() * 30) * 10

            //设置食物坐标
            food.style.left = x + "px";
            food.style.top = y + "px";
        }
        changeFood();

        //定时器获取蛇的位置
        setTimeout(function move() {
            keyActive = true;
            const snakeHead = snakes[0];
            //获取当前蛇头的x,y坐标
            let x = snakeHead.offsetLeft
            let y = snakeHead.offsetTop
            //根据按键修改x,y坐标
            switch (dir) {
                case "ArrowUp":
                    y -= 10
                    break;
                case "ArrowDown":
                    y += 10
                    break;
                case "ArrowLeft":
                    x -= 10
                    break;
                case "ArrowRight":
                    x += 10
                    break;
            }

            //判断游戏是否结束
            //判断是否撞墙
            if (x < 0 || x > 290 || y < 0 || y > 290) {
                alert("游戏结束")
                return;
            }
            //判断是否撞到自己
            for (let i = 1; i < snakes.length - 1; i++) {
                if (snakes[i].offsetLeft === x && snakes[i].offsetTop === y) {
                    alert("游戏结束")
                    return;
                }
            }

            //检查蛇是否吃到食物 
            if (snakeHead.offsetTop === food.offsetTop && snakeHead.offsetLeft === food.offsetLeft) {
                changeFood();
                const div = document.createElement("div")
                snake.appendChild(div);
                //加分
                score++;
                scoreSpan.textContent = score;
                //加等级
                if (score % 6 === 0 && level < 14) {
                    level++;
                    levelSpan.textContent = level + 1;
                }
            }
            //获取蛇的尾巴
            const snakeTail = snakes[snakes.length - 1]
            //移动蛇的位置
            snakeTail.style.left = x + "px"
            snakeTail.style.top = y + "px"
            //将蛇头的位置换成蛇尾
            snake.insertAdjacentElement("afterbegin", snakeTail)

            setTimeout(move, 300 - (level * 20))
        }, 300)
    </script>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值