This commit is contained in:
Rendo 2025-11-17 16:42:15 +05:00
commit abb0198a2b
3 changed files with 88 additions and 10 deletions

View file

@ -3,22 +3,101 @@ use bevy::prelude::*;
use crate::{ use crate::{
collision::Collider, collision::Collider,
damagable::Damagable, damagable::Damagable,
ships::{Factions, gun::Gun}, ships::{Factions, gun::Gun, player::PlayerMovement},
velocity::Velocity, velocity::{self, Velocity},
}; };
#[derive(Component)] #[derive(Component)]
pub struct Enemy; pub struct Enemy {
state: EnemyState,
return_radius: f32,
search_arc: f32,
}
#[derive(PartialEq)]
enum EnemyState {
Approaching,
OriginalViolence,
Distancing,
}
pub fn spawn_enemy(commands: &mut Commands, sprite: Handle<Image>, at: Vec2) { pub fn spawn_enemy(commands: &mut Commands, sprite: Handle<Image>, at: Vec2) {
commands.spawn(( commands.spawn((
Enemy, Enemy {
Gun::new(5, f32::to_radians(15.), 0.2), state: EnemyState::Approaching,
return_radius: 128.0,
search_arc: f32::to_radians(5.),
},
Gun::new(2, f32::to_radians(15.), 0.2),
Collider::new(8.), Collider::new(8.),
Velocity::stopped(500., f32::to_radians(360.)), Velocity::moving(256., f32::to_radians(360.)),
Sprite::from(sprite), Sprite::from(sprite),
Transform::from_xyz(at.x, at.y, 0.), Transform::from_xyz(at.x, at.y, 0.),
Damagable::new(100), Damagable::new(100),
Factions::EnemyFaction, Factions::EnemyFaction,
)); ));
} }
pub fn enemy_ai_system(
player_query: Single<&Transform, (With<PlayerMovement>, Without<Enemy>)>,
enemies_query: Query<
(&mut Velocity, &mut Enemy, &mut Gun, &Transform),
Without<PlayerMovement>,
>,
) {
let player_transform = player_query.into_inner();
for (mut enemy_velocity, mut enemy, mut gun, enemy_transform) in enemies_query {
let direction = enemy_transform.rotation * Vec3::X;
let left_side = enemy_transform.rotation * Vec3::Y;
let dir_to_player = player_transform.translation - enemy_transform.translation;
let distance_to_player = enemy_transform
.translation
.distance_squared(player_transform.translation);
match enemy.state {
EnemyState::Approaching => {
if direction.angle_between(dir_to_player) <= enemy.search_arc {
enemy_velocity.rotation_speed = 0.;
gun.shoot = true;
enemy.state = EnemyState::OriginalViolence;
enemy_velocity.linear_speed = enemy_velocity.max_linear_speed / 2.0;
continue;
}
enemy_velocity.rotation_speed =
enemy_velocity.max_rotation_speed * (left_side.dot(dir_to_player)).signum();
}
EnemyState::OriginalViolence => {
gun.shoot = true;
if direction.angle_between(dir_to_player) > enemy.search_arc {
enemy_velocity.linear_speed = enemy_velocity.max_linear_speed;
enemy.state = EnemyState::Approaching;
gun.shoot = false;
continue;
}
if distance_to_player <= enemy.return_radius * enemy.return_radius {
enemy_velocity.linear_speed = enemy_velocity.max_linear_speed;
enemy.state = EnemyState::Distancing;
gun.shoot = false;
continue;
}
}
EnemyState::Distancing => {
if distance_to_player > enemy.return_radius * enemy.return_radius {
enemy.state = EnemyState::Approaching;
continue;
}
if direction.angle_between(dir_to_player) > f32::to_radians(90.) {
enemy_velocity.rotation_speed = 0.;
continue;
}
let angle_to_left = direction.angle_between(left_side);
if angle_to_left <= f32::to_radians(90.) {
enemy_velocity.rotation_speed = -enemy_velocity.max_rotation_speed
} else {
enemy_velocity.rotation_speed = enemy_velocity.max_rotation_speed
}
}
}
}
}

View file

@ -39,6 +39,7 @@ impl Plugin for ShipsPlugin {
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.run_if(in_state(GameState::Game)),
gun::gun_shooting_system.run_if(in_state(GameState::Game)), gun::gun_shooting_system.run_if(in_state(GameState::Game)),
enemy::enemy_ai_system,
), ),
); );
} }

View file

@ -1,12 +1,10 @@
use crate::{ use crate::{
collision::Collider, collision::Collider,
damagable::Damagable, damagable::Damagable,
projectile::ProjectileSprite, ships::{Factions, enemy::Enemy, gun::Gun},
ships::{Factions, gun::Gun},
velocity::Velocity, velocity::Velocity,
}; };
use bevy::prelude::*; use bevy::prelude::*;
use rand::random_range;
#[derive(Component)] #[derive(Component)]
#[require(Velocity)] #[require(Velocity)]
@ -92,7 +90,7 @@ pub(super) fn player_movement_system(
pub fn player_shooting_system( pub fn player_shooting_system(
keyboard_input: Res<ButtonInput<KeyCode>>, keyboard_input: Res<ButtonInput<KeyCode>>,
query: Single<&mut Gun, With<PlayerMovement>>, query: Single<&mut Gun, (With<PlayerMovement>, Without<Enemy>)>,
) { ) {
let mut gun = query.into_inner(); let mut gun = query.into_inner();
gun.shoot = keyboard_input.pressed(KeyCode::Space); gun.shoot = keyboard_input.pressed(KeyCode::Space);