20250805-40

js实在是太有趣了,昨天晚上花了两个多小时写了一个简易的贪吃蛇,逻辑并不难,今天做了Flappybird的小鸟的运动模块,明天继续研究研究

贪吃蛇练习代码如下

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body {
      color: #ffffff;
      font-size: 100px;
      font-weight: bolder;
      margin: 0;
      display: flex;
      min-height: 100vh;
      justify-content: center;
      align-items: center;
      background-color: #000000;
    }

    .grid {
      display: grid;
      /* gap: 2px; */
      width: auto;
      height: auto;
      background-color: #000000;
    }

    .cell {
      width: 30px;
      height: 30px;
      background-color: #ffffff;
    }
  </style>
</head>

<body>
  <script>
    gamebegin(25, 25)
    //游戏开始
    function gamebegin(row, col) {
      let snakecolor='green'
      let foodcolor='red'
      //储存所有网格
      let cells = []
      cells = creategrid(row, col)
      //储存蛇身
      let snake = []
      //随机网格选蛇头并推入snake数组尾部
      let head = randomint(0, row * col - 1)
      snake.push(head)
      cells[head].style.backgroundColor = snakecolor
      //初始化食物
      cells[randomint(0, row * col - 1)].style.backgroundColor = foodcolor
      //初始化方向
      let direct = 3
      //添加键盘事件
      document.addEventListener('keydown', function (e) {
        if (e.key === 'ArrowUp' && (direct != 1 || snake.length === 1))
          direct = 0
        if (e.key === 'ArrowDown' && (direct != 0 || snake.length === 1))
          direct = 1
        if (e.key === 'ArrowLeft' && (direct != 3 || snake.length === 1))
          direct = 2
        if (e.key === 'ArrowRight' && (direct != 2 || snake.length === 1))
          direct = 3
      })
      //定时处理方向位置的新蛇头
      let nexthead
      const move = setInterval(function () {
        switch (direct) {
          case 0://
            if (head < col)//边界处理,以下同上
              nexthead = head + col * (row - 1)
            else
              nexthead = head - col
            break;
          case 1://
            if (head >= col * (row - 1))
              nexthead = head - col * (row - 1)
            else
              nexthead = head + col
            break;
          case 2://
            if (head % col === 0)
              nexthead += col - 1
            else
              nexthead = head - 1
            break;
          case 3://
            if ((head + 1) % col === 0)
              nexthead -= col - 1
            else
              nexthead = head + 1
            break;
        }
        //先尾部判断是否下一步是食物,是则尾部停一步,用来加长蛇身
        if (cells[nexthead].style.backgroundColor != foodcolor) {
          cells[snake[0]].style.backgroundColor = '#ffffff'
          snake.shift()
        }
        //再头部判断是否会撞到自己蛇身
        if (cells[nexthead].style.backgroundColor != snakecolor) {
          snake.push(nexthead)
          //防止食物生成在蛇身所在位置(效率待优化)
          if (cells[nexthead].style.backgroundColor === foodcolor) {
            let randomindex = randomint(0, row * col - 1)
            while (snake.includes(randomindex))
              randomindex = randomint(0, row * col - 1)
            cells[randomindex].style.backgroundColor = foodcolor
          }
          //增加新蛇头
          cells[nexthead].style.backgroundColor = snakecolor
          head = nexthead
        } else
          //失败
          document.body.innerHTML = "YOU LOSE !"
        //检测是否霸屏,是则通关
        if (snake.length == row * col)
          document.body.innerHTML = "YOU WIN !"
      }, 200)
    }
    //生成网格
    function creategrid(row, col) {
      let cells = []
      const grid = document.createElement('div')
      grid.classList.add('grid')
      //定义网格的行列数
      grid.style.gridTemplateColumns = `repeat(${col},30px)`
      grid.style.gridTemplateRows = `repeat(${row},30px)`
      //将所有单元添加到网格
      for (let i = 0; i < row * col; i++) {
        const cell = document.createElement('div')
        cell.classList.add('cell')
        grid.appendChild(cell)
        cells.push(cell)
      }
      document.body.appendChild(grid)
      //返回所有网格
      return cells
    }
    //随机数函数
    function randomint(min, max) {
      min = Math.ceil(min);
      max = Math.floor(max);
      return Math.floor(Math.random() * (max - min + 1)) + min;
    }
  </script>
</body>

</html>

