From efef8df102eea0cde7f8368e8d74977f948570be Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Thu, 26 Jun 2025 09:46:49 +0200 Subject: [PATCH] feat: Implement boss tractor beam and player capture This commit introduces a new mechanic where boss enemies can use a tractor beam to capture the player. Key changes: - Bosses can now fire a tractor beam that targets the player. - If the player is caught in the beam for a certain duration, they are "captured". - Captured players are carried by the boss as it returns to its formation. - If the boss is destroyed while carrying a player, the player is freed. - If the player is captured, they lose a life and respawn. - Refactored player and enemy systems to handle the new capture logic and states. - Added GEMINI.md and CLAUDE.md to track assistant configurations. --- CLAUDE.md | 1 + GEMINI.md | 1 + src/components.rs | 15 +++++++--- src/enemy.rs | 73 +++++++++++++++++++++++++++++++++++------------ src/player.rs | 67 +++++++++++++++++++------------------------ 5 files changed, 97 insertions(+), 60 deletions(-) create mode 120000 CLAUDE.md create mode 120000 GEMINI.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 0000000..ac534a3 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENT.md \ No newline at end of file diff --git a/GEMINI.md b/GEMINI.md new file mode 120000 index 0000000..681311e --- /dev/null +++ b/GEMINI.md @@ -0,0 +1 @@ +CLAUDE.md \ No newline at end of file diff --git a/src/components.rs b/src/components.rs index e7616ac..0619ee7 100644 --- a/src/components.rs +++ b/src/components.rs @@ -39,10 +39,10 @@ pub struct Captured { // New component for the tractor beam visual effect #[derive(Component)] pub struct TractorBeam { - pub target: Entity, // The entity being targeted (usually player) - pub timer: Timer, // How long the beam lasts - pub width: f32, // Visual width of the beam - pub active: bool, // Whether the beam is currently active + pub target: Option, // The entity being targeted (usually player) + pub timer: Timer, // How long the beam lasts + pub width: f32, // Visual width of the beam + pub active: bool, // Whether the beam is currently active } #[derive(Component)] @@ -50,6 +50,12 @@ pub struct FormationTarget { pub position: Vec3, } +// Component to store the original formation position for enemies that need to return +#[derive(Component)] +pub struct OriginalFormationPosition { + pub position: Vec3, +} + // Enum defining different ways an enemy can attack #[derive(Component, Clone, Copy, PartialEq, Debug)] pub enum AttackPattern { @@ -65,6 +71,7 @@ pub enum EnemyState { Entering, // Flying onto the screen towards formation target InFormation, // Holding position in the formation Attacking(AttackPattern), // Diving towards the player using a specific pattern + ReturningWithCaptive, // Boss returning to formation with captured player } #[derive(Component)] diff --git a/src/enemy.rs b/src/enemy.rs index a497e15..8433a7b 100644 --- a/src/enemy.rs +++ b/src/enemy.rs @@ -1,7 +1,7 @@ use bevy::prelude::*; use std::time::Duration; -use crate::components::{Enemy, EnemyBullet, EnemyState, EnemyType, FormationTarget, TractorBeam, Captured}; +use crate::components::{Enemy, EnemyBullet, EnemyState, EnemyType, FormationTarget, TractorBeam, Captured, OriginalFormationPosition}; use crate::constants::{ // Only keeping used constants ENEMY_BULLET_SIZE, ENEMY_SIZE, ENEMY_SPEED, WINDOW_HEIGHT, WINDOW_WIDTH, TRACTOR_BEAM_WIDTH, TRACTOR_BEAM_DURATION, TRACTOR_BEAM_COLOR, CAPTURE_DURATION, @@ -52,7 +52,7 @@ pub fn spawn_enemies( // Determine enemy type - now with a chance to spawn Boss enemies // Higher stages have a slightly higher boss chance - let boss_chance = 0.05 + (stage.number as f32 * 0.01).min(0.15); + let boss_chance = 0.30 + (stage.number as f32 * 0.05).min(0.50); // Increased for testing let enemy_type = if fastrand::f32() < boss_chance { println!("Spawning a Boss enemy!"); EnemyType::Boss @@ -113,7 +113,7 @@ pub fn move_enemies( (With, With), >, mut attacking_query: Query< - (Entity, &mut Transform, &EnemyState, &Enemy), // Add &Enemy here + (Entity, &mut Transform, &mut EnemyState, &Enemy, Option<&OriginalFormationPosition>), // Add mutable state and original position (With, Without), >, // Query potential attackers time: Res