疫情在家游戏玩腻了?那就一起来开发H5小游戏吧

前提:游戏玩腻了?作为一名合格的程序员,应该自己开发小游戏来玩,玩腻了,自己就再去开发个游戏,利用这一特点实现永动机。既可以学习,也可以娱乐。
在这里插入图片描述
本次开发的是贪吃蛇小游戏。使用技术:html、css、原生js、部分es6语法

贪吃蛇实现原理:利用绝对定位的left和top来小蛇进行移动

开发游戏的思路:

  1. 首先在页面上放一个大的盒子(box),加上border,相当于一个围栏。这个大盒子就是游戏区域。
  2. 在box中,又四个盒子,2个body盒子作为蛇的身体(初始长度为2),snake作为蛇头部,food作为食物。
  3. 将蛇的身体的第一段放在left:0;right:0这个位置,第二段向右偏移50px(因为蛇的一段身体的宽高是50*50),蛇的头部向右偏移100px。这就是蛇的初始位置。
  4. 蛇的移动:我们要知道,蛇的身体是跟着蛇的方向来移动的。我们可以通过移动蛇头,然后利用循环或者递归来使蛇的一段段身体来移动(就是第一段身体移动到蛇头的位置,第二段身体移动到第一段身体的位置),为了防止蛇的身体和头部的位置重叠,我们就从最后一段开始移动,而不是使蛇头先移动。
  5. 食物的随机出现:因为我蛇每次移动都是50px,所以食物的left和top位置都是50的倍数(0-1000中),Math.floor(Math.random() * 20) * 50就是取50的倍数,范围是0-1000.
  6. 判断蛇有没有撞到身体或者吃到食物或者撞到墙:就利用蛇头的left和top跟他们比较,如果相等就撞到获取吃到食物。
  7. 自动移动:利用时间间隔函数。
  8. 其他的功能:代码注释都有详细说明,如果还有不懂的可以评论或者私信我!
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        .box {
            position: relative;
            width: 1000px;
            height: 1000px;
            margin: 50px auto;
            border: 1px solid red;
        }

        .snake {
            position: absolute;
            width: 50px;
            height: 50px;
            background-color: red;
        }

        .food {
            position: absolute;
            top: 100px;
            left: 100px;
            width: 50px;
            height: 50px;
            background-color: pink;
        }

        .body {
            position: absolute;
            top: 0;
            left: 0;
            width: 50px;
            height: 50px;
            background-color: green;
        }
    </style>
</head>

<body>
    <div class="box">
        <div class="body"></div>
        <!--由于two的style样式使用dom.style获取不到,就写到了行内样式中-->
        <div class="body" id="two" style="top:0px;left:50px"></div>
        <div class="snake"></div>
        <div class="food"></div>
    </div>
</body>
<script src="./贪吃蛇.js"></script>

