Bevy 时间

本文我们将会介绍三种时间相关的工具------TimeTimerStopwatch、,也就是游戏时间、定时器和秒表。

游戏时间

Time是获取游戏时间的主要全局资源,我们可以在任何系统中访问时间,如果我们需要时间信息,就一定要通过TimeBevy会在每一帧的最开始更新时间。

delta 时间

最常见的用法就是获取delta time ------当前帧与上一帧的时间间隔。该时间可以体现游戏帧率有多快(想象一下30帧和120帧的时间间隔),因此我们一般通过这个时间来更新移动和动画等内容。这样做可以确保大家以相同的速度运行,无论游戏的帧率有多高。

rust 复制代码
fn asteroids_fly(
    time: Res<Time>,
    mut q: Query<&mut Transform, With<Player>>,
) {
    for mut transform in q.iter_mut() {
        // 沿X轴以每秒10个单位的速度移动玩家
        transform.translation.x += 10.0 * time.delta_seconds();
    }
}

总运行时间

我们还可以通过Time获取到自游戏启动以来的总运行时间:

rust 复制代码
fn elapsed_info(
    time: Res<Time>,
) {
    info!("Elapsed Time: {:?}", time.elapsed_secs());
}

定时器

Timer可以用于定时器相关逻辑,例如检测一段时间间隔。Timer有两种类型:一次性(Once)和可重复(Repeating)的。

Timer需要我们手动计时,即通过tickTimer累计时间。任何类型的Timer都可以重置reset

使用just_finished检测时间是否达到设定值:

rust 复制代码
// 定义一个一次性的计时器类型
#[derive(Component)]
struct OnceTimer(Timer);

// 定义一个可循环使用的计时器类型
#[derive(Component)]
struct RepeatingTimer(Timer);

// 设定计时器,添加计时器到系统
fn set_up_timer(
    mut commands: Commands,
) {
    // 设定一个一次性计时器,3秒后触发
    commands.spawn(OnceTimer(Timer::new(Duration::from_secs(3), TimerMode::Once)));
    // 设定一个可重复的计时器,每秒触发一次
    commands.spawn(RepeatingTimer(Timer::new(Duration::from_secs(1), TimerMode::Repeating)));
}

// 更新计时器
fn update_timer(
    time: Res<Time>,
    mut once_timer: Query<&mut OnceTimer>,
    mut repeating_timer: Query<&mut RepeatingTimer>,
) {
    // 获取 delta 时间
    let delta = time.delta();
    once_timer.iter_mut().for_each(|mut timer| {
        // 步进计时器
        timer.0.tick(delta);
        // 检查计时器是否达到设定的时间点
        if timer.0.just_finished() {
            info!("Once timer just finished");
        }
    });

    repeating_timer.iter_mut().for_each(|mut timer| {
        timer.0.tick(delta);
        if timer.0.just_finished() {
            info!("Repeating timer just finished");
        }
    });
}
rust 复制代码
// other code...
.add_systems(Startup, set_up_timer)
.add_systems(Update, update_timer)
// other code...

我们看下输出结果:

makefile 复制代码
2025-03-17T01:30:53.968213Z  INFO time: Repeating timer just finished
2025-03-17T01:30:54.968752Z  INFO time: Repeating timer just finished
2025-03-17T01:30:55.969461Z  INFO time: Once timer just finished
2025-03-17T01:30:55.969547Z  INFO time: Repeating timer just finished
2025-03-17T01:30:56.970133Z  INFO time: Repeating timer just finished
2025-03-17T01:30:57.971532Z  INFO time: Repeating timer just finished
2025-03-17T01:30:58.971745Z  INFO time: Repeating timer just finished
2025-03-17T01:30:59.972249Z  INFO time: Repeating timer just finished
2025-03-17T01:31:00.957014Z  INFO time: Repeating timer just finished

一次性的计时器在3秒触发,后续不再触发。

可重复计时器会每秒都出发。

如果我们想让一次性定时器再次出发,可以使用reset重置定时器。

rust 复制代码
fn reset_once_timer(
    mut once_timer: Query<&mut OnceTimer>,
) {
    once_timer.iter_mut().for_each(|mut timer| {
        // 重置定时器
        timer.0.reset();
    });
}

当定时器重置之后,定时器又会重新累计时间。

秒表

秒表的用法和定时器Timer类似,只不过秒表的主要作用是用于跟踪从过去的某个时间点到现在的累计时间(想象一下现实生活中秒表用于记录发令枪发令开始到运动员到达终点的时间间隔)。

他们的大致区别可以概括为:Stopwatch专注于记录时间累计值(如技能冷却剩余时间),而Timer更适合周期性触发事件(如每秒恢复生命值)。

rust 复制代码
#[derive(Component)]
struct RunWatch(Stopwatch);

// 生成秒表
fn setup_watch(
    mut commands: Commands,
) {
    commands.spawn(RunWatch(Stopwatch::new()));
}

// 秒表相关逻辑
fn run_watch(
    time: Res<Time>,
    mut watch: Query<&mut RunWatch>,
    key_input:Res<ButtonInput<KeyCode>>
) {
   
    watch.iter_mut().for_each(|mut run| {
        // 秒表的时间累计
        run.0.tick(time.delta());
        if key_input.just_pressed(KeyCode::Enter) {
            // 打印秒表的累计时间
            info!("time gone: {}", run.0.elapsed_secs());
        }
    })
}
相关推荐
我是前端小学生2 小时前
solana_business_card合约解析
rust
DevOps00817 小时前
在 Azure Linux 上安装 RustFS
rust·minio·分布式存储·s3·rustfs
hweiyu0018 小时前
Rust 简介
rust
萧曵 丶18 小时前
Rust中Option和Result详解
开发语言·后端·rust·option·result
火柴就是我21 小时前
每日见闻之Rust中 trait 的孤儿规则
android·rust
zstar-_1 天前
Hello, Tauri!
rust
我是前端小学生2 天前
Rust中的Vec数据结构介绍
rust
小马哥聊DevSecOps2 天前
RustFS:Rust 语言编写的分布式存储系统初探
rust
UestcXiye2 天前
Rust Web 全栈开发(八):添加功能并重构
rust·actix
UestcXiye2 天前
Rust Web 全栈开发(六):在 Web 项目中使用 MySQL 数据库
数据库·rust