@@ -34,6 +34,11 @@ struct SnakeHead {
3434 direction : Direction ,
3535}
3636
37+ struct GrowthEvent ;
38+
39+ #[ derive( Default ) ]
40+ struct LastTailPosition ( Option < Position > ) ;
41+
3742#[ derive( Component ) ]
3843struct SnakeSegment ;
3944
@@ -103,6 +108,7 @@ fn spawn_segment(mut commands: Commands, position: Position) -> Entity {
103108}
104109
105110fn snake_movement (
111+ mut last_tail_position : ResMut < LastTailPosition > ,
106112 segments : ResMut < SnakeSegments > ,
107113 mut heads : Query < ( Entity , & SnakeHead ) > ,
108114 mut positions : Query < & mut Position > ,
@@ -133,6 +139,7 @@ fn snake_movement(
133139 . for_each ( |( pos, segment) | {
134140 * positions. get_mut ( * segment) . unwrap ( ) = * pos;
135141 } ) ;
142+ * last_tail_position = LastTailPosition ( Some ( * segment_positions. last ( ) . unwrap ( ) ) ) ;
136143 }
137144}
138145
@@ -154,6 +161,32 @@ fn snake_movement_input(keyboard_input: Res<Input<KeyCode>>, mut heads: Query<&m
154161 }
155162 }
156163}
164+ fn snake_eating (
165+ mut commands : Commands ,
166+ mut growth_writer : EventWriter < GrowthEvent > ,
167+ food_positions : Query < ( Entity , & Position ) , With < Food > > ,
168+ head_positions : Query < & Position , With < SnakeHead > > ,
169+ ) {
170+ for head_pos in head_positions. iter ( ) {
171+ for ( ent, food_pos) in food_positions. iter ( ) {
172+ if food_pos == head_pos {
173+ commands. entity ( ent) . despawn ( ) ;
174+ growth_writer. send ( GrowthEvent ) ;
175+ }
176+ }
177+ }
178+ }
179+
180+ fn snake_growth (
181+ commands : Commands ,
182+ last_tail_position : Res < LastTailPosition > ,
183+ mut segments : ResMut < SnakeSegments > ,
184+ mut growth_reader : EventReader < GrowthEvent > ,
185+ ) {
186+ if growth_reader. iter ( ) . next ( ) . is_some ( ) {
187+ segments. push ( spawn_segment ( commands, last_tail_position. 0 . unwrap ( ) ) ) ;
188+ }
189+ }
157190
158191fn size_scaling ( windows : Res < Windows > , mut q : Query < ( & Size , & mut Transform ) > ) {
159192 let window = windows. get_primary ( ) . unwrap ( ) ;
@@ -209,13 +242,17 @@ fn main() {
209242 } )
210243 . add_startup_system ( setup_camera)
211244 . add_startup_system ( spawn_snake)
245+ . insert_resource ( SnakeSegments :: default ( ) )
246+ . insert_resource ( LastTailPosition :: default ( ) )
247+ . add_event :: < GrowthEvent > ( )
212248 . add_system ( snake_movement_input. before ( snake_movement) )
213249 . add_system_set (
214250 SystemSet :: new ( )
215251 . with_run_criteria ( FixedTimestep :: step ( 0.150 ) )
216- . with_system ( snake_movement) ,
252+ . with_system ( snake_movement)
253+ . with_system ( snake_eating. after ( snake_movement) )
254+ . with_system ( snake_growth. after ( snake_eating) ) ,
217255 )
218- . insert_resource ( SnakeSegments :: default ( ) )
219256 . add_system_set (
220257 SystemSet :: new ( )
221258 . with_run_criteria ( FixedTimestep :: step ( 1.0 ) )
0 commit comments