You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HTML/JavaScript抛体运动模拟器位置无法更新问题求助

抛体运动模拟器位置不更新问题解决

问题核心原因

你的代码里最关键的错误是moveProjectile函数中的t = +dt——这行代码每次都会把时间t重置为dt(0.2),而不是累加时间。导致每次计算x、y位置时,都用的是同一个时间值,自然位置不会发生变化。

另外还有几个小问题需要调整:

  • 边界判断应该考虑抛体图片的高度(100px),避免完全移出画布后才停止
  • 多次点击"Launch!"按钮会重复触发动画,需要重置初始状态并避免重复调用

修正后的代码

JavaScript 部分

var theCanvas = document.getElementById("theCanvas");
var theContext = theCanvas.getContext("2d");
var theImage = document.getElementById("frog");
var ay = 9.81; // 重力加速度(国际单位)
var dt = 0.2; // 时间步长(秒)
var t = 0; // 初始时间
var vel = 45; // 初始速度(米/秒)
var yo = 450; // 初始y位置(距离顶部像素)
var xo = 6; // 初始x位置(距离左侧像素)
var angle = 45 * Math.PI / 180; // 45度转弧度
var vx = vel * Math.cos(angle);
var vy = vel * Math.sin(angle);
var x = xo; // t=0时的x位置
var y = yo; // t=0时的y位置
var colDiam = 100;
var animationId = null; // 用于存储动画ID,方便取消

function launchProjectile() {
  // 重置初始状态,防止多次点击重复触发
  t = 0;
  x = xo;
  y = yo;
  // 如果已有动画在运行,先取消
  if (animationId) {
    cancelAnimationFrame(animationId);
  }
  moveProjectile();
}

function drawProjectile() {
  theContext.clearRect(0, 0, theCanvas.width, theCanvas.height);
  theContext.drawImage(theImage, x, y, 100, 100);
}

function moveProjectile() {
  // 考虑图片高度,避免完全移出画布
  if (y < theCanvas.height - 100) {
    t += dt; // 累加时间,而不是重置
    x = xo + vx * t + colDiam * 0.0109;
    // canvas的y轴向下,所以向上运动时y减小,重力使y增大,公式正确
    y = yo - vy * t + 0.5 * ay * t * t;
    drawProjectile();
    animationId = requestAnimationFrame(moveProjectile);
  }
}

HTML 部分

<div style="width:1000px; float:left; margin-left:auto; margin-right:auto;">
  <img src="https://static.wikia.nocookie.net/uncharted/images/2/26/Amazon_rainforest_1.png/revision/latest?cb=20200519083419" width="1224" height="572" style="position:absolute;">
  <canvas id="theCanvas" width="1224" height="572" style="position:relative;">
    Canvas not supported; please update your browser.
  </canvas>
  <div style="text-align:center">
    <input type="button" value="Launch!" onclick="launchProjectile();">
  </div>
</div>

<img id="frog" src="https://static.scientificamerican.com/sciam/cache/file/41DF7DA0-EE58-4259-AA815A390FB37C55_source.jpg" width="100" height="100" style="display:none;">

(注:把青蛙图片设为display:none,避免在页面上额外显示)

关键修改点说明

  1. 时间累加:将t = +dt改为t += dt,让时间随动画帧逐步增加,这样位置计算才会持续变化。
  2. 状态重置:在launchProjectile中重置t、x、y,并取消已有动画,确保每次点击都从初始状态开始。
  3. 边界优化:判断条件改为y < theCanvas.height - 100,因为图片高度是100px,避免抛体完全移出画布后才停止动画。
  4. 隐藏冗余图片:将青蛙图片设为display:none,防止它在画布外额外显示。

内容的提问来源于stack exchange,提问作者Coolbro83

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 19:45:03