Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/examples/ecs/state_scoped.rs
6592 views
1
//! Shows how to spawn entities that are automatically despawned either when
2
//! entering or exiting specific game states.
3
//!
4
//! This pattern is useful for managing menus, levels, or other state-specific
5
//! content that should only exist during certain states.
6
7
use bevy::prelude::*;
8
9
fn main() {
10
App::new()
11
.add_plugins(DefaultPlugins)
12
.init_state::<GameState>()
13
.add_systems(Startup, setup_camera)
14
.add_systems(OnEnter(GameState::A), on_a_enter)
15
.add_systems(OnEnter(GameState::B), on_b_enter)
16
.add_systems(OnExit(GameState::A), on_a_exit)
17
.add_systems(OnExit(GameState::B), on_b_exit)
18
.add_systems(Update, toggle)
19
.insert_resource(TickTock(Timer::from_seconds(1.0, TimerMode::Repeating)))
20
.run();
21
}
22
23
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default, States)]
24
enum GameState {
25
#[default]
26
A,
27
B,
28
}
29
30
#[derive(Resource)]
31
struct TickTock(Timer);
32
33
fn on_a_enter(mut commands: Commands) {
34
info!("on_a_enter");
35
commands.spawn((
36
DespawnOnExit(GameState::A),
37
Text::new("Game is in state 'A'"),
38
TextFont {
39
font_size: 33.0,
40
..default()
41
},
42
TextColor(Color::srgb(0.5, 0.5, 1.0)),
43
Node {
44
position_type: PositionType::Absolute,
45
top: px(0),
46
left: px(0),
47
..default()
48
},
49
));
50
}
51
52
fn on_a_exit(mut commands: Commands) {
53
info!("on_a_exit");
54
commands.spawn((
55
DespawnOnEnter(GameState::A),
56
Text::new("Game state 'A' will be back in 1 second"),
57
TextFont {
58
font_size: 33.0,
59
..default()
60
},
61
TextColor(Color::srgb(0.5, 0.5, 1.0)),
62
Node {
63
position_type: PositionType::Absolute,
64
top: px(0),
65
left: px(500),
66
..default()
67
},
68
));
69
}
70
71
fn on_b_enter(mut commands: Commands) {
72
info!("on_b_enter");
73
commands.spawn((
74
DespawnOnExit(GameState::B),
75
Text::new("Game is in state 'B'"),
76
TextFont {
77
font_size: 33.0,
78
..default()
79
},
80
TextColor(Color::srgb(0.5, 0.5, 1.0)),
81
Node {
82
position_type: PositionType::Absolute,
83
top: px(50),
84
left: px(0),
85
..default()
86
},
87
));
88
}
89
90
fn on_b_exit(mut commands: Commands) {
91
info!("on_b_exit");
92
commands.spawn((
93
DespawnOnEnter(GameState::B),
94
Text::new("Game state 'B' will be back in 1 second"),
95
TextFont {
96
font_size: 33.0,
97
..default()
98
},
99
TextColor(Color::srgb(0.5, 0.5, 1.0)),
100
Node {
101
position_type: PositionType::Absolute,
102
top: px(50),
103
left: px(500),
104
..default()
105
},
106
));
107
}
108
109
fn setup_camera(mut commands: Commands) {
110
commands.spawn(Camera3d::default());
111
}
112
113
fn toggle(
114
time: Res<Time>,
115
mut timer: ResMut<TickTock>,
116
state: Res<State<GameState>>,
117
mut next_state: ResMut<NextState<GameState>>,
118
) {
119
if !timer.0.tick(time.delta()).is_finished() {
120
return;
121
}
122
*next_state = match state.get() {
123
GameState::A => NextState::Pending(GameState::B),
124
GameState::B => NextState::Pending(GameState::A),
125
}
126
}
127
128