Projectrile movement and moving refactor

This commit is contained in:
Rendo 2025-11-15 19:04:08 +05:00
commit 079341f5a8
8 changed files with 125 additions and 55 deletions

View file

@ -1,4 +1,5 @@
use bevy::prelude::*;
use std::default::Default;
pub struct DamagablePlugin;
@ -14,6 +15,12 @@ pub struct Damagable {
max_hp: u32,
}
impl Default for Damagable {
fn default() -> Self {
Self { max_hp: 15, hp: 15 }
}
}
impl Damagable {
pub fn new(max_hp: u32) -> Damagable {
Damagable { max_hp, hp: max_hp }

View file

@ -2,21 +2,23 @@ use bevy::prelude::*;
use crate::collision::CollisionPlugin;
use crate::damagable::DamagablePlugin;
use crate::movable::MovablePlugin;
use crate::projectile::ProjectilePlugin;
use crate::ships::ShipsPlugin;
use crate::velocity::VelocityPlugin;
mod collision;
mod damagable;
mod movable;
mod projectile;
mod ships;
mod velocity;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(MovablePlugin)
.add_plugins(VelocityPlugin)
.add_plugins(CollisionPlugin)
.add_plugins(ShipsPlugin)
.add_plugins(DamagablePlugin)
.add_plugins(ProjectilePlugin)
.run();
}

View file

@ -1,42 +0,0 @@
use bevy::prelude::*;
pub struct MovablePlugin;
impl Plugin for MovablePlugin {
fn build(&self, app: &mut App) {
app.insert_resource(Time::<Fixed>::from_hz(60.0))
.add_systems(FixedUpdate, movement_system);
}
}
#[derive(Component)]
pub struct Movable {
pub linear_speed: f32,
pub rotation_speed: f32,
pub max_linear_speed: f32,
pub max_rotation_speed: f32,
}
impl Movable {
pub fn new(max_linear_speed: f32, max_rotation_speed: f32) -> Movable {
Movable {
linear_speed: 0.,
rotation_speed: 0.,
max_linear_speed: max_linear_speed,
max_rotation_speed: max_rotation_speed,
}
}
}
fn movement_system(time: Res<Time>, query: Query<(&Movable, &mut Transform)>) {
for (movable, mut transform) in query {
transform.rotate_z(movable.rotation_speed * time.delta_secs());
let movement_direction = transform.rotation * Vec3::X;
let movement_distance = movable.linear_speed * time.delta_secs();
let translation_delta = movement_direction * movement_distance;
transform.translation += translation_delta;
//TODO: Loop on bounds
}
}

View file

@ -4,17 +4,44 @@ use crate::{
collision::{Collided, Collider},
damagable::Damagable,
ships::Factions,
velocity::Velocity,
};
#[derive(Component)]
pub struct Projectile {
damage: u32,
faction: Factions,
despawn_countdown: Timer,
}
pub struct ProjectilePlugin;
impl Projectile {
pub fn new(damage: u32, faction: Factions) -> Projectile {
Projectile { damage, faction }
Projectile {
damage,
faction,
despawn_countdown: Timer::from_seconds(20., TimerMode::Once),
}
}
}
impl Plugin for ProjectilePlugin {
fn build(&self, app: &mut App) {
app.add_systems(FixedPreUpdate, projectile_despawn_countdown);
}
}
pub fn projectile_despawn_countdown(
mut commands: Commands,
time: Res<Time>,
query: Query<(Entity, &mut Projectile)>,
) {
for (entity, mut projectile) in query {
projectile.despawn_countdown.tick(time.delta());
if projectile.despawn_countdown.is_finished() {
commands.get_entity(entity).unwrap().despawn();
}
}
}
@ -30,9 +57,11 @@ pub fn spawn_projectile(
Sprite::from(sprite),
Collider::new(8.),
Transform::from_xyz(0., 0., 0.),
Velocity::moving(128.0, 0.0),
))
.observe(observe_collision);
}
pub fn observe_collision(
collision: On<Collided>,
mut commands: Commands,

View file

@ -1,6 +1,6 @@
use bevy::prelude::*;
use crate::{collision::Collider, damagable::Damagable, movable::Movable, ships::Factions};
use crate::{collision::Collider, damagable::Damagable, ships::Factions, velocity::Velocity};
#[derive(Component)]
pub struct Enemy;
@ -9,7 +9,7 @@ pub fn spawn_enemy(commands: &mut Commands, sprite: Handle<Image>, at: Vec2) {
commands.spawn((
Enemy,
Collider::new(8.),
Movable::new(500., f32::to_radians(360.)),
Velocity::stopped(500., f32::to_radians(360.)),
Sprite::from(sprite),
Transform::from_xyz(at.x, at.y, 0.),
Damagable::new(10),

View file

@ -51,7 +51,7 @@ fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn(Camera2d);
player::spawn_player(&mut commands, player_sprite, Vec2::new(100., 100.));
enemy::spawn_enemy(&mut commands, enemy_sprite.clone(), Vec2::new(0., 0.));
spawn_projectile(&mut commands, projectile, 100, Factions::PlayerFaction);
player::spawn_player(&mut commands, player_sprite, Vec2::new(0., 0.));
enemy::spawn_enemy(&mut commands, enemy_sprite.clone(), Vec2::new(100., 100.));
spawn_projectile(&mut commands, projectile, 1, Factions::PlayerFaction);
}

View file

@ -1,7 +1,8 @@
use crate::{collision::Collider, damagable::Damagable, movable::Movable, ships::Factions};
use crate::{collision::Collider, damagable::Damagable, ships::Factions, velocity::Velocity};
use bevy::prelude::*;
#[derive(Component)]
#[require(Velocity, Damagable)]
pub struct Player {
pub(super) acceleration: f32,
}
@ -10,10 +11,8 @@ pub fn spawn_player(commands: &mut Commands, sprite: Handle<Image>, at: Vec2) {
commands.spawn((
Player { acceleration: 100. },
Collider::new(8.),
Movable::new(500., f32::to_radians(360.)),
Sprite::from(sprite),
Transform::from_xyz(at.x, at.y, 0.),
Damagable::new(10),
Factions::PlayerFaction,
));
}
@ -21,7 +20,7 @@ pub fn spawn_player(commands: &mut Commands, sprite: Handle<Image>, at: Vec2) {
pub(super) fn player_movement_system(
time: Res<Time>,
keyboard_input: Res<ButtonInput<KeyCode>>,
query: Single<(&mut Movable, &Player)>,
query: Single<(&mut Velocity, &Player)>,
) {
let (mut movable, player) = query.into_inner();
let mut movement_factor = 0.0;

75
src/velocity.rs Normal file
View file

@ -0,0 +1,75 @@
use bevy::prelude::*;
use std::default::Default;
pub struct VelocityPlugin;
impl Plugin for VelocityPlugin {
fn build(&self, app: &mut App) {
app.insert_resource(Time::<Fixed>::from_hz(60.0))
.add_systems(FixedUpdate, movement_system);
}
}
#[derive(Component)]
pub struct Velocity {
pub linear_speed: f32,
pub rotation_speed: f32,
pub max_linear_speed: f32,
pub max_rotation_speed: f32,
}
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 {
Velocity {
linear_speed: 0.,
rotation_speed: 0.,
max_linear_speed: max_linear_speed,
max_rotation_speed: max_rotation_speed,
}
}
pub fn moving(max_linear_speed: f32, max_rotation_speed: f32) -> Velocity {
Velocity {
linear_speed: max_linear_speed,
rotation_speed: 0.,
max_linear_speed: max_linear_speed,
max_rotation_speed: max_rotation_speed,
}
}
}
impl Default for Velocity {
fn default() -> Self {
Self {
linear_speed: 0.,
rotation_speed: 0.,
max_linear_speed: 64.,
max_rotation_speed: f32::to_radians(360.),
}
}
}
fn movement_system(time: Res<Time>, query: Query<(&Velocity, &mut Transform)>) {
for (movable, mut transform) in query {
transform.rotate_z(movable.rotation_speed * time.delta_secs());
let movement_direction = transform.rotation * Vec3::X;
let movement_distance = movable.linear_speed * time.delta_secs();
let translation_delta = movement_direction * movement_distance;
transform.translation += translation_delta;
//TODO: Loop on bounds
}
}