时间系统(Time) 概述 学习目标 :
理解 Bevy 时间系统的基本概念
掌握时间资源的使用
了解定时器的使用
学会使用虚拟时间
前置知识要求 :
Bevy 快速入门
ECS 基础
资源(Resources)基础
核心概念 什么是时间系统? 时间系统是 Bevy 中用于管理游戏时间的功能。时间系统提供了多种时间类型,包括真实时间、虚拟时间和固定时间步。
为什么需要时间系统?
游戏逻辑 :时间系统可以控制游戏逻辑的执行速度
动画 :时间系统可以控制动画的播放速度
物理模拟 :时间系统可以控制物理模拟的时间步
游戏暂停 :时间系统可以实现游戏暂停功能
时间系统的核心组件 Bevy 时间系统包含以下核心组件:
Time :真实时间,不受游戏速度影响
Time :虚拟时间,受游戏速度影响
Time :固定时间步,用于物理模拟
Timer :定时器,用于延迟和周期性任务
基础用法 时间资源 使用时间资源获取时间信息。
源代码文件 :bevy/examples/time/time.rs
代码示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 use bevy::{app::AppExit, prelude::*};use std::{ io::{self , BufRead}, time::Duration, }; fn main () { App::new () .add_plugins (MinimalPlugins) .insert_resource (Time::<Virtual>::from_max_delta (Duration::from_secs (5 ))) .insert_resource (Time::<Fixed>::from_duration (Duration::from_secs (1 ))) .add_systems (PreUpdate, print_real_time) .add_systems (FixedUpdate, print_fixed_time) .add_systems (Update, print_time) .set_runner (runner) .run (); } fn print_real_time (time: Res<Time<Real>>) { println! ( "PreUpdate: this is real time clock, delta is {:?} and elapsed is {:?}" , time.delta (), time.elapsed () ); } fn print_fixed_time (time: Res<Time>) { println! ( "FixedUpdate: this is generic time clock inside fixed, delta is {:?} and elapsed is {:?}" , time.delta (), time.elapsed () ); } fn print_time (time: Res<Time>) { println! ( "Update: this is generic time clock, delta is {:?} and elapsed is {:?}" , time.delta (), time.elapsed () ); }
关键要点 :
使用 Time<Real> 获取真实时间
使用 Time<Virtual> 获取虚拟时间
使用 Time<Fixed> 获取固定时间步
使用 time.delta() 获取时间增量
使用 time.elapsed() 获取经过的时间
说明 : 时间资源是时间系统的基础。通过使用时间资源,可以获取时间信息,控制游戏逻辑的执行速度。
定时器 使用定时器实现延迟和周期性任务。
源代码文件 :bevy/examples/time/timers.rs
代码示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 use bevy::{log::info, prelude::*};fn main () { App::new () .add_plugins (DefaultPlugins) .init_resource::<Countdown>() .add_systems (Startup, setup) .add_systems (Update, (countdown, print_when_completed)) .run (); } #[derive(Component, Deref, DerefMut)] struct PrintOnCompletionTimer (Timer);#[derive(Resource)] struct Countdown { percent_trigger: Timer, main_timer: Timer, } impl Countdown { pub fn new () -> Self { Self { percent_trigger: Timer::from_seconds (4.0 , TimerMode::Repeating), main_timer: Timer::from_seconds (20.0 , TimerMode::Once), } } } impl Default for Countdown { fn default () -> Self ::new () } } fn setup (mut commands: Commands) { commands.spawn (PrintOnCompletionTimer (Timer::from_seconds ( 5.0 , TimerMode::Once, ))); } fn print_when_completed (time: Res<Time>, mut query: Query<&mut PrintOnCompletionTimer>) { for mut timer in &mut query { if timer.tick (time.delta ()).just_finished () { info!("Entity timer just finished" ); } } } fn countdown (time: Res<Time>, mut countdown: ResMut<Countdown>) { countdown.main_timer.tick (time.delta ()); if countdown.percent_trigger.tick (time.delta ()).just_finished () { if !countdown.main_timer.is_finished () { info!( "Timer is {:0.0}% complete!" , countdown.main_timer.fraction () * 100.0 ); } else { countdown.percent_trigger.pause (); info!("Paused percent trigger timer" ); } } }
关键要点 :
使用 Timer::from_seconds() 创建定时器
使用 TimerMode::Once 创建单次定时器
使用 TimerMode::Repeating 创建重复定时器
使用 timer.tick() 更新定时器
使用 timer.just_finished() 检查定时器是否刚完成
使用 timer.is_finished() 检查定时器是否完成
使用 timer.fraction() 获取定时器完成的百分比
说明 : 定时器是时间系统的重要功能。通过使用定时器,可以实现延迟和周期性任务。
进阶用法 虚拟时间 使用虚拟时间控制游戏速度。
源代码文件 :bevy/examples/time/virtual_time.rs
代码示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 use std::time::Duration;use bevy::{ color::palettes::css::*, input::common_conditions::input_just_pressed, prelude::*, time::common_conditions::on_real_timer, }; fn main () { App::new () .add_plugins (DefaultPlugins) .add_systems (Startup, setup) .add_systems ( Update, ( move_virtual_time_sprites, move_real_time_sprites, toggle_pause.run_if (input_just_pressed (KeyCode::Space)), change_time_speed::<1 >.run_if (input_just_pressed (KeyCode::ArrowUp)), change_time_speed::<-1 >.run_if (input_just_pressed (KeyCode::ArrowDown)), (update_virtual_time_info_text, update_real_time_info_text) .run_if (on_real_timer (Duration::from_millis (250 ))), ), ) .run (); } #[derive(Component)] struct RealTime ;#[derive(Component)] struct VirtualTime ;fn setup (mut commands: Commands, asset_server: Res<AssetServer>, mut time: ResMut<Time<Virtual>>) { time.set_relative_speed (2 .); commands.spawn (Camera2d); } fn move_virtual_time_sprites ( mut sprite_query: Query<&mut Transform, (With<Sprite>, With<VirtualTime>)>, time: Res<Time>, ) { for mut transform in sprite_query.iter_mut () { transform.translation.x = get_sprite_translation_x (time.elapsed_secs ()); } } fn change_time_speed <const DELTA: i8 >(mut time: ResMut<Time<Virtual>>) { let time_speed = (time.relative_speed () + DELTA as f32 ) .round () .clamp (0.25 , 5 .); time.set_relative_speed (time_speed); } fn toggle_pause (mut time: ResMut<Time<Virtual>>) { if time.is_paused () { time.unpause (); } else { time.pause (); } }
关键要点 :
使用 Time<Virtual> 获取虚拟时间
使用 time.set_relative_speed() 设置相对速度
使用 time.pause() 暂停时间
使用 time.unpause() 恢复时间
使用 time.is_paused() 检查时间是否暂停
说明 : 虚拟时间是时间系统的高级功能。通过使用虚拟时间,可以控制游戏速度,实现游戏暂停和加速功能。
实际应用 在游戏开发中的应用场景 时间系统在游戏开发中有广泛的应用:
游戏逻辑 :控制游戏逻辑的执行速度
动画 :控制动画的播放速度
物理模拟 :控制物理模拟的时间步
游戏暂停 :实现游戏暂停功能
定时任务 :实现延迟和周期性任务
常见问题 问题 1 :如何获取时间增量?
解决方案 :
使用 Time::delta() 获取时间增量
使用 Time::delta_secs() 获取时间增量(秒)
使用 Time::delta_secs_f64() 获取时间增量(秒,f64)
问题 2 :如何创建定时器?
解决方案 :
使用 Timer::from_seconds() 创建定时器
使用 TimerMode::Once 创建单次定时器
使用 TimerMode::Repeating 创建重复定时器
问题 3 :如何控制游戏速度?
解决方案 :
使用 Time<Virtual>::set_relative_speed() 设置相对速度
使用 Time<Virtual>::pause() 暂停时间
使用 Time<Virtual>::unpause() 恢复时间
性能考虑
时间资源 :时间资源是轻量级的,可以频繁访问
定时器 :定时器更新是高效的,可以大量使用
虚拟时间 :虚拟时间计算是高效的,可以用于控制游戏速度
相关资源 相关源代码文件 :
bevy/examples/time/time.rs - 时间系统基础示例
bevy/examples/time/timers.rs - 定时器示例
bevy/examples/time/virtual_time.rs - 虚拟时间示例
官方文档链接 :
进一步学习建议 :
学习系统调度,了解固定时间步的使用
学习资源管理,了解资源的生命周期
索引 :返回上级目录