@dao3fun/timer
v1.0.2
Published
轻量、无依赖的计时器组件,适用于游戏循环与回调调度。提供基础计时器 `Timer` 与多计时器管理器 `TimeManager`
Keywords
Readme
Timer 计时器
轻量、无依赖的计时器组件,适用于游戏循环与回调调度。提供基础计时器 Timer 与多计时器管理器 TimeManager。
- 单位约定:所有时间相关参数需使用相同单位(建议毫秒 ms)。例如
TimeManager.tick与Timer.cd必须一致。
安装
npm install @dao3fun/timer快速开始
从聚合入口导出:
import { Timer, TimeManager } from "@dao3fun/timer";最小示例(一次性触发):
import { TimeManager } from "@dao3fun/timer";
const mgr = new TimeManager(16.67); // 约 60 FPS,单位:ms
mgr.createTimer(
1000,
() => {
// 1s 后触发
console.log("fire once after ~1s");
},
false,
true
); // loop=false, autoStart=true
mgr.start();Timer 与 TimeManager 的区别
简单来说,Timer 是一个独立的“闹钟”,而 TimeManager 是管理这些“闹钟”的“管家”。
| 特性 | Timer (计时器) | TimeManager (时间管理器) |
| :----------- | :------------------------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------------- |
| 核心职责 | 定义单个计时任务的逻辑:何时触发 (cd)、触发什么 (callback)、是否重复 (loop)。 | 管理一个或多个 Timer 实例的生命周期与时间推进。 |
| 时间驱动 | 被动。它自身不产生时间流逝,需要外部循环调用其 update(dt) 方法来推进时间。 | 主动。它内部使用 setInterval 创建一个自动循环,按固定的 tick 间隔为所有受其管理的 Timer 调用 update(dt)。 |
| 关系 | Timer 是基础组件,可以脱离 TimeManager 独立存在。 | TimeManager 是 Timer 的一个可选的便捷封装,用于简化多计时器和自动循环的管理。 |
| 使用场景 | 当你已有自己的游戏主循环 (game loop) 或 requestAnimationFrame 时,可以在循环中手动创建并调用 timer.update(dt)。 | 当你需要一个独立的、基于 setInterval 的“后台”定时任务管理器,或者希望同时管理多个计时器时,用 TimeManager 更方便。 |
总结:
- 如果你需要一个简单的、能融入现有循环的计时逻辑,请使用
Timer。 - 如果你需要一个能自动运行、管理多个计时任务的“全自动”方案,请使用
TimeManager。
API 说明
Timer
文件:node_modules/@dao3fun/timer/server/src/lib/Timer.ts
属性
- loop: boolean — 是否循环触发
- cd: number — 冷却时间/间隔(与 dt 同单位)
- callback: (() => void) | null — 达到 cd 时触发的回调
- timeCount: number — 自上次触发累计的时间
- isStop: boolean — 是否处于停止状态
方法
- setTimer(cd: number, cb: () => void, loop = false): void
配置计时器。注意 cd 单位需与update(dt)的 dt 一致。 - start(): void
重置累计时间并开始计时。 - update(dt: number): void
推进计时器,一般由TimeManager调用。若timeCount >= cd:loop=true:回调后timeCount -= cd并继续运行loop=false:回调后停止
- stop(): void
停止计时(再次start()会清零并重启)
- setTimer(cd: number, cb: () => void, loop = false): void
注意:Timer 不做任何单位换算,请确保外部 dt 与 cd 一致(建议毫秒)。
TimeManager
文件:node_modules/@dao3fun/timer/server/src/lib/TimeManager.ts
构造
- new TimeManager(tick: number = 16.67)
指定每次推进的增量(单位与 Timer 一致,建议毫秒)
- new TimeManager(tick: number = 16.67)
基本方法
- add(timer: Timer): void — 添加计时器
- remove(timer: Timer): void — 移除计时器
- clear(): void — 清空全部计时器
- setTick(tick: number): void — 动态调整 tick(运行中会自动重启内部 interval)
- start(): void — 使用
setInterval开始自动推进 - stop(): void — 停止自动推进
- isRunning(): boolean — 查询是否运行中
便捷方法
- createTimer(cd: number, cb: () => void, loop = false, autoStart = false): Timer
创建并加入一个Timer。autoStart=true会在创建后自动start()。
- createTimer(cd: number, cb: () => void, loop = false, autoStart = false): Timer
示例
1. 单独使用 Timer (standalone.ts)
如果你已经有自己的主循环(如 requestAnimationFrame),可以不依赖 TimeManager,手动驱动 Timer。
import Timer from "../lib/Timer"; // 注意:直接从源文件导入
// 1) 创建并配置一个循环 Timer
const timer = new Timer();
timer.setTimer(
1000, // cd: 1000ms
() => {
console.log("Manual update tick every 1s");
},
true // loop: true
);
// 2) 启动 Timer
timer.start();
// 3) 模拟一个主循环
const tickInterval = 50; // 假设主循环每 50ms 运行一次
setInterval(() => {
// 在循环的每一帧,手动调用 update 并传入时间增量 (dt)
timer.update(tickInterval);
}, tickInterval);2. 一次性触发 (once.ts)
这是最基础的用法,调用 createTimer 创建一个只执行一次的计时器。
import { TimeManager } from "@dao3fun/timer";
// 1) 创建时间管理器,指定 tick 间隔(约 60 FPS)
const mgr = new TimeManager(16.67);
// 2) 创建一次性计时器
mgr.createTimer(
1000, // cd: 1000ms 后触发
() => {
console.log("fire once after ~1s");
},
false, // loop: false
true // autoStart: true
);
// 3) 启动管理器
mgr.start();3. 循环触发 (loop.ts)
设置 loop: true,计时器将在每次触发后自动重复。
import { TimeManager } from "@dao3fun/timer";
const mgr = new TimeManager(100); // 每 100ms 推进一次
mgr.createTimer(
500, // cd: 每 500ms 触发一次
() => {
console.log("tick every 500ms");
},
true, // loop: true
true // autoStart: true
);
mgr.start();4. 多计时器管理 (multi.ts)
一个 TimeManager 实例可以同时管理多个不同间隔的 Timer。
import { TimeManager } from "@dao3fun/timer";
const mgr = new TimeManager(16.67); // 60 FPS
// 创建多个不同 cd 的循环计时器
mgr.createTimer(300, () => console.log("A every 300ms"), true, true);
mgr.createTimer(1000, () => console.log("B every 1s"), true, true);
mgr.createTimer(2000, () => console.log("C every 2s"), true, true);
mgr.start();注意事项
- 该库不依赖外部框架,易于在游戏主循环或服务器定时任务中集成。
- 若需要更精准或帧同步逻辑,可配合引擎的主循环手动调用
Timer.update(dt),或在TimeManager内自定义推进机制。
