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

优化蒸汽引擎模拟系统:实现数值与仪表平滑变化

解决方案:平滑蒸汽引擎模拟数值变化并替换数组计算

关键修改步骤

1. 缩短更新间隔并适配步长

将定时器间隔从500ms改为100ms,同时按比例调整温度变化步长:

  • 加热时,原500ms增加0.5℃ → 改为100ms增加0.1℃(保持总升温速率不变)
  • 降温时,原500ms减少0.25℃ → 改为100ms减少0.05℃
    更小的步长配合更短的更新间隔,能让数值变化更顺滑,避免生硬跳变。

2. 用数学公式替代庞大数组

压力计算

原数组是温度从100℃到145℃时,压力从1Bar线性增长到10Bar,直接用线性公式计算即可:

pressure = 1 + (temperature - 100) * 0.2;
pressure = Math.min(Math.max(pressure, 1), 10); // 限制压力在1-10Bar区间

速度计算

原数组的速度增长是非线性的(前期慢、后期快),用幂函数模拟这个物理特性,替代离散数组:

// 将压力映射到0-1区间,通过1.5次幂实现非线性增长,最终映射到0-90km/h
speed = 90 * Math.pow((pressure - 1) / 9, 1.5);
speed = Math.min(Math.max(speed, 0), 90); // 限制速度在0-90km/h区间

3. 优化数值显示精度

通过toFixed()方法保留1位小数,避免显示过多冗余小数位,同时保持平滑感:

function updateTemperatureDisplay() {
  temperatureDisplay.innerHTML = temperature.toFixed(1) + " °C";
}

function updatePressureDisplay() {
  pressureDisplay.innerHTML = "Current Pressure: " + pressure.toFixed(1) + " Bar";
}

function updateSpeedDisplay() {
  speedDisplay.innerHTML = speed.toFixed(1) + " km/h";
}

修改后的完整JS代码

let temperature = 20;
let pressure = 1;
let speed = 0;

const temperatureDisplay = document.getElementById("temperature");
const pressureDisplay = document.getElementById("pressure");
const speedDisplay = document.getElementById("speed");
const gaugeElement = document.querySelector(".gauge");

function updateTemperatureDisplay() {
  temperatureDisplay.innerHTML = temperature.toFixed(1) + " °C";
}

function updatePressureDisplay() {
  pressureDisplay.innerHTML = "Current Pressure: " + pressure.toFixed(1) + " Bar";
}

function updateSpeedDisplay() {
  speedDisplay.innerHTML = speed.toFixed(1) + " km/h";
}

function toggleHeater() {
  const heaterStatus = document.getElementById("heater-status");
  const heaterAudio = document.getElementById("heater-audio");

  if (heaterStatus.innerHTML === "On") {
    heaterStatus.innerHTML = "Off";
    heaterAudio.pause();
  } else {
    heaterStatus.innerHTML = "On";
    heaterAudio.play();
  }
}

function playSteamWhistle() {
  if (temperature >= 100) {
    const steamWhistle = new Audio("sfx6-whistlescreemtrain-33567.mp3");
    steamWhistle.play();
    temperature -= 2.5;
  }
}

// 提前封装仪表盘设置函数,避免重复定义
function setGaugeValue(gauge, value) {
  if (value < 0 || value > 90) {
    return;
  }
  gauge.querySelector(".gauge__fill").style.transform = `rotate(${value / 180}turn)`;
  gauge.querySelector(".gauge__cover").textContent = `${value.toFixed(1)} km/h`;
}

setInterval(function () {
  const heaterStatus = document.getElementById("heater-status");

  if (heaterStatus.innerHTML === "On") {
    if (temperature < 145) {
      temperature += 0.1; // 适配100ms间隔的步长
    }
  } else if (temperature > 20) {
    temperature -= 0.05; // 适配100ms间隔的步长
  }

  if (temperature >= 100) {
    // 线性计算压力
    pressure = 1 + (temperature - 100) * 0.2;
    pressure = Math.min(Math.max(pressure, 1), 10);
    // 非线性计算速度
    speed = 90 * Math.pow((pressure - 1) / 9, 1.5);
    speed = Math.min(Math.max(speed, 0), 90);
  } else {
    // 温度低于100时,压力和速度平滑回落
    pressure = Math.max(pressure - 0.02, 1);
    speed = Math.max(speed - 0.1, 0);
  }

  setGaugeValue(gaugeElement, speed);

  updateTemperatureDisplay();
  updatePressureDisplay();
  updateSpeedDisplay();
}, 100); // 更新间隔改为100ms

额外优化说明

  • 将setGaugeValue函数提取到定时器外部,避免每次触发都重新定义函数,提升性能
  • 补充了温度低于100℃时,压力和速度的平滑回落逻辑,更贴近真实物理规律
  • 用Math.min/Math.max限制所有数值的合理区间,避免出现异常值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 03:55:01