1
- use bevy:: prelude:: * ;
1
+ use bevy:: { ecs :: event :: Events , prelude:: * } ;
2
2
3
3
#[ derive( Component , Default ) ]
4
4
struct Enemy {
5
5
hit_points : u32 ,
6
+ score_value : u32 ,
6
7
}
7
8
8
- fn despawn_dead_enemies ( mut commands : Commands , enemies : Query < ( Entity , & Enemy ) > ) {
9
+ struct EnemyDied ( u32 ) ;
10
+
11
+ struct Score ( u32 ) ;
12
+
13
+ fn update_score ( mut dead_enemies : EventReader < EnemyDied > , mut score : ResMut < Score > ) {
14
+ for value in dead_enemies. iter ( ) {
15
+ score. 0 += value. 0 ;
16
+ }
17
+ }
18
+
19
+ fn despawn_dead_enemies (
20
+ mut commands : Commands ,
21
+ mut dead_enemies : EventWriter < EnemyDied > ,
22
+ enemies : Query < ( Entity , & Enemy ) > ,
23
+ ) {
9
24
for ( entity, enemy) in enemies. iter ( ) {
10
25
if enemy. hit_points == 0 {
11
26
commands. entity ( entity) . despawn_recursive ( ) ;
27
+ dead_enemies. send ( EnemyDied ( enemy. score_value ) ) ;
12
28
}
13
29
}
14
30
}
@@ -21,77 +37,137 @@ fn hurt_enemies(mut enemies: Query<&mut Enemy>) {
21
37
22
38
fn spawn_enemy ( mut commands : Commands , keyboard_input : Res < Input < KeyCode > > ) {
23
39
if keyboard_input. just_pressed ( KeyCode :: Space ) {
24
- commands. spawn ( ) . insert ( Enemy { hit_points : 5 } ) ;
40
+ commands. spawn ( ) . insert ( Enemy {
41
+ hit_points : 5 ,
42
+ score_value : 3 ,
43
+ } ) ;
25
44
}
26
45
}
27
46
28
47
#[ test]
29
48
fn did_hurt_enemy ( ) {
30
- // Setup world
31
- let mut world = World :: default ( ) ;
49
+ // Setup app
50
+ let mut app = App :: new ( ) ;
51
+
52
+ // Add Score resource
53
+ app. insert_resource ( Score ( 0 ) ) ;
32
54
33
- // Setup stage with our two systems
34
- let mut update_stage = SystemStage :: parallel ( ) ;
35
- update_stage. add_system ( hurt_enemies. before ( despawn_dead_enemies) ) ;
36
- update_stage. add_system ( despawn_dead_enemies) ;
55
+ // Add `EnemyDied` event
56
+ app. add_event :: < EnemyDied > ( ) ;
57
+
58
+ // Add our two systems
59
+ app. add_system ( hurt_enemies. before ( despawn_dead_enemies) ) ;
60
+ app. add_system ( despawn_dead_enemies) ;
37
61
38
62
// Setup test entities
39
- let enemy_id = world. spawn ( ) . insert ( Enemy { hit_points : 5 } ) . id ( ) ;
63
+ let enemy_id = app
64
+ . world
65
+ . spawn ( )
66
+ . insert ( Enemy {
67
+ hit_points : 5 ,
68
+ score_value : 3 ,
69
+ } )
70
+ . id ( ) ;
40
71
41
72
// Run systems
42
- update_stage . run ( & mut world ) ;
73
+ app . update ( ) ;
43
74
44
75
// Check resulting changes
45
- assert ! ( world. get:: <Enemy >( enemy_id) . is_some( ) ) ;
46
- assert_eq ! ( world. get:: <Enemy >( enemy_id) . unwrap( ) . hit_points, 4 ) ;
76
+ assert ! ( app . world. get:: <Enemy >( enemy_id) . is_some( ) ) ;
77
+ assert_eq ! ( app . world. get:: <Enemy >( enemy_id) . unwrap( ) . hit_points, 4 ) ;
47
78
}
48
79
49
80
#[ test]
50
81
fn did_despawn_enemy ( ) {
51
- // Setup world
52
- let mut world = World :: default ( ) ;
82
+ // Setup app
83
+ let mut app = App :: new ( ) ;
84
+
85
+ // Add Score resource
86
+ app. insert_resource ( Score ( 0 ) ) ;
87
+
88
+ // Add `EnemyDied` event
89
+ app. add_event :: < EnemyDied > ( ) ;
53
90
54
- // Setup stage with our two systems
55
- let mut update_stage = SystemStage :: parallel ( ) ;
56
- update_stage. add_system ( hurt_enemies. before ( despawn_dead_enemies) ) ;
57
- update_stage. add_system ( despawn_dead_enemies) ;
91
+ // Add our two systems
92
+ app. add_system ( hurt_enemies. before ( despawn_dead_enemies) ) ;
93
+ app. add_system ( despawn_dead_enemies) ;
58
94
59
95
// Setup test entities
60
- let enemy_id = world. spawn ( ) . insert ( Enemy { hit_points : 1 } ) . id ( ) ;
96
+ let enemy_id = app
97
+ . world
98
+ . spawn ( )
99
+ . insert ( Enemy {
100
+ hit_points : 1 ,
101
+ score_value : 1 ,
102
+ } )
103
+ . id ( ) ;
61
104
62
105
// Run systems
63
- update_stage . run ( & mut world ) ;
106
+ app . update ( ) ;
64
107
65
- // Check resulting changes
66
- assert ! ( world. get:: <Enemy >( enemy_id) . is_none( ) ) ;
108
+ // Check enemy was despawned
109
+ assert ! ( app. world. get:: <Enemy >( enemy_id) . is_none( ) ) ;
110
+
111
+ // Get `EnemyDied` event reader
112
+ let enemy_died_events = app. world . resource :: < Events < EnemyDied > > ( ) ;
113
+ let mut enemy_died_reader = enemy_died_events. get_reader ( ) ;
114
+ let enemy_died = enemy_died_reader. iter ( enemy_died_events) . next ( ) . unwrap ( ) ;
115
+
116
+ // Check the event has been sent
117
+ assert_eq ! ( enemy_died. 0 , 1 ) ;
67
118
}
68
119
69
120
#[ test]
70
121
fn spawn_enemy_using_input_resource ( ) {
71
- // Setup world
72
- let mut world = World :: default ( ) ;
122
+ // Setup app
123
+ let mut app = App :: new ( ) ;
73
124
74
- // Setup stage with a system
75
- let mut update_stage = SystemStage :: parallel ( ) ;
76
- update_stage. add_system ( spawn_enemy) ;
125
+ // Add our systems
126
+ app. add_system ( spawn_enemy) ;
77
127
78
128
// Setup test resource
79
129
let mut input = Input :: < KeyCode > :: default ( ) ;
80
130
input. press ( KeyCode :: Space ) ;
81
- world . insert_resource ( input) ;
131
+ app . insert_resource ( input) ;
82
132
83
133
// Run systems
84
- update_stage . run ( & mut world ) ;
134
+ app . update ( ) ;
85
135
86
136
// Check resulting changes, one entity has been spawned with `Enemy` component
87
- assert_eq ! ( world. query:: <& Enemy >( ) . iter( & world) . len( ) , 1 ) ;
137
+ assert_eq ! ( app . world. query:: <& Enemy >( ) . iter( & app . world) . len( ) , 1 ) ;
88
138
89
139
// Clear the `just_pressed` status for all `KeyCode`s
90
- world. resource_mut :: < Input < KeyCode > > ( ) . clear ( ) ;
140
+ app . world . resource_mut :: < Input < KeyCode > > ( ) . clear ( ) ;
91
141
92
142
// Run systems
93
- update_stage . run ( & mut world ) ;
143
+ app . update ( ) ;
94
144
95
145
// Check resulting changes, no new entity has been spawned
96
- assert_eq ! ( world. query:: <& Enemy >( ) . iter( & world) . len( ) , 1 ) ;
146
+ assert_eq ! ( app. world. query:: <& Enemy >( ) . iter( & app. world) . len( ) , 1 ) ;
147
+ }
148
+
149
+ #[ test]
150
+ fn update_score_on_event ( ) {
151
+ // Setup app
152
+ let mut app = App :: new ( ) ;
153
+
154
+ // Add Score resource
155
+ app. insert_resource ( Score ( 0 ) ) ;
156
+
157
+ // Add `EnemyDied` event
158
+ app. add_event :: < EnemyDied > ( ) ;
159
+
160
+ // Add our systems
161
+ app. add_system ( update_score) ;
162
+
163
+ // Send an `EnemyDied` event
164
+ app. world
165
+ . resource_mut :: < Events < EnemyDied > > ( )
166
+ . send ( EnemyDied ( 3 ) ) ;
167
+
168
+ // Run systems
169
+ app. update ( ) ;
170
+
171
+ // Check resulting changes
172
+ assert_eq ! ( app. world. resource:: <Score >( ) . 0 , 3 ) ;
97
173
}
0 commit comments