Ship Controls
+ Refactoring
This commit is contained in:
112
src/plugins/ship.rs
Normal file
112
src/plugins/ship.rs
Normal file
@@ -0,0 +1,112 @@
|
||||
use avian3d::prelude::*;
|
||||
use bevy::{input::mouse::MouseMotion, prelude::*};
|
||||
|
||||
use crate::{components::tags::Ship, utils::input::get_mouse_delta};
|
||||
|
||||
pub struct ShipPlugin;
|
||||
|
||||
impl Plugin for ShipPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(Update, ship_controls);
|
||||
#[cfg(feature = "dev-viz")]
|
||||
app.add_systems(Update, ship_debug);
|
||||
}
|
||||
}
|
||||
|
||||
fn ship_controls(
|
||||
ship_query: Single<
|
||||
(
|
||||
&Transform,
|
||||
&mut LinearVelocity,
|
||||
&mut AngularVelocity,
|
||||
&mut LinearDamping,
|
||||
&mut AngularDamping,
|
||||
),
|
||||
With<Ship>,
|
||||
>,
|
||||
key: Res<ButtonInput<KeyCode>>,
|
||||
time: Res<Time>,
|
||||
mut mouse_motion: EventReader<MouseMotion>,
|
||||
) {
|
||||
let (transform, mut vel, mut ang, mut ldamp, mut adamp) = ship_query.into_inner();
|
||||
|
||||
let mut move_vec = Vec3::ZERO;
|
||||
|
||||
if key.pressed(KeyCode::KeyW) {
|
||||
move_vec.z = -1.0;
|
||||
} else if key.pressed(KeyCode::KeyS) {
|
||||
move_vec.z = 1.0;
|
||||
}
|
||||
|
||||
if key.pressed(KeyCode::KeyA) {
|
||||
move_vec.x = -1.0;
|
||||
} else if key.pressed(KeyCode::KeyD) {
|
||||
move_vec.x = 1.0;
|
||||
}
|
||||
|
||||
if key.pressed(KeyCode::Space) {
|
||||
move_vec.y = 1.0;
|
||||
} else if key.pressed(KeyCode::ShiftLeft) {
|
||||
move_vec.y = -1.0;
|
||||
}
|
||||
|
||||
if key.pressed(KeyCode::ControlLeft) {
|
||||
ldamp.0 = 0.8;
|
||||
adamp.0 = 0.8;
|
||||
} else {
|
||||
ldamp.0 = 0.0;
|
||||
adamp.0 = 0.0;
|
||||
}
|
||||
|
||||
const ROLL_SPEED: f32 = 1.0;
|
||||
const DEAD_ZONE: f32 = 0.1;
|
||||
const INPUT_CURVE: f32 = 3.0;
|
||||
let yaw = if key.pressed(KeyCode::KeyQ) {
|
||||
Vec3::Y * ROLL_SPEED
|
||||
} else if key.pressed(KeyCode::KeyE) {
|
||||
Vec3::Y * -ROLL_SPEED
|
||||
} else {
|
||||
Vec3::ZERO
|
||||
};
|
||||
|
||||
let mouse_delta = get_mouse_delta(mouse_motion).normalize_or_zero();
|
||||
let mouse_input = mouse_delta
|
||||
.abs()
|
||||
.map(|v| if v < DEAD_ZONE { 0.0 } else { v })
|
||||
.powf(INPUT_CURVE)
|
||||
* mouse_delta.signum();
|
||||
|
||||
let roll = Vec3::NEG_Z * mouse_input.x;
|
||||
let pitch = Vec3::X * mouse_input.y;
|
||||
|
||||
ang.0 += (transform.rotation * (roll + yaw + pitch)) * time.delta_secs();
|
||||
|
||||
move_vec = transform.rotation * move_vec.normalize_or_zero();
|
||||
|
||||
vel.0 += move_vec * time.delta_secs();
|
||||
}
|
||||
|
||||
#[cfg(feature = "dev-viz")]
|
||||
fn ship_debug(mut gizmos: Gizmos, ship: Single<&Transform, With<Ship>>) {
|
||||
use std::ops::Range;
|
||||
|
||||
let base = ship.translation.floor();
|
||||
const GRID: Range<i32> = -10..10;
|
||||
for x in GRID {
|
||||
for y in GRID {
|
||||
for z in GRID {
|
||||
let p = base + Vec3::new(x as f32, y as f32, z as f32);
|
||||
let color = if x == 0 && y == 0 {
|
||||
LinearRgba::BLUE
|
||||
} else if x == 0 && z == 0 {
|
||||
LinearRgba::GREEN
|
||||
} else if y == 0 && z == 0 {
|
||||
LinearRgba::RED
|
||||
} else {
|
||||
LinearRgba::gray(0.2).with_alpha(0.2)
|
||||
};
|
||||
gizmos.sphere(p, 0.01, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user