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());
        }
    })
}
相关推荐
KENYCHEN奉孝12 小时前
基于 actix-web 框架的简单 demo
前端·rust
love530love13 小时前
【笔记】旧版MSYS2 环境中 Rust 升级问题及解决过程
开发语言·人工智能·windows·笔记·python·rust·virtualenv
Humbunklung14 小时前
Rust 函数
开发语言·后端·rust
荣江14 小时前
【实战】基于 Tauri 和 Rust 实现基于无头浏览器的高可用网页抓取
后端·rust
susnm15 小时前
创建你的第一个 Dioxus app
rust·全栈
love530love1 天前
【笔记】在 MSYS2(MINGW64)中正确安装 Rust
运维·开发语言·人工智能·windows·笔记·python·rust
技术小甜甜1 天前
【Blender Texture】【游戏开发】高质感 Blender 4K 材质资源推荐合集 —— 提升场景真实感与美术表现力
blender·游戏开发·材质·texture
景天科技苑1 天前
【Rust宏编程】Rust有关宏编程底层原理解析与应用实战
开发语言·后端·rust·rust宏·宏编程·rust宏编程
维维酱1 天前
Rust - 消息传递
rust
Thomas游戏开发1 天前
Unity3D TextMeshPro终极使用指南
前端·unity3d·游戏开发