Browse Source

avoid spawning food on the snake tail

Getty Ritter 2 years ago
parent
commit
0b82fe8cea
1 changed files with 22 additions and 5 deletions
  1. 22 5
      src/main.rs

+ 22 - 5
src/main.rs

@@ -72,17 +72,34 @@ fn setup(mut commands: Commands, mut materials: ResMut<Assets<ColorMaterial>>) {
     });
 }
 
-fn food_spawner(mut commands: Commands, materials: Res<c::Materials>) {
+fn food_spawner(
+    mut commands: Commands,
+    materials: Res<c::Materials>,
+    segments: Query<&c::Position, With<c::SnakeSegment>>,
+) {
+    let snake_positions = segments.iter().collect::<Vec<&c::Position>>();
+    // try three times, giving up if we still haven't found a free spot
+    let mut x;
+    let mut y;
+    let mut attempts = 3;
+    loop {
+        x = (random::<f32>() * c::ARENA_WIDTH as f32) as i32;
+        y = (random::<f32>() * c::ARENA_HEIGHT as f32) as i32;
+        if !snake_positions.contains(&&c::Position {x, y}) {
+            break;
+        }
+        attempts -= 1;
+        if attempts == 0 {
+            return;
+        }
+    }
     commands
         .spawn_bundle(SpriteBundle {
             material: materials.food_material.clone(),
             ..Default::default()
         })
         .insert(c::Food)
-        .insert(c::Position {
-            x: (random::<f32>() * c::ARENA_WIDTH as f32) as i32,
-            y: (random::<f32>() * c::ARENA_HEIGHT as f32) as i32,
-        })
+        .insert(c::Position { x, y })
         .insert(c::GridSize::square(0.8));
 }