• canvas实现类似吃鸡游戏中的缩圈效果
  • 发布于 2个月前
  • 230 热度
    0 评论
什么是“缩圈”

吃鸡类型游戏中,为了增加游戏的紧张感和刺激感,通常会设置一个“缩圈”的机制。每隔一段时间,游戏地图上的安全区域会逐渐缩小,只有在安全区内的玩家才能保证自身的健康值。玩家需要根据小地图上的圆形范围来判断自己是否在安全区内,以避免被淘汰。本文将介绍如何通过代码实现吃鸡游戏中的小地图缩圈效果。


效果展示

代码实现
1. 创建一个 canvas 元素
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>吃鸡游戏小地图缩圈效果 -堆代码 www.duidaima.com</title>
    <style>
      canvas {
        background-color: #161823;
      }
    </style>
  </head>
  <body>
    <canvas id="canvas" width="400" height="400"></canvas>
  </body>
</html>
2. 初始化 Canvas
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
3. 分析动画效果
缩圈效果可以拆分为两步:
1.大圈的半径逐渐缩小到和小圈相等
2.大圈的圆心逐渐往小圈的方向移动

因此,我们需要定义两个圆:
onst bigCircle = {
    x: 200,
    y: 200,
    radius: 100
}

const smallCircle = {
    x: 220,
    y: 240,
    radius: 40
}
以及缩圈的时间:
// 缩圈时间(单位:秒)
const DURATION = 5
接下来,我们需要实现缩圈效果:
let startTime // 动画开始时间

function draw(currentTime) {
    // 堆代码 duidaima.com
    // 如果动画开始时间戳未定义,则设置为当前时间戳
    if (!startTime) {
      startTime = currentTime
    }

    // 计算动画进度百分比
    const progress = (currentTime - startTime) / 1000 / DURATION // 除以1000将毫秒转换为秒

    // 如果动画未完成,则继续动画
    if (progress < 1) {
      // 计算当前点的位置
      const currentPoint = {
        x: bigCircle.x + (smallCircle.x - bigCircle.x) * progress,
        y: bigCircle.y + (smallCircle.y - bigCircle.y) * progress
      }

      const currentRadius = bigCircle.radius + (smallCircle.radius - bigCircle.radius) * progress

      // 清除画布并绘制圆形
      ctx.clearRect(0, 0, canvas.width, canvas.height)
      // 绘制大圆
      ctx.beginPath()
      ctx.arc(currentPoint.x, currentPoint.y, currentRadius, 0, Math.PI * 2)
      ctx.strokeStyle = '#00f'
      ctx.stroke()
      // 绘制小圆
      ctx.beginPath()
      ctx.arc(smallCircle.x, smallCircle.y, smallCircle.radius, 0, Math.PI * 2)
      ctx.strokeStyle = '#000'
      ctx.stroke()

      // 继续动画
      requestAnimationFrame(draw)
    }
}

requestAnimationFrame(draw)
最后,我们将所有代码整合起来:(以下代码复制到记事本存储为.html格式可以直接用浏览器查看效果)
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>堆代码 duidaima.com</title>
    <style>
      canvas {
        border: 1px solid #000;
      }
    </style>
  </head>
  <body>
    <canvas id="canvas" width="400" height="400"></canvas>
    <script>
      const canvas = document.getElementById('canvas')
      const ctx = canvas.getContext('2d')

      // 当前安全区(大圈)
      const bigCircle = {
        x: 200,
        y: 200,
        radius: 100
      }

      // 下一个安全区(小圈)
      const smallCircle = {
        x: 220,
        y: 240,
        radius: 40
      }

      // 缩圈时间(单位:秒)
      const DURATION = 5

      let startTime // 动画开始时间

      function draw(currentTime) {
        // 如果动画开始时间戳未定义,则设置为当前时间戳
        if (!startTime) {
          startTime = currentTime
        }

        // 计算动画进度百分比
        const progress = (currentTime - startTime) / 1000 / DURATION // 除以1000将毫秒转换为秒

        // 如果动画未完成,则继续动画
        if (progress < 1) {
          // 计算当前点的位置
          const currentPoint = {
            x: bigCircle.x + (smallCircle.x - bigCircle.x) * progress,
            y: bigCircle.y + (smallCircle.y - bigCircle.y) * progress
          }

          const currentRadius = bigCircle.radius + (smallCircle.radius - bigCircle.radius) * progress

          // 清除画布并绘制圆形
          ctx.clearRect(0, 0, canvas.width, canvas.height)
          // 绘制大圆
          ctx.beginPath()
          ctx.arc(currentPoint.x, currentPoint.y, currentRadius, 0, Math.PI * 2)
          ctx.strokeStyle = '#00f'
          ctx.stroke()
          // 绘制小圆
          ctx.beginPath()
          ctx.arc(smallCircle.x, smallCircle.y, smallCircle.radius, 0, Math.PI * 2)
          ctx.strokeStyle = '#000'
          ctx.stroke()

          // 继续动画
          requestAnimationFrame(draw)
        }
      }

      requestAnimationFrame(draw)
    </script>
  </body>
</html>

写在最后
这里只是提供了一种思路,当然还有其它的思路可以实现的。还是留一个问题,玩过吃鸡游戏的都知道,安全区之外的会显示一层蓝色的蒙版,怎么实现的还是交给各位了

用户评论