refactor: clean up formatting and improve readability in components and player logic
This commit is contained in:
parent
008f9cc24a
commit
d27d27bb5a
|
@ -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: 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
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
|
@ -53,8 +53,8 @@ pub struct FormationTarget {
|
|||
// Enum defining different ways an enemy can attack
|
||||
#[derive(Component, Clone, Copy, PartialEq, Debug)]
|
||||
pub enum AttackPattern {
|
||||
SwoopDive, // Original pattern: dive towards center, then off screen
|
||||
DirectDive, // Dive straight down
|
||||
SwoopDive, // Original pattern: dive towards center, then off screen
|
||||
DirectDive, // Dive straight down
|
||||
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
|
||||
// Add more patterns later (e.g., FigureEight, Looping)
|
||||
|
|
|
@ -31,7 +31,8 @@ pub const BULLET_ENEMY_COLLISION_THRESHOLD: f32 = (BULLET_SIZE.x + ENEMY_SIZE.x)
|
|||
// 22.5
|
||||
pub const PLAYER_ENEMY_COLLISION_THRESHOLD: f32 = (PLAYER_SIZE.x + ENEMY_SIZE.x) * 0.5;
|
||||
// 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
|
||||
pub const TRACTOR_BEAM_WIDTH: f32 = 20.0;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use bevy::prelude::*;
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::components::{Bullet, Enemy, Invincible, Player, Captured};
|
||||
use crate::components::{Bullet, Captured, Enemy, Invincible, Player};
|
||||
use crate::constants::{
|
||||
BULLET_SIZE, PLAYER_ENEMY_COLLISION_THRESHOLD, PLAYER_INVINCIBILITY_DURATION, PLAYER_SIZE,
|
||||
PLAYER_SPEED, WINDOW_HEIGHT, WINDOW_WIDTH,
|
||||
|
@ -79,48 +79,68 @@ pub fn handle_captured_player(
|
|||
) {
|
||||
// First, collect data from all captured players
|
||||
let mut to_process = Vec::new();
|
||||
|
||||
|
||||
for (entity, transform, captured) in player_query.iter() {
|
||||
// Check if the boss exists
|
||||
let boss_exists = enemy_query.get(captured.boss_entity).is_ok();
|
||||
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 {
|
||||
None
|
||||
};
|
||||
|
||||
|
||||
// Create a copy of the timer to check if it would finish
|
||||
let mut timer_copy = captured.timer.clone();
|
||||
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
|
||||
for (entity, current_pos, boss_pos_opt, timer_would_finish) in to_process {
|
||||
if let Ok((mut transform, mut captured)) = player_mut_query.get_mut(entity) {
|
||||
// Tick the real timer
|
||||
captured.timer.tick(time.delta());
|
||||
|
||||
|
||||
match boss_pos_opt {
|
||||
Some(boss_pos) => {
|
||||
// Boss exists, update player position
|
||||
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);
|
||||
},
|
||||
}
|
||||
None => {
|
||||
// Boss is gone, release player but lose a life
|
||||
println!("Boss is gone, releasing captured player!");
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If capture duration expires, player escapes but loses a life
|
||||
if timer_would_finish || captured.timer.finished() {
|
||||
println!("Player escaped from capture after timer expired!");
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -137,10 +157,10 @@ fn lose_life_and_respawn(
|
|||
// Lose a life
|
||||
lives.count = lives.count.saturating_sub(1);
|
||||
println!("Lives remaining: {}", lives.count);
|
||||
|
||||
|
||||
// Destroy player
|
||||
commands.entity(player_entity).despawn();
|
||||
|
||||
|
||||
if lives.count > 0 {
|
||||
respawn_timer.timer.reset();
|
||||
respawn_timer.timer.unpause();
|
||||
|
@ -192,7 +212,10 @@ pub fn check_player_enemy_collisions(
|
|||
mut respawn_timer: ResMut<PlayerRespawnTimer>,
|
||||
mut next_state: ResMut<NextState<AppState>>, // Resource to change state
|
||||
// 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>>,
|
||||
) {
|
||||
// This system only runs if player exists and is not invincible, due to run_if
|
||||
|
@ -271,4 +294,4 @@ pub fn manage_invincibility(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue