129 lines
3.6 KiB
Rust
129 lines
3.6 KiB
Rust
use crate::{
|
|
collision::Collider,
|
|
damagable::Damagable,
|
|
projectile::{ProjectileSprite, spawn_projectile},
|
|
ships::Factions,
|
|
velocity::Velocity,
|
|
};
|
|
use bevy::prelude::*;
|
|
use rand::random_range;
|
|
|
|
#[derive(Component)]
|
|
#[require(Velocity)]
|
|
pub struct PlayerMovement {
|
|
acceleration: f32,
|
|
deceleration: 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) {
|
|
commands.spawn((
|
|
PlayerMovement {
|
|
acceleration: 100.,
|
|
deceleration: 300.,
|
|
stop_epsilon: 50.,
|
|
},
|
|
PlayerGun {
|
|
shoot_timer: Timer::from_seconds(0.2, TimerMode::Once),
|
|
damage: 1,
|
|
},
|
|
Collider::new(8.),
|
|
Sprite::from(sprite),
|
|
Transform::from_xyz(at.x, at.y, 0.),
|
|
Factions::PlayerFaction,
|
|
Damagable::new(15),
|
|
));
|
|
}
|
|
|
|
pub(super) fn player_movement_system(
|
|
time: Res<Time>,
|
|
keyboard_input: Res<ButtonInput<KeyCode>>,
|
|
query: Single<(&mut Velocity, &PlayerMovement)>,
|
|
) {
|
|
let (mut velocity, player) = query.into_inner();
|
|
let mut movement_factor = 0.0;
|
|
let mut rotation_factor = 0.0;
|
|
|
|
if keyboard_input.pressed(KeyCode::ArrowLeft) {
|
|
rotation_factor += 1.0;
|
|
}
|
|
|
|
if keyboard_input.pressed(KeyCode::ArrowRight) {
|
|
rotation_factor -= 1.0;
|
|
}
|
|
|
|
if keyboard_input.pressed(KeyCode::ArrowUp) {
|
|
movement_factor += 1.0;
|
|
}
|
|
if keyboard_input.pressed(KeyCode::ArrowDown) {
|
|
movement_factor -= 1.0;
|
|
}
|
|
|
|
if movement_factor > 0. {
|
|
if velocity.linear_speed >= 0. {
|
|
velocity.linear_speed = (velocity.linear_speed
|
|
+ player.acceleration * time.delta_secs())
|
|
.clamp(-velocity.max_linear_speed, velocity.max_linear_speed);
|
|
} else {
|
|
velocity.linear_speed = (velocity.linear_speed
|
|
+ player.deceleration * time.delta_secs())
|
|
.clamp(-velocity.max_linear_speed, velocity.max_linear_speed);
|
|
|
|
if velocity.linear_speed > -player.stop_epsilon {
|
|
velocity.linear_speed = 0.;
|
|
}
|
|
}
|
|
}
|
|
if movement_factor < 0. {
|
|
if velocity.linear_speed <= 0. {
|
|
velocity.linear_speed = (velocity.linear_speed
|
|
- player.acceleration * time.delta_secs())
|
|
.clamp(-velocity.max_linear_speed, velocity.max_linear_speed);
|
|
} else {
|
|
velocity.linear_speed = (velocity.linear_speed
|
|
- player.deceleration * time.delta_secs())
|
|
.clamp(-velocity.max_linear_speed, velocity.max_linear_speed);
|
|
|
|
if velocity.linear_speed < player.stop_epsilon {
|
|
velocity.linear_speed = 0.;
|
|
}
|
|
}
|
|
}
|
|
|
|
velocity.rotation_speed = rotation_factor * velocity.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;
|
|
}
|
|
|
|
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();
|
|
}
|