Projectile spawn

This commit is contained in:
Rendo 2025-11-15 20:29:43 +05:00
commit 1ea451993d
3 changed files with 67 additions and 12 deletions

View file

@ -14,6 +14,9 @@ pub struct Projectile {
despawn_countdown: Timer, despawn_countdown: Timer,
} }
#[derive(Resource)]
pub struct ProjectileSprite(Handle<Image>);
pub struct ProjectilePlugin; pub struct ProjectilePlugin;
impl Projectile { impl Projectile {
@ -28,10 +31,15 @@ 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(FixedPreUpdate, projectile_despawn_countdown); app.add_systems(Startup, projectile_startup)
.add_systems(FixedPreUpdate, projectile_despawn_countdown);
} }
} }
pub fn projectile_startup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.insert_resource(ProjectileSprite(asset_server.load("projectile.png")));
}
pub fn projectile_despawn_countdown( pub fn projectile_despawn_countdown(
mut commands: Commands, mut commands: Commands,
time: Res<Time>, time: Res<Time>,
@ -47,16 +55,17 @@ pub fn projectile_despawn_countdown(
pub fn spawn_projectile( pub fn spawn_projectile(
commands: &mut Commands, commands: &mut Commands,
sprite: Handle<Image>, sprite: Res<ProjectileSprite>,
transform: Transform,
damage: u32, damage: u32,
faction: Factions, faction: Factions,
) { ) {
commands commands
.spawn(( .spawn((
Projectile::new(damage, faction), Projectile::new(damage, faction),
Sprite::from(sprite), Sprite::from(sprite.0.clone()),
Collider::new(8.), Collider::new(8.),
Transform::from_xyz(0., 0., 0.), transform,
Velocity::moving(128.0, 0.0), Velocity::moving(128.0, 0.0),
)) ))
.observe(observe_collision); .observe(observe_collision);

View file

@ -40,18 +40,22 @@ impl Plugin for ShipsPlugin {
fn build(&self, app: &mut bevy::app::App) { fn build(&self, app: &mut bevy::app::App) {
app.insert_resource(Time::<Fixed>::from_hz(60.)) app.insert_resource(Time::<Fixed>::from_hz(60.))
.add_systems(Startup, startup) .add_systems(Startup, startup)
.add_systems(FixedUpdate, player::player_movement_system); .add_systems(
FixedUpdate,
(
player::player_movement_system,
player::player_shooting_system,
),
);
} }
} }
fn startup(mut commands: Commands, asset_server: Res<AssetServer>) { fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {
let player_sprite: Handle<Image> = asset_server.load("player.png"); let player_sprite: Handle<Image> = asset_server.load("player.png");
let enemy_sprite: Handle<Image> = asset_server.load("enemy.png"); let enemy_sprite: Handle<Image> = asset_server.load("enemy.png");
let projectile: Handle<Image> = asset_server.load("projectile.png");
commands.spawn(Camera2d); commands.spawn(Camera2d);
player::spawn_player(&mut commands, player_sprite, Vec2::new(0., 0.)); player::spawn_player(&mut commands, player_sprite, Vec2::new(0., 0.));
enemy::spawn_enemy(&mut commands, enemy_sprite.clone(), Vec2::new(100., 100.)); enemy::spawn_enemy(&mut commands, enemy_sprite.clone(), Vec2::new(100., 100.));
spawn_projectile(&mut commands, projectile, 1, Factions::PlayerFaction);
} }

View file

@ -1,26 +1,43 @@
use crate::{collision::Collider, damagable::Damagable, ships::Factions, velocity::Velocity}; use crate::{
collision::Collider,
damagable::Damagable,
projectile::{ProjectileSprite, spawn_projectile},
ships::Factions,
velocity::Velocity,
};
use bevy::prelude::*; use bevy::prelude::*;
#[derive(Component)] #[derive(Component)]
#[require(Velocity, Damagable)] #[require(Velocity)]
pub struct Player { pub struct PlayerMovement {
pub(super) acceleration: f32, pub(super) acceleration: 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((
Player { acceleration: 100. }, PlayerMovement { acceleration: 100. },
PlayerGun {
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.),
Factions::PlayerFaction, Factions::PlayerFaction,
Damagable::new(15),
)); ));
} }
pub(super) fn player_movement_system( pub(super) fn player_movement_system(
time: Res<Time>, time: Res<Time>,
keyboard_input: Res<ButtonInput<KeyCode>>, keyboard_input: Res<ButtonInput<KeyCode>>,
query: Single<(&mut Velocity, &Player)>, query: Single<(&mut Velocity, &PlayerMovement)>,
) { ) {
let (mut movable, player) = query.into_inner(); let (mut movable, player) = query.into_inner();
let mut movement_factor = 0.0; let mut movement_factor = 0.0;
@ -45,3 +62,28 @@ pub(super) fn player_movement_system(
.clamp(-movable.max_linear_speed, movable.max_linear_speed); .clamp(-movable.max_linear_speed, movable.max_linear_speed);
movable.rotation_speed = rotation_factor * movable.max_rotation_speed; movable.rotation_speed = rotation_factor * movable.max_rotation_speed;
} }
pub fn player_shooting_system(
mut commands: Commands,
time: Res<Time>,
keyboard_input: Res<ButtonInput<KeyCode>>,
projectile_sprite: Res<ProjectileSprite>,
query: Single<(&mut PlayerGun, &Transform)>,
) {
let (mut gun, transform) = query.into_inner();
gun.shoot_timer.tick(time.delta());
if gun.shoot_timer.is_finished() == false || keyboard_input.pressed(KeyCode::Space) == false {
return;
}
spawn_projectile(
&mut commands,
projectile_sprite,
transform.clone(),
gun.damage,
Factions::PlayerFaction,
);
gun.shoot_timer.reset();
}