Compare commits

...

2 commits

Author SHA1 Message Date
9c774fdccf Decouple gun from player 2025-11-16 17:45:58 +05:00
782e446c46 Unused content cleanup 2025-11-16 14:43:15 +05:00
5 changed files with 81 additions and 88 deletions

View file

@ -1,12 +1,6 @@
use bevy::prelude::*; use bevy::prelude::*;
use crate::{ use crate::{GameState, collision::Collided, damagable::Damagable, ships::Factions};
GameState,
collision::{Collided, Collider},
damagable::Damagable,
ships::Factions,
velocity::Velocity,
};
#[derive(Component)] #[derive(Component)]
pub struct Projectile { pub struct Projectile {
@ -16,7 +10,10 @@ pub struct Projectile {
} }
#[derive(Resource)] #[derive(Resource)]
pub struct ProjectileSprite(Handle<Image>); pub struct ProjectileSprite {
pub player_projectile: Handle<Image>,
pub enemy_projectile: Handle<Image>,
}
pub struct ProjectilePlugin; pub struct ProjectilePlugin;
@ -32,16 +29,20 @@ impl Projectile {
impl Plugin for ProjectilePlugin { impl Plugin for ProjectilePlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_systems(OnEnter(GameState::Game), projectile_startup) app.add_systems(Startup, projectile_startup)
.add_systems( .add_systems(
FixedPreUpdate, FixedPreUpdate,
projectile_despawn_countdown.run_if(in_state(GameState::Game)), projectile_despawn_countdown.run_if(in_state(GameState::Game)),
); )
.add_observer(observe_collision);
} }
} }
pub fn projectile_startup(mut commands: Commands, asset_server: Res<AssetServer>) { pub fn projectile_startup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.insert_resource(ProjectileSprite(asset_server.load("projectile.png"))); commands.insert_resource(ProjectileSprite {
player_projectile: asset_server.load("projectile.png"),
enemy_projectile: asset_server.load("enemy_projectile.png"),
});
} }
pub fn projectile_despawn_countdown( pub fn projectile_despawn_countdown(
@ -57,24 +58,6 @@ pub fn projectile_despawn_countdown(
} }
} }
pub fn spawn_projectile(
commands: &mut Commands,
sprite: Res<ProjectileSprite>,
transform: Transform,
damage: u32,
faction: Factions,
) {
commands
.spawn((
Projectile::new(damage, faction),
Sprite::from(sprite.0.clone()),
Collider::new(8.),
transform,
Velocity::moving(1024.0, 0.0),
))
.observe(observe_collision);
}
pub fn observe_collision( pub fn observe_collision(
collision: On<Collided>, collision: On<Collided>,
mut commands: Commands, mut commands: Commands,

59
src/ships/gun.rs Normal file
View file

@ -0,0 +1,59 @@
use bevy::prelude::*;
use rand::random_range;
use crate::{
collision::Collider,
projectile::{Projectile, ProjectileSprite},
ships::Factions,
velocity::Velocity,
};
#[derive(Component)]
pub struct Gun {
pub shoot: bool,
shoot_timer: Timer,
damage: u32,
spread_radius: f32,
}
impl Gun {
pub fn new(damage: u32, spread: f32, firerate: f32) -> Self {
Self {
shoot: false,
shoot_timer: Timer::from_seconds(firerate, TimerMode::Once),
damage,
spread_radius: spread,
}
}
}
pub fn gun_shooting_system(
mut commands: Commands,
time: Res<Time>,
projectile_sprite: Res<ProjectileSprite>,
query: Query<(&mut Gun, &Transform, &Factions)>,
) {
for (mut gun, transform, faction) in query {
gun.shoot_timer.tick(time.delta());
if gun.shoot_timer.is_finished() == false || gun.shoot == false {
return;
}
let mut bullet_transform = transform.clone();
bullet_transform.rotate_z(random_range(-gun.spread_radius..gun.spread_radius));
commands.spawn((
Projectile::new(gun.damage, faction.clone()),
bullet_transform,
Velocity::moving(1024., 0.),
Collider::new(8.),
Sprite::from(match faction {
Factions::EnemyFaction => projectile_sprite.enemy_projectile.clone(),
Factions::PlayerFaction => projectile_sprite.player_projectile.clone(),
}),
));
gun.shoot_timer.reset();
}
}

View file

@ -3,13 +3,13 @@ use bevy::prelude::*;
use crate::GameState; use crate::GameState;
pub mod enemy; pub mod enemy;
pub mod gun;
pub mod player; pub mod player;
#[derive(Component)] #[derive(Component, Copy, Clone)]
pub enum Factions { pub enum Factions {
PlayerFaction, PlayerFaction,
EnemyFaction, EnemyFaction,
NeutralFaction,
} }
impl Factions { impl Factions {
@ -18,17 +18,10 @@ impl Factions {
Factions::PlayerFaction => match other { Factions::PlayerFaction => match other {
Factions::PlayerFaction => false, Factions::PlayerFaction => false,
Factions::EnemyFaction => true, Factions::EnemyFaction => true,
Factions::NeutralFaction => false,
}, },
Factions::EnemyFaction => match other { Factions::EnemyFaction => match other {
Factions::PlayerFaction => true, Factions::PlayerFaction => true,
Factions::EnemyFaction => false, Factions::EnemyFaction => false,
Factions::NeutralFaction => false,
},
Factions::NeutralFaction => match other {
Factions::EnemyFaction => false,
Factions::NeutralFaction => false,
Factions::PlayerFaction => false,
}, },
} }
} }
@ -44,7 +37,8 @@ impl Plugin for ShipsPlugin {
FixedUpdate, FixedUpdate,
( (
player::player_movement_system.run_if(in_state(GameState::Game)), player::player_movement_system.run_if(in_state(GameState::Game)),
player::player_shooting_system, player::player_shooting_system.run_if(in_state(GameState::Game)),
gun::gun_shooting_system.run_if(in_state(GameState::Game)),
), ),
); );
} }

