2020-07-23 11:00:46 +08:00
|
|
|
|
module es {
|
2023-03-13 23:32:24 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 时间管理器,用于管理游戏中的时间相关属性
|
|
|
|
|
|
*/
|
2020-07-23 11:00:46 +08:00
|
|
|
|
export class Time {
|
2023-03-13 23:32:24 +08:00
|
|
|
|
/** 游戏运行的总时间,单位为秒 */
|
2020-12-15 11:46:33 +08:00
|
|
|
|
public static totalTime: number = 0;
|
2023-03-13 23:32:24 +08:00
|
|
|
|
|
|
|
|
|
|
/** deltaTime 的未缩放版本,不受时间尺度的影响 */
|
2020-12-15 11:46:33 +08:00
|
|
|
|
public static unscaledDeltaTime: number = 0;
|
2023-03-13 23:32:24 +08:00
|
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
|
/** 前一帧到当前帧的时间增量,按时间刻度进行缩放 */
|
|
|
|
|
|
public static deltaTime: number = 0;
|
2023-03-13 23:32:24 +08:00
|
|
|
|
|
|
|
|
|
|
/** 时间刻度缩放,可以加快或减慢游戏时间 */
|
2020-07-23 11:00:46 +08:00
|
|
|
|
public static timeScale = 1;
|
2023-03-13 23:32:24 +08:00
|
|
|
|
|
|
|
|
|
|
/** DeltaTime 可以为的最大值,避免游戏出现卡顿情况 */
|
2021-03-26 12:49:00 +08:00
|
|
|
|
public static maxDeltaTime = Number.MAX_VALUE;
|
2023-03-13 23:32:24 +08:00
|
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
|
/** 已传递的帧总数 */
|
|
|
|
|
|
public static frameCount = 0;
|
2023-03-13 23:32:24 +08:00
|
|
|
|
|
|
|
|
|
|
/** 自场景加载以来的总时间,单位为秒 */
|
2020-12-15 11:46:33 +08:00
|
|
|
|
public static timeSinceSceneLoad: number = 0;
|
2023-03-13 23:32:24 +08:00
|
|
|
|
|
|
|
|
|
|
/** 上一次记录的时间,用于计算两次调用 update 之间的时间差 */
|
2021-01-20 15:35:59 +08:00
|
|
|
|
private static _lastTime = -1;
|
2020-06-08 21:53:09 +08:00
|
|
|
|
|
2023-03-13 23:32:24 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 更新时间管理器
|
|
|
|
|
|
* @param currentTime 当前时间
|
|
|
|
|
|
* @param useEngineTime 是否使用引擎时间
|
|
|
|
|
|
*/
|
2021-08-05 11:47:47 +08:00
|
|
|
|
public static update(currentTime: number, useEngineTime: boolean) {
|
2021-05-13 16:58:24 +08:00
|
|
|
|
let dt = 0;
|
2023-03-13 23:32:24 +08:00
|
|
|
|
|
2021-08-05 11:47:47 +08:00
|
|
|
|
if (useEngineTime) {
|
2021-05-13 16:58:24 +08:00
|
|
|
|
dt = currentTime;
|
2021-08-05 11:47:47 +08:00
|
|
|
|
} else {
|
2023-03-13 23:32:24 +08:00
|
|
|
|
// 如果当前时间为 -1,则表示使用系统时间
|
|
|
|
|
|
if (currentTime === -1) {
|
2021-08-05 11:47:47 +08:00
|
|
|
|
currentTime = Date.now();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-13 23:32:24 +08:00
|
|
|
|
// 如果上一次记录的时间为 -1,则表示当前为第一次调用 update
|
|
|
|
|
|
if (this._lastTime === -1) {
|
2021-08-05 11:47:47 +08:00
|
|
|
|
this._lastTime = currentTime;
|
2023-03-13 23:32:24 +08:00
|
|
|
|
}
|
2021-08-05 11:47:47 +08:00
|
|
|
|
|
2023-03-13 23:32:24 +08:00
|
|
|
|
// 计算两次调用 update 之间的时间差,并将其转换为秒
|
2021-08-05 11:47:47 +08:00
|
|
|
|
dt = (currentTime - this._lastTime) / 1000;
|
2021-05-13 16:58:24 +08:00
|
|
|
|
}
|
2023-03-13 23:32:24 +08:00
|
|
|
|
|
|
|
|
|
|
// 如果计算得到的时间差超过了最大时间步长,则将其限制为最大时间步长
|
|
|
|
|
|
if (dt > this.maxDeltaTime) {
|
2021-03-26 12:49:00 +08:00
|
|
|
|
dt = this.maxDeltaTime;
|
2023-03-13 23:32:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新时间管理器的各个属性
|
2020-11-25 11:37:24 +08:00
|
|
|
|
this.totalTime += dt;
|
2020-07-23 11:00:46 +08:00
|
|
|
|
this.deltaTime = dt * this.timeScale;
|
|
|
|
|
|
this.unscaledDeltaTime = dt;
|
2020-11-25 11:37:24 +08:00
|
|
|
|
this.timeSinceSceneLoad += dt;
|
2020-07-28 16:25:20 +08:00
|
|
|
|
this.frameCount++;
|
2020-07-12 23:30:48 +08:00
|
|
|
|
|
2023-03-13 23:32:24 +08:00
|
|
|
|
// 记录当前时间,以备下一次调用 update 使用
|
2020-07-23 11:00:46 +08:00
|
|
|
|
this._lastTime = currentTime;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-13 23:32:24 +08:00
|
|
|
|
|
2020-07-28 16:25:20 +08:00
|
|
|
|
public static sceneChanged() {
|
2020-11-25 11:37:24 +08:00
|
|
|
|
this.timeSinceSceneLoad = 0;
|
2020-07-23 11:00:46 +08:00
|
|
|
|
}
|
2020-07-12 23:30:48 +08:00
|
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
|
/**
|
2023-03-13 23:32:24 +08:00
|
|
|
|
* 检查指定时间间隔是否已过去
|
|
|
|
|
|
* @param interval 指定时间间隔
|
|
|
|
|
|
* @returns 是否已过去指定时间间隔
|
2020-07-23 11:00:46 +08:00
|
|
|
|
*/
|
2023-03-13 23:32:24 +08:00
|
|
|
|
public static checkEvery(interval: number): boolean {
|
|
|
|
|
|
// 计算当前时刻所经过的完整时间间隔个数(向下取整)
|
|
|
|
|
|
const passedIntervals = Math.floor(this.timeSinceSceneLoad / interval);
|
|
|
|
|
|
|
|
|
|
|
|
// 计算上一帧到当前帧经过的时间所包含的时间间隔个数(向下取整)
|
|
|
|
|
|
const deltaIntervals = Math.floor(this.deltaTime / interval);
|
|
|
|
|
|
|
|
|
|
|
|
// 如果当前时刻所经过的时间间隔数比上一帧所经过的时间间隔数多,则说明时间间隔已过去
|
|
|
|
|
|
return passedIntervals > deltaIntervals;
|
2020-07-23 11:00:46 +08:00
|
|
|
|
}
|
2020-07-12 23:30:48 +08:00
|
|
|
|
}
|
2020-07-23 11:00:46 +08:00
|
|
|
|
}
|