Flappybird练习代码如下

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body {
      margin: 0;
      display: flex;
      justify-content: center;
      height: 100vh;
      align-items: center;
    }

    .box {
      width: 1200px;
      height: 800px;
      background-color: #000;
      overflow: hidden;
      position: relative;
    }

    .bird {
      position: relative;
      transform: translate(-50%, -50%);
      top: 100px;
      left: 15%;
      width: 50px;
      height: 50px;
      background-color: #ff0000;
    }

    .pillar {
      background-color: chartreuse;
      width: 80px;
      position: absolute;
      left: 1200px;
      top: 0;
    }

    .show {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      color: white;
      font-size: 100px;
      font-weight: bolder;
    }
  </style>
</head>

<body>

  <script>
    //初始背景
    const box = document.createElement('div')
    box.classList.add('box')
    document.body.appendChild(box)
    //游戏开始
    gamebegin()
    //游戏开始函数
    function gamebegin() {
      //创建玩家
      const bird = createbird()
      //初始速度
      speed = 0;
      //计数器,用于后续平衡速度
      i = 0
      const birdtimer = setInterval(function () {
        i++
        //每五次计数增加下落速度,同时限制最大速度大小,避免加速度和速度过大
        if (i % 5 === 0 && speed <= 10)
          speed++
        let y = +bird.style.top.replace(/px/g, "")
        //防止飞出上边框
        if (y < 0) {
          y = 0
          speed = 0
        }
        bird.style.top = `${y += speed}px`
        //飞出下边框将导致游戏失败
        if (+bird.style.top.replace(/px/g, "") >= 800) {
          //失败函数
          fail()
          //清除计数器
          clearInterval(birdtimer)
          clearInterval(createpillar)
          clearInterval(pillarmove)
          clearInterval(crushcheck)
          //清除遗存柱子
          const ps = document.querySelectorAll('.pillar');
          for (let p of ps)
            p.remove();
        }
      }, 16)
      //键盘事件,空格飞升 
      document.addEventListener('keydown', function (e) {
        if (e.key === ' ')
          speed = -7//按下空格后速度变化为向上的 '7',达到飞升的效果
      })
      //定时创建柱子
      const createpillar = setInterval(function () {
        //同时创建上下两条
        const pillar1 = document.createElement('div')
        pillar1.classList.add('pillar')
        const pillar2 = document.createElement('div')
        pillar2.classList.add('pillar')
        //随机缺口位置,缺口大小固定为 200px
        let h1 = randomint(1, 5) * 100
        let h2 = 600 - h1
        pillar1.style.height = `${h1}px`
        pillar2.style.height = `${h2}px`
        pillar2.style.top = `${h1 + 200}px`
        //添加到界面
        box.appendChild(pillar1)
        box.appendChild(pillar2)
      }, 2000)
      //柱子移动
      const pillarmove = setInterval(function () {
        const pillars = document.querySelectorAll('.pillar')
        for (const pillar of pillars) {
          let x = +getComputedStyle(pillar).left.replace(/px/g, "")
          //柱子移出界面时移除,优化性能
          if (x < 0)
            pillar.remove()
          else {
            x -= 4
            pillar.style.left = `${x}px`
          }
        }
      }, 16)
    }
    //碰撞检测
    crushcheck = setInterval(function () {
      const pillars = document.querySelectorAll('.pillar');
      const birds = document.querySelectorAll('.bird');
      for (let pillar of pillars) {
        const p = pillar.getBoundingClientRect();
        for (let bird of birds) {
          const b = bird.getBoundingClientRect();
          if (b.left < p.right && b.right > p.left && b.top < p.bottom && b.bottom > p.top) {
            fail();
            clearInterval(birdtimer);
            clearInterval(createpillar);
            clearInterval(pillarmove);
            clearInterval(crushcheck);
            const ps = document.querySelectorAll('.pillar');
            for (let p of ps)
              p.remove();
          }
        }
      }
    }, 16);
    //创建玩家函数
    function createbird() {
      const bird = document.createElement('div')
      bird.classList.add('bird')
      box.appendChild(bird)
      return bird
    }
    //失败函数
    function fail() {
      box.innerHTML = ''
      const show = document.createElement('div')
      show.classList.add('show')
      show.innerHTML = "YOU FAILED"
      box.appendChild(show)
    }
    //随机整数函数
    function randomint(min, max) {
      min = Math.ceil(min);
      max = Math.floor(max);
      return Math.floor(Math.random() * (max - min + 1)) + min;
    }
  </script>
</body>

</html>

 

posted @ 2025-08-05 23:13  Lee_sz  阅读(6)  评论(1)    收藏  举报