</html>
class Snake {
    constructor() {
        this.snake = document.querySelector('.snake')
        this.food = document.querySelector('.food')
        this.bodys = document.querySelectorAll('.body')
        this.top = 0
        this.left = 100
        this.lastTop = '' //记录蛇身体最后一段的top
        this.lastLeft = '' //记录蛇身体最后一段的left
        this.lastBody = null //蛇的最后一段,没吃到食物为null
        this.snakeMoveByAuto = null
        this.init()
    }
    // 初始化
    init () {
        this.snake.style.top = this.top + 'px'
        this.snake.style.left = this.left + 'px'
        this.foodAppearByRandom()
        // 监听键盘的事件
        document.querySelector('body').onkeydown = (e) => {
            clearInterval(this.snakeMoveByAuto)
            switch (e.keyCode) {
                case 87:  //w键
                    this.snakeMoveByAuto = setInterval(() => this.snakeMove(-50, 0), 500)
                    break;
                case 65: // a键
                    this.snakeMoveByAuto = setInterval(() => this.snakeMove(0, -50), 500)
                    break;
                case 83:  // s键
                    this.snakeMoveByAuto = setInterval(() => this.snakeMove(50, 0), 500)
                    break;
                case 68: // d键
                    this.snakeMoveByAuto = setInterval(() => this.snakeMove(0, 50), 500)
                    break;
            }
        }
    }
    // 食物随机出现
    foodAppearByRandom () {
        let length = this.bodys.length
        this.food.style.top = Math.floor(Math.random() * 20) * 50 + 'px'
        this.food.style.left = Math.floor(Math.random() * 20) * 50 + 'px'
        // 防止食物刷新在同一位置
        if (this.snake.style.top === this.food.style.top && this.snake.style.left === this.food.style.left) {
            this.foodAppearByRandom()
        }
        // 防止食物刷新在蛇身上
        for (var i = 0; i < length; i++) {
            if (this.food.style.top === this.bodys[i].style.top && this.food.style.left === this.bodys[i].style.left) {
                this.foodAppearByRandom()
            }
        }
    }
    // 移动蛇位置
    snakeMove (top, left) {
        let newTop = parseInt(this.snake.style.top.slice(0, -2)) + top
        let newLeft = parseInt(this.snake.style.left.slice(0, -2)) + left
        let length = this.bodys.length

        // 阻止蛇走出方框
        // 因为盒子的宽高是50px,就各自减50
        if (newTop < 0 || newTop > 950 || newLeft < 0 || newLeft > 950) {
            clearInterval(this.snakeMoveByAuto)
            alert('gg')
            window.location.reload()
            return
        }


        // 让蛇身体后一个跟着前一个移动
        for (var i = 0; i < length - 1; i++) {
            console.log(this.bodys[i + 1].style.left)
            this.bodys[i].style.left = this.bodys[i + 1].style.left
            this.bodys[i].style.top = this.bodys[i + 1].style.top
        }

        // 让蛇身体的最后部分跟着蛇的头移动
        this.bodys[length - 1].style.top = this.snake.style.top
        this.bodys[length - 1].style.left = this.snake.style.left


        // 让蛇的头部移动
        this.snake.style.top = newTop + 'px'
        this.snake.style.left = newLeft + 'px'


        // 蛇吃到食物
        if (this.snake.style.top === this.food.style.top && this.snake.style.left === this.food.style.left) {
            this.lastTop = this.bodys[0].style.top
            this.lastLeft = this.bodys[0].style.left
            this.foodAppearByRandom()
            this.snakeChangeBig()
        }

        // 循环判断蛇有没有撞到自己的身体
        for (var i = 0; i < length; i++) {
            if (this.snake.style.top === this.bodys[i].style.top && this.snake.style.left === this.bodys[i].style.left) {
                clearInterval(this.snakeMoveByAuto)
                alert('gg')
                window.location.reload()
            }
        }
    }
    // 蛇吃到食物变大
    snakeChangeBig () {
        // 创建蛇身体最后一段
        this.lastBody = document.createElement('div')
        this.lastBody.className = 'body'
        this.lastBody.style.top = this.lastTop
        this.lastBody.style.left = this.lastLeft
        document.querySelector('.box').prepend(this.lastBody)
        // 因为添加了蛇的最后一段,所以要更新this.bodys
        this.bodys = document.querySelectorAll('.body')
    }
}

var snake = new Snake()

游戏操作:使用键盘的wasd来控制方向。
GitHub项目:https://github.com/wa545464/H5-

小白运行教程:
创建一个html文件,html文件内容如下,然后用浏览器打开该html文件:

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        .box {
            position: relative;
            width: 1000px;
            height: 1000px;
            margin: 50px auto;
            border: 1px solid red;
        }

        .snake {
            position: absolute;
            width: 50px;
            height: 50px;
            background-color: red;
        }

        .food {
            position: absolute;
            top: 100px;
            left: 100px;
            width: 50px;
            height: 50px;
            background-color: pink;
        }

        .body {
            position: absolute;
            top: 0;
            left: 0;
            width: 50px;
            height: 50px;
            background-color: green;
        }
    </style>
</head>

<body>
    <div class="box">
        <div class="body"></div>
        <!--由于two的style样式使用dom.style获取不到,就写到了行内样式中-->
        <div class="body" id="two" style="top:0px;left:50px"></div>
        <div class="snake"></div>
        <div class="food"></div>
    </div>
