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

如何实现相对版本的setTimeout以随机间隔扣减生命值?

问题场景

需要开发一个程序,核心逻辑是:

  • 初始化health变量为100
  • 让生命值在随机间隔(如2秒、3秒、5秒)以随机数值(10、20、25点)减少,这类扣血事件称为"Injuries"
  • 由于每次间隔和扣血量都要随机变化,选择用setTimeout替代setInterval实现,但运行时生命值会快速无限减少,误以为是setTimeout不是相对延迟,实际是调用setTimeout时错误直接执行了函数。
错误原因

问题出在decreaseHealth函数内的这行代码:

setTimeout(decreaseHealth(), possibleIntervals[random]);

setTimeout的第一个参数需要传入函数引用,而不是函数执行的结果。写decreaseHealth()会立即执行该函数,同时把函数的返回值(此处为undefined)传给setTimeout,并且函数内部又会立即触发下一次调用,形成无限递归,导致生命值瞬间被扣除至负数。

修正后的代码

JavaScript 部分

var health = 100;
var possibleInjuries = [20, 10, 25];
var possibleIntervals = [5000, 2000, 3000];

// 初始调用,设置第一次扣血延迟
setTimeout(decreaseHealth, getRandomInterval());

function decreaseHealth() {
  // 随机获取扣血量和下一次的延迟时间
  const hit = possibleInjuries[Math.floor(Math.random() * possibleInjuries.length)];
  const nextInterval = getRandomInterval();

  health -= hit;
  $("#health").text(health);

  // 生命值大于0时才继续触发下一次扣血
  if (health > 0) {
    setTimeout(decreaseHealth, nextInterval);
  }
}

// 封装随机获取间隔的函数,避免重复代码
function getRandomInterval() {
  return possibleIntervals[Math.floor(Math.random() * possibleIntervals.length)];
}

HTML 部分

<html>
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
  <title>Eat the lettuce</title>
</head>
<body>
  <span>Health:</span><span id="health">100</span>%
</body>
</html>
优化说明
  1. 去掉了全局的random变量,每次调用时直接生成随机索引,避免全局变量污染
  2. 封装了getRandomInterval函数,统一处理随机间隔的获取,代码更清晰
  3. 添加了生命值大于0的判断,当生命值耗尽时停止扣血逻辑,符合游戏常理
  4. 核心修正:把setTimeout(decreaseHealth(), ...)改为setTimeout(decreaseHealth, ...),传递函数引用而非立即执行函数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 10:15:14