Files
Space-Game/apps/game/src/gameplay/movement/orbit.rs

52 lines
1.7 KiB
Rust

use bevy::prelude::*;
/// Which plane the orbit lies on.
#[derive(Debug, Clone, Copy, Default)]
pub enum OrbitPlane {
/// XZ plane (Y up). Typical for planets around a star viewed from above.
#[default]
Horizontal,
/// XY plane (Z up). Useful for UI elements or top-down 2D-style orbits.
Vertical,
}
/// An entity that orbits around its parent's origin.
/// Attach as a child of the orbit center; local Transform is updated each frame.
#[derive(Component, Debug, Clone, Copy)]
pub struct Orbit {
pub angle: f32,
pub angular_velocity: f32,
pub radius: f32,
pub plane: OrbitPlane,
}
impl Default for Orbit {
fn default() -> Self {
Self {
angle: 0.0,
// ~1 full revolution every 40 seconds — calm enough to read at
// inspection-scale zoom levels. Callers can override per-instance.
angular_velocity: 0.15,
radius: 10.0,
plane: OrbitPlane::Horizontal,
}
}
}
/// Advance each Orbit's angle and recompute local translation.
/// The orbit center is the parent entity (via Bevy's parent-child hierarchy).
pub fn update_orbits(mut query: Query<(&mut Orbit, &mut Transform)>, time: Res<Time>) {
let dt = time.delta_secs();
for (mut orbit, mut transform) in &mut query {
orbit.angle += orbit.angular_velocity * dt;
let (sin, cos) = orbit.angle.sin_cos();
let (x, y, z) = match orbit.plane {
OrbitPlane::Horizontal => (cos * orbit.radius, 0.0, sin * orbit.radius),
OrbitPlane::Vertical => (cos * orbit.radius, sin * orbit.radius, 0.0),
};
transform.translation.x = x;
transform.translation.y = y;
transform.translation.z = z;
}
}