View file

@ -1,8 +1,8 @@
use crate::{ use crate::{
collision::Collider, collision::Collider,
damagable::Damagable, damagable::Damagable,
projectile::{ProjectileSprite, spawn_projectile}, projectile::ProjectileSprite,
ships::Factions, ships::{Factions, gun::Gun},
velocity::Velocity, velocity::Velocity,
}; };
use bevy::prelude::*; use bevy::prelude::*;
@ -16,12 +16,6 @@ pub struct PlayerMovement {
stop_epsilon: f32, stop_epsilon: f32,
} }
#[derive(Component)]
pub struct PlayerGun {
shoot_timer: Timer,
damage: u32,
}
pub fn spawn_player(commands: &mut Commands, sprite: Handle<Image>, at: Vec2) { pub fn spawn_player(commands: &mut Commands, sprite: Handle<Image>, at: Vec2) {
commands.spawn(( commands.spawn((
PlayerMovement { PlayerMovement {
@ -29,10 +23,7 @@ pub fn spawn_player(commands: &mut Commands, sprite: Handle<Image>, at: Vec2) {
deceleration: 300., deceleration: 300.,
stop_epsilon: 50., stop_epsilon: 50.,
}, },
PlayerGun { Gun::new(1, f32::to_radians(15.), 0.2),
shoot_timer: Timer::from_seconds(0.2, TimerMode::Once),
damage: 1,
},
Collider::new(8.), Collider::new(8.),
Sprite::from(sprite), Sprite::from(sprite),
Transform::from_xyz(at.x, at.y, 0.), Transform::from_xyz(at.x, at.y, 0.),
@ -100,30 +91,9 @@ pub(super) fn player_movement_system(
} }
pub fn player_shooting_system( pub fn player_shooting_system(
mut commands: Commands,
time: Res<Time>,
keyboard_input: Res<ButtonInput<KeyCode>>, keyboard_input: Res<ButtonInput<KeyCode>>,
projectile_sprite: Res<ProjectileSprite>, query: Single<&mut Gun, With<PlayerMovement>>,
query: Single<(&mut PlayerGun, &Transform)>,
) { ) {
let (mut gun, transform) = query.into_inner(); let mut gun = query.into_inner();
gun.shoot_timer.tick(time.delta()); gun.shoot = keyboard_input.pressed(KeyCode::Space);
if gun.shoot_timer.is_finished() == false || keyboard_input.pressed(KeyCode::Space) == false {
return;
}
let five_degrees = f32::to_radians(5.);
let mut bullet_transform = transform.clone();
bullet_transform.rotate_z(random_range(-five_degrees..five_degrees));
spawn_projectile(
&mut commands,
projectile_sprite,
bullet_transform,
gun.damage,
Factions::PlayerFaction,
);
gun.shoot_timer.reset();
} }

View file

@ -24,19 +24,6 @@ pub struct Velocity {
} }
impl Velocity { impl Velocity {
pub fn new(
linear_speed: f32,
rotation_speed: f32,
max_linear_speed: f32,
max_rotation_speed: f32,
) -> Velocity {
Velocity {
linear_speed,
rotation_speed,
max_linear_speed: max_linear_speed,
max_rotation_speed: max_rotation_speed,
}
}
pub fn stopped(max_linear_speed: f32, max_rotation_speed: f32) -> Velocity { pub fn stopped(max_linear_speed: f32, max_rotation_speed: f32) -> Velocity {
Velocity { Velocity {
linear_speed: 0., linear_speed: 0.,