1
- use bevy:: app:: { Events , ManualEventReader } ;
2
1
use bevy:: prelude:: * ;
2
+ use bevy:: {
3
+ app:: { Events , ManualEventReader } ,
4
+ core:: FixedTimestep ,
5
+ } ;
3
6
4
7
/// In this example, we show how to store events of a given type
5
8
/// as a component on individual entities rather than in a single resource.
@@ -39,6 +42,11 @@ fn main() {
39
42
. add_system ( add_number. system ( ) . label ( "action_handling" ) )
40
43
. add_system ( scale_selected. system ( ) . after ( "action_handling" ) )
41
44
. add_system ( update_text_color. system ( ) . after ( "action_handling" ) )
45
+ . add_system (
46
+ move_text
47
+ . system ( )
48
+ . with_run_criteria ( FixedTimestep :: step ( TIME_STEP ) ) ,
49
+ )
42
50
. run ( )
43
51
}
44
52
@@ -55,6 +63,7 @@ struct InteractableBundle {
55
63
selectable : Selectable ,
56
64
rainbow : ColorChoices ,
57
65
cycle_color_events : Events < CycleColorAction > ,
66
+ move_events : Events < MoveAction > ,
58
67
add_number_events : Events < AddNumberAction > ,
59
68
}
60
69
@@ -81,6 +90,7 @@ impl InteractableBundle {
81
90
selectable : Selectable ,
82
91
rainbow : ColorChoices :: Red ,
83
92
cycle_color_events : Events :: < CycleColorAction > :: default ( ) ,
93
+ move_events : Events <MoveAction >:: default ( ) ,
84
94
add_number_events : Events :: < AddNumberAction > :: default ( ) ,
85
95
}
86
96
}
@@ -201,7 +211,11 @@ fn input_dispatch(
201
211
// You could also access the &Events<T> component directly
202
212
// then send events to that component with `Events::send`
203
213
mut query : Query <
204
- ( EventWriter < CycleColorAction > , EventWriter < AddNumberAction > ) ,
214
+ (
215
+ EventWriter < CycleColorAction > ,
216
+ EventWriter < MoveAction > ,
217
+ EventWriter < AddNumberAction > ,
218
+ ) ,
205
219
With < Selectable > ,
206
220
> ,
207
221
selected : Res < Selected > ,
@@ -211,13 +225,27 @@ fn input_dispatch(
211
225
212
226
let ( mut cycle_actions, mut add_actions) = query. get_mut ( selected. entity ) . unwrap ( ) ;
213
227
214
- // Inputs for cycling colors
215
- if keyboard_input. just_pressed ( Space ) {
216
- cycle_actions. send ( CycleColorAction ) ;
217
- }
218
-
219
- // Inputs for sending numbers to be added
220
228
for key_code in keyboard_input. get_just_pressed ( ) {
229
+ match key_code {
230
+ // Color changing
231
+ Space => cycle_actions. send ( CycleColorAction ) ,
232
+ // Movement
233
+ Left => move_actions. send ( MoveAction {
234
+ transform : Transform :: from_xyz ( -MOVE_DISTANCE , 0.0 , 0.0 ) ,
235
+ } ) ,
236
+ Right => move_actions. send ( MoveAction {
237
+ transform : Transform :: from_xyz ( MOVE_DISTANCE , 0.0 , 0.0 ) ,
238
+ } ) ,
239
+ Down => move_actions. send ( MoveAction {
240
+ transform : Transform :: from_xyz ( 0.0 , -MOVE_DISTANCE , 0.0 ) ,
241
+ } ) ,
242
+ Up => move_actions. send ( MoveAction {
243
+ transform : Transform :: from_xyz ( 0.0 , MOVE_DISTANCE , 0.0 ) ,
244
+ } ) ,
245
+ _ => ( ) ,
246
+ }
247
+
248
+ // Inputs for sending numbers to be added
221
249
if ( key_code as u8 ) < 10 {
222
250
add_actions. send ( AddNumberAction {
223
251
// The keycode for KeyCode::Key1 is 0
@@ -265,3 +293,24 @@ fn add_number(
265
293
text. sections [ 0 ] . value = new_number. to_string ( ) ;
266
294
}
267
295
}
296
+
297
+ const MOVE_DISTANCE : f32 = 100.0 ;
298
+ const TIME_STEP : f32 = 2 ;
299
+ #[ derive( Default ) ]
300
+ struct MoveAction {
301
+ transform : Transform ,
302
+ }
303
+
304
+ // When events are registered in the AppBuilder using .add_event(),
305
+ // a system will automatically be created to clean them up after two frames.
306
+ // This can be problematic if your event-consuming systems ever skip frames (such as due to a fixed timestep run criteria).
307
+ // We can get around this by not registering them, and instead handling clean-up by consuming them when read.
308
+ // Be careful though: once consumed, other systems will not be able to read them!
309
+ fn move_text ( query : Query < ( & mut Transform , EventConsumer < MoveAction > ) > ) {
310
+ for ( mut transform, events) in query. iter ( ) {
311
+ // Unlike EventReaders which simply iterate, EventConsumers drain the events they read
312
+ for move_action in events. drain ( ) {
313
+ * transform += move_action. transform * TIME_STEP ;
314
+ }
315
+ }
316
+ }
0 commit comments