docs/bevy/examples/ecs/delayed_commands.rs 1.8 K · 60 lines · raw · history

1 //! This example demonstrates how to send commands which will take effect after a period of time.
2 //!
3 //! We've chosen to demonstrate this effect through the creation of a grid of clickable,
4 //! with "ripples" created when you click.
5
6 use bevy::prelude::*;
7
8 fn main() {
9 App::new()
10 .add_plugins(DefaultPlugins)
11 .add_systems(Startup, spawn)
12 .add_observer(click)
13 .run();
14 }
15
16 #[derive(Component)]
17 struct BlinkySquare;
18
19 const SQUARE_SIZE: Vec2 = Vec2::splat(45.0);
20
21 fn spawn(mut commands: Commands) {
22 commands.spawn(Camera2d);
23 for x in -5..=5 {
24 for y in -5..=5 {
25 commands.spawn((
26 BlinkySquare,
27 Transform::from_xyz(x as f32 * 50.0, y as f32 * 50.0, 0.0),
28 Sprite::from_color(Color::BLACK, SQUARE_SIZE),
29 ));
30 }
31 }
32 }
33
34 fn click(
35 click: On<PointerClick>,
36 mut commands: Commands,
37 squares: Query<(Entity, &Transform), With<BlinkySquare>>,
38 cameras: Query<(&Camera, &GlobalTransform)>,
39 ) {
40 let (camera, camera_transform) = cameras.single().unwrap();
41 let mut delayed = commands.delayed();
42 for (entity, transform) in squares.iter() {
43 // convert the pointer position to world position
44 let mouse_world_pos = camera
45 .viewport_to_world_2d(camera_transform, click.pointer.position)
46 .unwrap();
47
48 // delay the blinkiness by distance to cursor
49 let dist = mouse_world_pos.distance(transform.translation.truncate());
50 let delay = dist / 1000.0;
51 delayed
52 .secs(delay)
53 .entity(entity)
54 .insert(Sprite::from_color(Color::WHITE, SQUARE_SIZE));
55 delayed
56 .secs(delay + 0.1)
57 .entity(entity)
58 .insert(Sprite::from_color(Color::BLACK, SQUARE_SIZE));
59 }
60 }