Latest commit 23576f7
时间和计时器
相关的官方文档:[timers]、[move_sprite]
时间
Time 是全局资源,可以从任何系统访问来获取时间信息。
Bevy 在每帧开始时更新这些值。
增量时间
最常用的是 delta 时间:上一帧和当前帧之间经过了多少时间。可以通过 delta 得知游戏运行的速度,使用 delta 能让游戏忽略帧率平稳地运行。
#![allow(unused)] fn main() { fn asteroids_fly( time: Res<Time>, mut q: Query<&mut Transform, With<Asteroid>>, ) { for mut transform in q.iter_mut() { // 沿 X 轴以每秒 10.0 单位的速度移动小行星 transform.translation.x += 10.0 * time.delta_seconds(); } } }
持续时间
Time 还提供自 App 启动以来的总运行时间。
#![allow(unused)] fn main() { use std::time::Instant; /// 目标时获取实体生成时的具体时间 #[derive(Component)] struct SpawnedTime(Instant); fn spawn_my_stuff( mut commands: Commands, time: Res<Time>, ) { commands .spawn() .insert(SpawnedTime(time.startup() + time.time_since_startup())); } }
计时器和秒表
Timer 和 Stopwatch 可以处理时间间隔和定时。可以在自定义的组件和资源中使用。
计时器和秒表需要系统来驱动:在系统中调用 .tick(delta) 函数来使计时器、秒表工作,否则不会开始计时。可以在 Time 资源查看详细信息。
计时器
Timer 可以检测流逝的时间。计时器有一个设定的时间。计时器可以设置成“重复”或“不重复”。
计时器可以手动“重置”(重新开始)和“暂停”(即使调用 .tick() 也不会工作)。
设定为“重复”的计时器会在达到设定的持续时间时自动重置。
todo:需要测试 Use .finished() to detect when a timer has reached its set duration. Use .just_finished(), if you need to detect only on the exact tick when the duration was reached.
#![allow(unused)] fn main() { use std::time::Duration; #[derive(Component)] struct FuseTime { /// 炸弹爆炸倒计时(不重复计时) timer: Timer, } fn 引爆炸弹( mut commands: Commands, mut q: Query<(Entity, &mut FuseTime)>, time: Res<Time>, ) { for (entity, mut fuse_timer) in q.iter_mut() { // 计时器必须“滴答”计时才能工作 fuse_timer.timer.tick(time.delta()); // 计时完成,由于世界和平,炸弹会被拆除 if fuse_timer.timer.finished() { commands.entity(entity).despawn(); } } } struct BombsSpawnConfig { // 定义多久产生新的炸弹(重复计时) timer: Timer, } /// 隔一段时间产生新的炸弹 fn 生成炸弹( mut commands: Commands, time: Res<Time>, mut config: ResMut<BombsSpawnConfig>, ) { // 计时器开始计时 config.timer.tick(time.delta()); if config.timer.finished() { commands .spawn() .insert(FuseTime { // 不重复的计时器 timer: Timer::new(Duration::from_secs(5), false), }); } } // 配置我们的炸弹生成算法 fn 炸弹生成设置( mut commands: Commands, ) { commands.insert_resource(BombsSpawnConfig { // 重复的计时器 timer: Timer::new(Duration::from_secs(10), true), }); } }
注意,Bevy 的计时器无法像典型的现实计时器那样工作(倒计时)。Bevy 的计时器从零开始计时,直到设定的“持续时间”(duration)。计时器就像秒表,但是多了额外的功能:最大持续时间、可选的“自动重置”。
秒表
todo:新概念。