From ef055fe3c51efbd60987fff6e7c1e9ff1e666fad Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Sat, 5 Apr 2025 19:21:09 +0200 Subject: [PATCH] feat: Add enemy type differentiation and adjust movement logic for Grunt and Boss enemies --- .gitignore | 2 +- README.md | 6 +-- src/main.rs | 122 +++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 92 insertions(+), 38 deletions(-) diff --git a/.gitignore b/.gitignore index f649208..7e17b2b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ /target /.direnv /logs -.idea/workspace.xml +/.idea diff --git a/README.md b/README.md index 1f04e1e..8b33cbf 100644 --- a/README.md +++ b/README.md @@ -69,13 +69,13 @@ nix develop --command bash -c "cargo build" * ~~Make enemies fire bullets (downwards or towards the player) during their dives.~~ **(DONE - Downward)** * After an attack dive, enemies could return to their formation position or fly off-screen. **(Fly off-screen implemented)** * **Enemy Variety:** - * Introduce different types of enemies (e.g., using different components or an enum). - * Assign different behaviors, point values, and maybe sprites to each type. + * ~~Introduce different types of enemies (e.g., using different components or an enum).~~ **(DONE - Added EnemyType enum and field)** + * ~~Assign different behaviors, point values, and maybe sprites to each type.~~ **(DONE - Behaviors, points & color based on type)** **3. Advanced Galaga Mechanics:** * **Boss Galaga & Capture Beam:** - * Create a "Boss" enemy type. + * ~~Create a "Boss" enemy type.~~ **(DONE - Added to Enum, handled in matches)** * Implement the tractor beam attack (visual effect, player capture logic). * Player needs a `Captured` state. * Logic for the Boss to return captured ships to the formation. diff --git a/src/main.rs b/src/main.rs index cbbbc91..bd7de2d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -48,6 +48,7 @@ struct Bullet; #[derive(Component)] struct Enemy { + enemy_type: EnemyType, // Add type field shoot_cooldown: Timer, } @@ -70,6 +71,12 @@ enum EnemyState { #[derive(Component)] struct EnemyBullet; +#[derive(Component, Clone, Copy, PartialEq, Eq, Debug)] // Added derive for common traits +pub enum EnemyType { + Grunt, + Boss, // Added Boss type +} + // --- Resources --- #[derive(Resource)] struct EnemySpawnTimer { @@ -625,10 +632,19 @@ fn spawn_enemies( let spawn_x = (fastrand::f32() - 0.5) * (WINDOW_WIDTH - ENEMY_SIZE.x); let spawn_y = WINDOW_HEIGHT / 2.0 - ENEMY_SIZE.y / 2.0; + // Determine enemy type (currently always Grunt) + let enemy_type = EnemyType::Grunt; + + // Determine sprite color based on type + let sprite_color = match enemy_type { + EnemyType::Grunt => Color::rgb(1.0, 0.2, 0.2), // Red for Grunts + EnemyType::Boss => Color::rgb(0.8, 0.2, 1.0), // Purple for Bosses + }; + commands.spawn(( SpriteBundle { sprite: Sprite { - color: Color::rgb(1.0, 0.2, 0.2), + color: sprite_color, // Use determined color custom_size: Some(ENEMY_SIZE), ..default() }, @@ -636,6 +652,7 @@ fn spawn_enemies( ..default() }, Enemy { + enemy_type, // Use the defined type // Initialize cooldown, maybe slightly randomized later shoot_cooldown: Timer::new( Duration::from_secs_f32(ENEMY_SHOOT_INTERVAL), @@ -672,8 +689,8 @@ fn move_enemies( (With, With), >, mut attacking_query: Query< - (Entity, &mut Transform, &EnemyState), // Add &EnemyState here - (With, Without), // Keep With filter if desired, but we check explicitly below + (Entity, &mut Transform, &EnemyState, &Enemy), // Add &Enemy here + (With, Without), >, // Query potential attackers time: Res