Compare commits

..

No commits in common. "9c774fdccf90af56d62c0349cb522b5ac49d1169" and "b7aff68e3a602d49cbb9821f86778a8438f4c6c1" have entirely different histories.

5 changed files with 88 additions and 81 deletions

View file

@ -1,6 +1,12 @@
use bevy::prelude::*; use bevy::prelude::*;
use crate::{GameState, collision::Collided, damagable::Damagable, ships::Factions}; use crate::{
GameState,
collision::{Collided, Collider},
damagable::Damagable,
ships::Factions,
velocity::Velocity,
};
#[derive(Component)] #[derive(Component)]
pub struct Projectile { pub struct Projectile {
@ -10,10 +16,7 @@ pub struct Projectile {
} }
#[derive(Resource)] #[derive(Resource)]
pub struct ProjectileSprite { pub struct ProjectileSprite(Handle<Image>);
pub player_projectile: Handle<Image>,
pub enemy_projectile: Handle<Image>,
}
pub struct ProjectilePlugin; pub struct ProjectilePlugin;
@ -29,20 +32,16 @@ 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(Startup, projectile_startup) app.add_systems(OnEnter(GameState::Game), 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 { commands.insert_resource(ProjectileSprite(asset_server.load("projectile.png")));
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(
@ -58,6 +57,24 @@ 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,

View file

@ -1,59 +0,0 @@
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, Copy, Clone)] #[derive(Component)]
pub enum Factions { pub enum Factions {
PlayerFaction, PlayerFaction,
EnemyFaction, EnemyFaction,
NeutralFaction,
} }
impl Factions { impl Factions {
@ -18,10 +18,17 @@ 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,
}, },
} }
} }
@ -37,8 +44,7 @@ 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.run_if(in_state(GameState::Game)), player::player_shooting_system,
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, projectile::{ProjectileSprite, spawn_projectile},
ships::{Factions, gun::Gun}, ships::Factions,
velocity::Velocity, velocity::Velocity,
}; };
use bevy::prelude::*; use bevy::prelude::*;
@ -16,6 +16,12 @@ 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 {
@ -23,7 +29,10 @@ pub fn spawn_player(commands: &mut Commands, sprite: Handle<Image>, at: Vec2) {
deceleration: 300., deceleration: 300.,
stop_epsilon: 50., stop_epsilon: 50.,
}, },
Gun::new(1, f32::to_radians(15.), 0.2), 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.),
@ -91,9 +100,30 @@ 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>>,
query: Single<&mut Gun, With<PlayerMovement>>, projectile_sprite: Res<ProjectileSprite>,
query: Single<(&mut PlayerGun, &Transform)>,
) { ) {
let mut gun = query.into_inner(); let (mut gun, transform) = query.into_inner();
gun.shoot = keyboard_input.pressed(KeyCode::Space); gun.shoot_timer.tick(time.delta());
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,6 +24,19 @@ 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.,