抖音上情侣玩的小游戏--炸飞机 单身狗 没朋友也能玩 附HTML源码

一样 先上图

在这里插入图片描述
在这里插入图片描述
源码附上
可优化的地方还有很多,懒得写了 有兴趣可以帮忙改改

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="row-UA-Compatible" content="IE=edge" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, target-densitydpi=device-dpi"
    />

    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      body {
        padding: 10px;
      }
      .container {
        max-width: 600px;
        width: 90vw;
        margin: auto;
        margin-top: 10px;
        font-size: 0;
      }
      .container span {
        display: inline-block;
        max-width: 60px;
        max-height: 60px;
        width: 9vw;
        height: 9vw;
        background: #a3a3a3;
        border: 2px solid #fefbf3;
        box-sizing: border-box;
        position: relative;
      }
      .container span.plan {
        background-color: #4dac4d;
      }
      .container span.plan-head {
        background-color: #e04444;
      }
      .container span::after {
        content: '';
        display: block;
        width: 100%;
        height: 100%;
        position: absolute;
        left: 0;
        top: 0;
        z-index: 999;
        background-color: #79b4b7;
      }
      .container span.nomask::after {
        content: none;
      }
      button {
        font-size: 14px;
        color: #000;
        background-color: rgb(187, 245, 237);
        outline: unset;
        border: 1px solid #ccc;
        padding: 6px 15px;
        border-radius: 4px;
        margin-bottom: 10px;
      }
    </style>
  </head>
  <body>
    <header>
      <h2 style="text-align: center; line-height: 50px;">炸飞机</h2>
      <h4 style="text-align: center; line-height: 20px;">
        <button onclick="init()">重新开始</button><br />
        <span
          >您已发射<span id="shotedNum">0</span>颗导弹,累计击毁<span
            id="successShotNum"
            >0</span
          >架飞机</span
        ><br />
        <span style="color: rgb(209, 209, 209); font-size: 12px;"
          >tips:灰色表示空,绿色表示机身,红色表示机头,命中机头则飞机被击落。</span
        >
      </h4>
    </header>
    <div class="container" onclick="handleClick()"></div>
    <!-- 可以再手机浏览器调试代码 可以排错,一般用于排查手机端兼容性问题 -->
    <!-- <script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
    <script>
      var vConsole = new window.VConsole()
    </script> -->
    <script>
      let shoted = 0
      const setShoted = num => {
        shoted = num !== undefined ? num : shoted + 1
        document.getElementById('shotedNum').innerText = shoted
      }
      let successShot = 0
      const setSuccessShot = num => {
        successShot = num !== undefined ? num : successShot + 1
        document.getElementById('successShotNum').innerText = successShot
      }
      // 生成[m,n]的随机数
      const rangeRandom = (m, n) => {
        const mun = ~~(Math.random() * (n - m + 1) + m)
        return mun
      }
      // 不同朝向的飞机所对应的机头的横纵坐标的范围
      const planeHeadRangeMap = {
        top: {
          row: [0, 6],
          col: [2, 7]
        },
        left: {
          row: [2, 7],
          col: [0, 6]
        },
        bottom: {
          row: [3, 9],
          col: [2, 7]
        },
        right: {
          row: [2, 7],
          col: [3, 9]
        }
      }
      const handleClick = () => {
        var e = e || window.event
        if (
          e.target.nodeName !== 'SPAN' ||
          e.target.classList.contains('nomask')
        ) {
          return
        }
        setShoted()
        e.target.classList.add('nomask')
        // 如果击中飞机头部
        const { row, col } = e.target.dataset
        if (map[~~row][~~col] === 2) {
          setSuccessShot()
          if (successShot === 3) {
            confirm('恭喜你 所有日本鬼子的飞机都被炸碎了,再来一局吧') && init()
          }
        }
      }
      let map
      let pointList = []
      const addClass = (row, col) => {
        const rowEl = document.querySelectorAll('p')[row]
        const spanEl = rowEl.children[col].classList.add('plan')
      }
      const canGeneratePlan = (row, col, direction) => {
        switch (direction) {
          case 'top':
            pointList = [
              [row, col],
              [row + 1, col - 2],
              [row + 1, col - 1],
              [row + 1, col],
              [row + 1, col + 1],
              [row + 1, col + 2],
              [row + 2, col],
              [row + 3, col - 1],
              [row + 3, col],
              [row + 3, col + 1]
            ]
            break
          case 'left':
            pointList = [
              [row, col],
              [row - 2, col + 1],
              [row - 1, col + 1],
              [row, col + 1],
              [row + 1, col + 1],
              [row + 2, col + 1],
              [row, col + 2],
              [row - 1, col + 3],
              [row, col + 3],
              [row + 1, col + 3]
            ]
            break
          case 'bottom':
            pointList = [
              [row, col],
              [row - 1, col - 2],
              [row - 1, col - 1],
              [row - 1, col],
              [row - 1, col + 1],
              [row - 1, col + 2],
              [row - 2, col],
              [row - 3, col - 1],
              [row - 3, col],
              [row - 3, col + 1]
            ]
            break
          case 'right':
            pointList = [
              [row, col],
              [row - 2, col - 1],
              [row - 1, col - 1],
              [row, col - 1],
              [row + 1, col - 1],
              [row + 2, col - 1],
              [row, col - 2],
              [row - 1, col - 3],
              [row, col - 3],
              [row + 1, col - 3]
            ]
            break
        }
        const isbeizhan = pointList.find(i => {
          let rowNum = i[0]
          let colNum = i[1]
          return map[rowNum][colNum] !== 0
        })
        return !isbeizhan
      }
      const drawPlan = (row, col) => {
        map[row][col] = 2
        const rowEl = document.querySelectorAll('p')[row]
        const spanEl = rowEl.children[col].classList.add('plan-head')
        pointList.map(i => {
          const row = i[0]
          const col = i[1]
          map[row][col] = map[row][col] ? map[row][col] : 1
          addClass(row, col)
        })
      }
      let planNum = 0
      const generatPlan = num => {
        while (planNum < num) {
          // 随机飞机方向
          const directionList = ['top', 'bottom', 'left', 'right']
          const direction = directionList[~~(Math.random() * 4)]

          // 获取机头的坐标范围
          const { row: rowRange, col: colRange } = planeHeadRangeMap[direction]

          // 随机生成机头位置
          const row = rangeRandom(...rowRange)
          const col = rangeRandom(...colRange)

          // 如果放置飞机的位置没有被占用,则生成飞机
          if (canGeneratePlan(row, col, direction)) {
            drawPlan(row, col)
            planNum++
          }
        }
      }
      const initExcel = () => {
        // 生成 span 标签表示 10 * 10 的格子
        const frag = document.createDocumentFragment()
        for (let i = 0; i < 10; i++) {
          const p = document.createElement('p')
          for (let j = 0; j < 10; j++) {
            const span = document.createElement('span')
            span.setAttribute('data-row', i)
            span.setAttribute('data-col', j)
            p.appendChild(span)
          }
          frag.appendChild(p)
        }
        document.querySelector('.container').innerHTML = ''
        document.querySelector('.container').appendChild(frag)
      }
      const initMap = () => {
        // 生成 10 * 10 的二位数字 值都为0
        map = JSON.parse(JSON.stringify(Array.from(new Array(10).fill(new Array(10).fill(0)))))
      }
      const init = () => {
        setShoted(0)
        setSuccessShot(0)
        planNum = 0
        initExcel()
        initMap()
        generatPlan(3)
      }
      init()
    </script>
  </body>
</html>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值