</body>
<script>
class Snake {
    constructor() {
        this.snake = document.querySelector('.snake')
        this.food = document.querySelector('.food')
        this.bodys = document.querySelectorAll('.body')
        this.top = 0
        this.left = 100
        this.lastTop = '' //记录蛇身体最后一段的top
        this.lastLeft = '' //记录蛇身体最后一段的left
        this.lastBody = null //蛇的最后一段,没吃到食物为null
        this.snakeMoveByAuto = null
        this.init()
    }
    // 初始化
    init () {
        this.snake.style.top = this.top + 'px'
        this.snake.style.left = this.left + 'px'
        this.foodAppearByRandom()
        // 监听键盘的事件
        document.querySelector('body').onkeydown = (e) => {
            clearInterval(this.snakeMoveByAuto)
            switch (e.keyCode) {
                case 87:  //w键
                    this.snakeMoveByAuto = setInterval(() => this.snakeMove(-50, 0), 500)
                    break;
                case 65: // a键
                    this.snakeMoveByAuto = setInterval(() => this.snakeMove(0, -50), 500)
                    break;
                case 83:  // s键
                    this.snakeMoveByAuto = setInterval(() => this.snakeMove(50, 0), 500)
                    break;
                case 68: // d键
                    this.snakeMoveByAuto = setInterval(() => this.snakeMove(0, 50), 500)
                    break;
            }
        }
    }
    // 食物随机出现
    foodAppearByRandom () {
        let length = this.bodys.length
        this.food.style.top = Math.floor(Math.random() * 20) * 50 + 'px'
        this.food.style.left = Math.floor(Math.random() * 20) * 50 + 'px'
        // 防止食物刷新在同一位置
        if (this.snake.style.top === this.food.style.top && this.snake.style.left === this.food.style.left) {
            this.foodAppearByRandom()
        }
        // 防止食物刷新在蛇身上
        for (var i = 0; i < length; i++) {
            if (this.food.style.top === this.bodys[i].style.top && this.food.style.left === this.bodys[i].style.left) {
                this.foodAppearByRandom()
            }
        }
    }
    // 移动蛇位置
    snakeMove (top, left) {
        let newTop = parseInt(this.snake.style.top.slice(0, -2)) + top
        let newLeft = parseInt(this.snake.style.left.slice(0, -2)) + left
        let length = this.bodys.length

        // 阻止蛇走出方框
        // 因为盒子的宽高是50px,就各自减50
        if (newTop < 0 || newTop > 950 || newLeft < 0 || newLeft > 950) {
            clearInterval(this.snakeMoveByAuto)
            alert('gg')
            window.location.reload()
            return
        }


        // 让蛇身体后一个跟着前一个移动
        for (var i = 0; i < length - 1; i++) {
            console.log(this.bodys[i + 1].style.left)
            this.bodys[i].style.left = this.bodys[i + 1].style.left
            this.bodys[i].style.top = this.bodys[i + 1].style.top
        }

        // 让蛇身体的最后部分跟着蛇的头移动
        this.bodys[length - 1].style.top = this.snake.style.top
        this.bodys[length - 1].style.left = this.snake.style.left


        // 让蛇的头部移动
        this.snake.style.top = newTop + 'px'
        this.snake.style.left = newLeft + 'px'


        // 蛇吃到食物
        if (this.snake.style.top === this.food.style.top && this.snake.style.left === this.food.style.left) {
            this.lastTop = this.bodys[0].style.top
            this.lastLeft = this.bodys[0].style.left
            this.foodAppearByRandom()
            this.snakeChangeBig()
        }

        // 循环判断蛇有没有撞到自己的身体
        for (var i = 0; i < length; i++) {
            if (this.snake.style.top === this.bodys[i].style.top && this.snake.style.left === this.bodys[i].style.left) {
                clearInterval(this.snakeMoveByAuto)
                alert('gg')
                window.location.reload()
            }
        }
    }
    // 蛇吃到食物变大
    snakeChangeBig () {
        // 创建蛇身体最后一段
        this.lastBody = document.createElement('div')
        this.lastBody.className = 'body'
        this.lastBody.style.top = this.lastTop
        this.lastBody.style.left = this.lastLeft
        document.querySelector('.box').prepend(this.lastBody)
        // 因为添加了蛇的最后一段,所以要更新this.bodys
        this.bodys = document.querySelectorAll('.body')
    }
}

var snake = new Snake()
</script>

</html>
  • 370
    点赞
  • 1501
    收藏
    觉得还不错? 一键收藏
  • 108
    评论
评论 108
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值