refactor: clean up formatting and improve readability in components and player logic

This commit is contained in:
Harald Hoyer 2025-04-16 08:46:12 +02:00
parent 008f9cc24a
commit d27d27bb5a
3 changed files with 47 additions and 23 deletions

View file

@ -39,10 +39,10 @@ pub struct Captured {
// New component for the tractor beam visual effect // New component for the tractor beam visual effect
#[derive(Component)] #[derive(Component)]
pub struct TractorBeam { pub struct TractorBeam {
pub target: Entity, // The entity being targeted (usually player) pub target: Entity, // The entity being targeted (usually player)
pub timer: Timer, // How long the beam lasts pub timer: Timer, // How long the beam lasts
pub width: f32, // Visual width of the beam pub width: f32, // Visual width of the beam
pub active: bool, // Whether the beam is currently active pub active: bool, // Whether the beam is currently active
} }
#[derive(Component)] #[derive(Component)]
@ -53,8 +53,8 @@ pub struct FormationTarget {
// Enum defining different ways an enemy can attack // Enum defining different ways an enemy can attack
#[derive(Component, Clone, Copy, PartialEq, Debug)] #[derive(Component, Clone, Copy, PartialEq, Debug)]
pub enum AttackPattern { pub enum AttackPattern {
SwoopDive, // Original pattern: dive towards center, then off screen SwoopDive, // Original pattern: dive towards center, then off screen
DirectDive, // Dive straight down DirectDive, // Dive straight down
Kamikaze(Vec3), // Dive towards a specific target location (e.g., player's last known position) - Needs target Vec3 Kamikaze(Vec3), // Dive towards a specific target location (e.g., player's last known position) - Needs target Vec3
CaptureBeam, // New pattern: Boss dives and attempts to capture the player with a tractor beam CaptureBeam, // New pattern: Boss dives and attempts to capture the player with a tractor beam
// Add more patterns later (e.g., FigureEight, Looping) // Add more patterns later (e.g., FigureEight, Looping)

View file

@ -31,7 +31,8 @@ pub const BULLET_ENEMY_COLLISION_THRESHOLD: f32 = (BULLET_SIZE.x + ENEMY_SIZE.x)
// 22.5 // 22.5
pub const PLAYER_ENEMY_COLLISION_THRESHOLD: f32 = (PLAYER_SIZE.x + ENEMY_SIZE.x) * 0.5; pub const PLAYER_ENEMY_COLLISION_THRESHOLD: f32 = (PLAYER_SIZE.x + ENEMY_SIZE.x) * 0.5;
// 35.0 // 35.0
pub const ENEMY_BULLET_PLAYER_COLLISION_THRESHOLD: f32 = (ENEMY_BULLET_SIZE.x + PLAYER_SIZE.x) * 0.5; pub const ENEMY_BULLET_PLAYER_COLLISION_THRESHOLD: f32 =
(ENEMY_BULLET_SIZE.x + PLAYER_SIZE.x) * 0.5;
// Tractor beam constants // Tractor beam constants
pub const TRACTOR_BEAM_WIDTH: f32 = 20.0; pub const TRACTOR_BEAM_WIDTH: f32 = 20.0;

View file

@ -1,7 +1,7 @@
use bevy::prelude::*; use bevy::prelude::*;
use std::time::Duration; use std::time::Duration;
use crate::components::{Bullet, Enemy, Invincible, Player, Captured}; use crate::components::{Bullet, Captured, Enemy, Invincible, Player};
use crate::constants::{ use crate::constants::{
BULLET_SIZE, PLAYER_ENEMY_COLLISION_THRESHOLD, PLAYER_INVINCIBILITY_DURATION, PLAYER_SIZE, BULLET_SIZE, PLAYER_ENEMY_COLLISION_THRESHOLD, PLAYER_INVINCIBILITY_DURATION, PLAYER_SIZE,
PLAYER_SPEED, WINDOW_HEIGHT, WINDOW_WIDTH, PLAYER_SPEED, WINDOW_HEIGHT, WINDOW_WIDTH,
@ -84,7 +84,10 @@ pub fn handle_captured_player(
// Check if the boss exists // Check if the boss exists
let boss_exists = enemy_query.get(captured.boss_entity).is_ok(); let boss_exists = enemy_query.get(captured.boss_entity).is_ok();
let boss_pos = if boss_exists { let boss_pos = if boss_exists {
enemy_query.get(captured.boss_entity).map(|t| t.translation).ok() enemy_query
.get(captured.boss_entity)
.map(|t| t.translation)
.ok()
} else { } else {
None None
}; };
@ -93,7 +96,12 @@ pub fn handle_captured_player(
let mut timer_copy = captured.timer.clone(); let mut timer_copy = captured.timer.clone();
timer_copy.tick(time.delta()); timer_copy.tick(time.delta());
to_process.push((entity, transform.translation, boss_pos, timer_copy.finished())); to_process.push((
entity,
transform.translation,
boss_pos,
timer_copy.finished(),
));
} }
// Now process each player separately // Now process each player separately
@ -107,12 +115,18 @@ pub fn handle_captured_player(
// Boss exists, update player position // Boss exists, update player position
let target_pos = boss_pos - Vec3::new(0.0, PLAYER_SIZE.y + 10.0, 0.0); let target_pos = boss_pos - Vec3::new(0.0, PLAYER_SIZE.y + 10.0, 0.0);
transform.translation = current_pos.lerp(target_pos, 0.2); transform.translation = current_pos.lerp(target_pos, 0.2);
}, }
None => { None => {
// Boss is gone, release player but lose a life // Boss is gone, release player but lose a life
println!("Boss is gone, releasing captured player!"); println!("Boss is gone, releasing captured player!");
commands.entity(entity).remove::<Captured>(); commands.entity(entity).remove::<Captured>();
lose_life_and_respawn(&mut commands, &mut lives, &mut respawn_timer, &mut next_state, entity); lose_life_and_respawn(
&mut commands,
&mut lives,
&mut respawn_timer,
&mut next_state,
entity,
);
} }
} }
@ -120,7 +134,13 @@ pub fn handle_captured_player(
if timer_would_finish || captured.timer.finished() { if timer_would_finish || captured.timer.finished() {
println!("Player escaped from capture after timer expired!"); println!("Player escaped from capture after timer expired!");
commands.entity(entity).remove::<Captured>(); commands.entity(entity).remove::<Captured>();
lose_life_and_respawn(&mut commands, &mut lives, &mut respawn_timer, &mut next_state, entity); lose_life_and_respawn(
&mut commands,
&mut lives,
&mut respawn_timer,
&mut next_state,
entity,
);
} }
} }
} }
@ -192,7 +212,10 @@ pub fn check_player_enemy_collisions(
mut respawn_timer: ResMut<PlayerRespawnTimer>, mut respawn_timer: ResMut<PlayerRespawnTimer>,
mut next_state: ResMut<NextState<AppState>>, // Resource to change state mut next_state: ResMut<NextState<AppState>>, // Resource to change state
// Query player without Invincible component - relies on run_if condition too // Query player without Invincible component - relies on run_if condition too
player_query: Query<(Entity, &Transform), (With<Player>, Without<Invincible>, Without<Captured>)>, // Don't check collisions for captured players player_query: Query<
(Entity, &Transform),
(With<Player>, Without<Invincible>, Without<Captured>),
>, // Don't check collisions for captured players
enemy_query: Query<(Entity, &Transform), With<Enemy>>, enemy_query: Query<(Entity, &Transform), With<Enemy>>,
) { ) {
// This system only runs if player exists and is not invincible, due to run_if // This system only runs if player exists and is not invincible, due to run_if