当前位置:首页 > JavaScript

js实现射箭

2026-02-02 07:21:41JavaScript

使用 Canvas 实现射箭动画

通过 HTML5 Canvas 和 JavaScript 可以模拟射箭效果,核心包括绘制弓箭、箭矢轨迹和物理运动逻辑。

HTML 结构

<canvas id="gameCanvas" width="800" height="500"></canvas>

JavaScript 实现

const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

// 弓箭参数
let bow = {
  x: 100,
  y: 250,
  angle: 0,
  power: 0,
  maxPower: 50
};

// 箭矢参数
let arrow = {
  x: 0,
  y: 0,
  speedX: 0,
  speedY: 0,
  flying: false
};

// 绘制弓箭
function drawBow() {
  ctx.save();
  ctx.translate(bow.x, bow.y);
  ctx.rotate(bow.angle);

  // 弓身
  ctx.beginPath();
  ctx.moveTo(0, -20);
  ctx.quadraticCurveTo(30, 0, 0, 20);
  ctx.strokeStyle = '#8B4513';
  ctx.lineWidth = 8;
  ctx.stroke();

  // 弓弦
  if (!arrow.flying) {
    ctx.beginPath();
    ctx.moveTo(0, -15);
    ctx.lineTo(40 + bow.power/2, 0);
    ctx.lineTo(0, 15);
    ctx.strokeStyle = '#FFF';
    ctx.lineWidth = 2;
    ctx.stroke();
  }

  ctx.restore();
}

// 绘制箭矢
function drawArrow() {
  if (!arrow.flying) {
    arrow.x = bow.x + Math.cos(bow.angle) * (40 + bow.power/2);
    arrow.y = bow.y + Math.sin(bow.angle) * (40 + bow.power/2);
  }

  ctx.save();
  ctx.translate(arrow.x, arrow.y);
  ctx.rotate(Math.atan2(arrow.speedY, arrow.speedX));

  // 箭杆
  ctx.beginPath();
  ctx.moveTo(0, 0);
  ctx.lineTo(-30, 0);
  ctx.strokeStyle = '#A9A9A9';
  ctx.lineWidth = 3;
  ctx.stroke();

  // 箭尾
  ctx.beginPath();
  ctx.moveTo(0, 0);
  ctx.lineTo(-10, -5);
  ctx.lineTo(-10, 5);
  ctx.closePath();
  ctx.fillStyle = '#FF6347';
  ctx.fill();

  ctx.restore();
}

// 更新箭矢位置
function updateArrow() {
  if (arrow.flying) {
    arrow.x += arrow.speedX;
    arrow.y += arrow.speedY;
    arrow.speedY += 0.2; // 重力

    // 边界检测
    if (arrow.x > canvas.width || arrow.y > canvas.height || arrow.x < 0) {
      arrow.flying = false;
    }
  }
}

// 鼠标控制
canvas.addEventListener('mousemove', (e) => {
  if (!arrow.flying) {
    const rect = canvas.getBoundingClientRect();
    const mouseX = e.clientX - rect.left;
    const mouseY = e.clientY - rect.top;
    bow.angle = Math.atan2(mouseY - bow.y, mouseX - bow.x);
  }
});

canvas.addEventListener('mousedown', () => {
  if (!arrow.flying) {
    bow.power = 0;
    const powerInterval = setInterval(() => {
      if (bow.power < bow.maxPower) {
        bow.power += 1;
      }
    }, 50);

    const mouseUpHandler = () => {
      clearInterval(powerInterval);
      arrow.flying = true;
      arrow.speedX = Math.cos(bow.angle) * bow.power;
      arrow.speedY = Math.sin(bow.angle) * bow.power;
      canvas.removeEventListener('mouseup', mouseUpHandler);
    };

    canvas.addEventListener('mouseup', mouseUpHandler);
  }
});

// 动画循环
function gameLoop() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  updateArrow();
  drawBow();
  drawArrow();

  requestAnimationFrame(gameLoop);
}

gameLoop();

实现要点说明

弓箭控制逻辑

  • 通过鼠标移动控制弓箭角度(Math.atan2计算角度)
  • 鼠标按下时蓄力(bow.power递增)
  • 鼠标释放时根据蓄力值计算箭矢初速度

物理运动模拟

  • 箭矢飞行时受重力影响(arrow.speedY += 0.2
  • 使用三角函数分解速度分量:
    arrow.speedX = Math.cos(bow.angle) * bow.power
    arrow.speedY = Math.sin(bow.angle) * bow.power

绘制技巧

  • 使用ctx.translatectx.rotate实现对象旋转
  • 箭矢方向始终与速度方向一致(Math.atan2(arrow.speedY, arrow.speedX)

扩展建议

  1. 添加目标检测功能:

    function checkHit() {
    const targets = [{x: 700, y: 300, radius: 30}];
    targets.forEach(target => {
     const dx = arrow.x - target.x;
     const dy = arrow.y - target.y;
     if (Math.sqrt(dx*dx + dy*dy) < target.radius) {
       // 命中处理
     }
    });
    }
  2. 加入风阻效果:

    // 在updateArrow中添加
    arrow.speedX *= 0.99; // 空气阻力
  3. 使用粒子系统实现尾迹效果:

    const particles = [];
    function createParticles() {
    particles.push({
     x: arrow.x,
     y: arrow.y,
     size: Math.random() * 3 + 1,
     alpha: 1
    });
    }

完整实现可通过调整物理参数(重力、阻力等)来改变游戏难度,添加碰撞检测和得分系统可扩展为完整小游戏。

js实现射箭

标签: js
分享给朋友:

相关文章

js 实现vue模板

js 实现vue模板

实现 Vue 模板的 JavaScript 方法 通过原生 JavaScript 可以实现类似 Vue 的模板渲染功能,主要包括数据绑定、指令处理和模板解析。以下是核心实现思路: 数据绑定与响应式…

js实现拖拽

js实现拖拽

实现拖拽的基本步骤 通过监听鼠标事件(mousedown、mousemove、mouseup)实现拖拽功能。以下是核心代码逻辑: const draggableElement = document.…

js实现全选

js实现全选

实现全选功能的方法 在JavaScript中实现全选功能通常涉及监听全选复选框的点击事件,并根据其状态控制其他复选框的选中状态。以下是几种常见的实现方式: 基础DOM操作实现 通过获取所有目标复选框…

js实现全屏

js实现全屏

实现全屏的基本方法 使用JavaScript实现全屏功能主要依赖Element.requestFullscreen()方法。现代浏览器均支持此API,但不同浏览器可能需要添加前缀。 // 触发全屏…

js实现列表

js实现列表

使用 JavaScript 实现列表 JavaScript 提供了多种方式来实现列表功能,包括数组操作、DOM 元素动态生成等。以下是几种常见的实现方法: 使用数组存储列表数据 数组是 JavaS…

js实现图表

js实现图表

在JavaScript中实现图表通常使用流行的图表库,以下是几种常见的方法和工具: 使用Chart.js Chart.js是一个简单灵活的库,适合快速生成响应式图表。安装方式包括CDN引入或npm…