From ad2037a7a58362352b230685d717dcd275157cab Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Wed, 6 May 2026 21:36:26 +0200 Subject: [PATCH] refactor: idiomatic cleanup across the codebase MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Net -311 lines (1075 → 764). Build clean, clippy clean, 8 tests pass, headless render verified. Highlights: - player.rs: bug fix in handle_captured_player — was cloning captured.timer and ticking the clone, never the real timer. Consolidated kill_player as pub(crate) helper (was duplicated across 3 sites). Switched from ParamSet to two disjoint Queries. - enemy.rs: extracted step_attacker(), spawn_beam_visual(), end_beam(), pick_pattern() helpers — move_enemies is no longer 3-deep nested matches, beam cleanup no longer duplicated. Fixed SwoopDive overshoot check (was using already-applied movement). Mid-file `use` hoisted to top. - resources.rs: added StageConfigurations::for_stage() helper (was repeated 4×); FormationState/Score/CurrentStage now Default; extracted circle_formation() helper. - stage.rs: replaced raw world: &mut World access with ordinary ResMut system params (no need — resource types are disjoint). - game_state.rs: cleanup queries collapsed via Or<…> filters; dropped dead RestartMessage cleanup from cleanup_game_entities; button colors extracted as constants. - bullet.rs: reuses kill_player; introduced GRUNT_POINTS/BOSS_POINTS with TODO referencing GAL-27. - lib.rs: init_resource::() for Default-implementing resources. - Removed unused TRACTOR_BEAM_COLOR constant. - Replaced per-frame println! debug spam with targeted info!/warn!. - Stripped noise comments that restated what the code does. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/bullet.rs | 103 ++---- src/components.rs | 46 +-- src/constants.rs | 47 +-- src/enemy.rs | 902 ++++++++++++++++++---------------------------- src/game_state.rs | 87 ++--- src/lib.rs | 93 ++--- src/player.rs | 305 +++++++--------- src/resources.rs | 123 ++++--- src/stage.rs | 44 +-- src/starfield.rs | 37 +- src/systems.rs | 48 ++- 11 files changed, 762 insertions(+), 1073 deletions(-) diff --git a/src/bullet.rs b/src/bullet.rs index 2ab56c3..5481fb0 100644 --- a/src/bullet.rs +++ b/src/bullet.rs @@ -1,17 +1,17 @@ use bevy::prelude::*; -use crate::components::{Bullet, Enemy, EnemyBullet, EnemyType}; +use crate::components::{Bullet, Enemy, EnemyBullet, EnemyType, Invincible, Player}; use crate::constants::{ - BULLET_ENEMY_COLLISION_THRESHOLD, BULLET_SIZE, BULLET_SPEED, ENEMY_BULLET_PLAYER_COLLISION_THRESHOLD, - ENEMY_BULLET_SIZE, ENEMY_BULLET_SPEED, WINDOW_HEIGHT, + BULLET_ENEMY_COLLISION_THRESHOLD, BULLET_SIZE, BULLET_SPEED, + ENEMY_BULLET_PLAYER_COLLISION_THRESHOLD, ENEMY_BULLET_SIZE, ENEMY_BULLET_SPEED, WINDOW_HEIGHT, }; -use crate::resources::{PlayerLives, PlayerRespawnTimer, Score}; use crate::game_state::AppState; -use crate::components::Player; // Needed for check_enemy_bullet_player_collisions -use crate::components::Invincible; // Needed for check_enemy_bullet_player_collisions +use crate::player::kill_player; +use crate::resources::{PlayerLives, PlayerRespawnTimer, Score}; use crate::systems::spawn_explosion; -// --- Player Bullet Systems --- +const GRUNT_POINTS: u32 = 100; +const BOSS_POINTS: u32 = 100; // TODO(GAL-27): differentiate Boss from Grunt scoring pub fn move_bullets( mut query: Query<(Entity, &mut Transform), With>, @@ -20,7 +20,6 @@ pub fn move_bullets( ) { for (entity, mut transform) in query.iter_mut() { transform.translation.y += BULLET_SPEED * time.delta_secs(); - if transform.translation.y > WINDOW_HEIGHT / 2.0 + BULLET_SIZE.y { commands.entity(entity).despawn(); } @@ -30,35 +29,26 @@ pub fn move_bullets( pub fn check_bullet_collisions( mut commands: Commands, bullet_query: Query<(Entity, &Transform), With>, - enemy_query: Query<(Entity, &Transform, &Enemy), With>, // Fetch Enemy component too - mut score: ResMut, // Add Score resource + enemy_query: Query<(Entity, &Transform, &Enemy)>, + mut score: ResMut, ) { for (bullet_entity, bullet_transform) in bullet_query.iter() { - for (enemy_entity, enemy_transform, enemy) in enemy_query.iter() { - // Get Enemy component - let distance = bullet_transform - .translation - .distance(enemy_transform.translation); + let hit = enemy_query.iter().find(|(_, t, _)| { + bullet_transform.translation.distance(t.translation) < BULLET_ENEMY_COLLISION_THRESHOLD + }); - if distance < BULLET_ENEMY_COLLISION_THRESHOLD { - commands.entity(bullet_entity).despawn(); - spawn_explosion(&mut commands, enemy_transform.translation); - commands.entity(enemy_entity).despawn(); - // Increment score based on enemy type - let points = match enemy.enemy_type { - EnemyType::Grunt => 100, - EnemyType::Boss => 100, // Same points as Grunt for now - }; - score.value += points; - println!("Enemy hit by player bullet! Score: {}", score.value); // Log score update - break; // Bullet only hits one enemy - } + if let Some((enemy_entity, enemy_transform, enemy)) = hit { + commands.entity(bullet_entity).despawn(); + spawn_explosion(&mut commands, enemy_transform.translation); + commands.entity(enemy_entity).despawn(); + score.value += match enemy.enemy_type { + EnemyType::Grunt => GRUNT_POINTS, + EnemyType::Boss => BOSS_POINTS, + }; } } } -// --- Enemy Bullet Systems --- - pub fn move_enemy_bullets( mut commands: Commands, time: Res