add orbital clock (in menu)

This commit is contained in:
yuni 2024-10-26 21:22:03 +02:00
parent 55426ba0dd
commit 758114e3a2
3 changed files with 63 additions and 10 deletions

View file

@ -18,6 +18,7 @@ use bevy_xpbd_3d::prelude::*;
use regex::Regex; use regex::Regex;
pub const ID_SPECIAL_PLAYERCAM: &str = "PLAYERCAMERA"; pub const ID_SPECIAL_PLAYERCAM: &str = "PLAYERCAMERA";
pub const ID_PLAYER: &str = "player";
pub const ID_EARTH: &str = "earth"; pub const ID_EARTH: &str = "earth";
pub const ID_SOL: &str = "sol"; pub const ID_SOL: &str = "sol";
pub const ID_JUPITER: &str = "jupiter"; pub const ID_JUPITER: &str = "jupiter";

View file

@ -49,6 +49,8 @@ pub struct MenuElement;
#[derive(Component)] #[derive(Component)]
pub struct MenuTopLevel; pub struct MenuTopLevel;
#[derive(Component)] #[derive(Component)]
pub struct FooterElement;
#[derive(Component)]
pub struct MenuAchievements; pub struct MenuAchievements;
#[derive(Component)] #[derive(Component)]
pub struct DeathScreenElement; pub struct DeathScreenElement;
@ -349,17 +351,20 @@ pub fn setup(
}, },
)) ))
.with_children(|builder| { .with_children(|builder| {
builder.spawn((TextBundle { builder.spawn((
text: Text { FooterElement,
sections: vec![TextSection::new( TextBundle {
format!("{} {}", GAME_NAME, settings.version.as_str()), text: Text {
style_version, sections: vec![TextSection::new(
)], format!("{} {}", GAME_NAME, settings.version.as_str()),
justify: JustifyText::Right, style_version,
)],
justify: JustifyText::Right,
..default()
},
..default() ..default()
}, },
..default() ));
},));
}); });
} }
@ -435,8 +440,17 @@ pub struct MenuState {
pub fn update_menu( pub fn update_menu(
mut q_text: Query<&mut Text, With<MenuTopLevel>>, mut q_text: Query<&mut Text, With<MenuTopLevel>>,
mut q_achievement_text: Query<&mut Text, (With<MenuAchievements>, Without<MenuTopLevel>)>, mut q_footer: Query<&mut Text, (With<FooterElement>, Without<MenuTopLevel>)>,
mut q_achievement_text: Query<
&mut Text,
(
With<MenuAchievements>,
Without<MenuTopLevel>,
Without<FooterElement>,
),
>,
mut q_vis: Query<&mut Visibility, With<menu::MenuElement>>, mut q_vis: Query<&mut Visibility, With<menu::MenuElement>>,
id2pos: Res<game::Id2Pos>,
achievement_tracker: Res<var::AchievementTracker>, achievement_tracker: Res<var::AchievementTracker>,
menustate: Res<MenuState>, menustate: Res<MenuState>,
settings: Res<Settings>, settings: Res<Settings>,
@ -451,6 +465,21 @@ pub fn update_menu(
let bools = achievement_tracker.to_bool_vec(); let bools = achievement_tracker.to_bool_vec();
let rendered = achievement_tracker.to_textsections(); let rendered = achievement_tracker.to_textsections();
if let (Ok(mut text), Some(player_pos), Some(jupiter_pos)) = (
q_footer.get_single_mut(),
id2pos.0.get(cmd::ID_PLAYER),
id2pos.0.get(cmd::ID_JUPITER),
) {
let (clock_max, clock_current) =
nature::pos_to_orbit_time(*player_pos, *jupiter_pos, nature::JUPITER_MASS);
text.sections[0].value = format!(
"Orbital Clock:\n{} of {}\n{} {}",
nature::format_seconds_to_hour_min(clock_current),
nature::format_seconds_to_hour_min(clock_max),
GAME_NAME,
settings.version.as_str()
);
}
if let Ok(mut text) = q_achievement_text.get_single_mut() { if let Ok(mut text) = q_achievement_text.get_single_mut() {
for i in 0..text.sections.len() - 1 { for i in 0..text.sections.len() - 1 {
text.sections[i + 1].style.color = if bools[i] { text.sections[i + 1].style.color = if bools[i] {

View file

@ -242,3 +242,26 @@ pub fn rotation_for_orbiting_body(orbit_distance: f64, mass: f64) -> f64 {
0.0 0.0
} }
} }
/// Assumes a circular 2D orbit in the invariable plane of the solar system
/// Returns (seconds for a single orbit, current seconds of orbit)
pub fn pos_to_orbit_time(pos: DVec3, orbited_pos: DVec3, orbited_mass: f64) -> (f64, f64) {
let rel_x = pos.x - orbited_pos.x;
let rel_z = pos.z - orbited_pos.z;
let orbit_distance = (rel_x * rel_x + rel_z * rel_z).sqrt();
// get total orbit seconds
let period = simple_orbital_period(orbited_mass, orbit_distance);
// get current orbital phase
let angle_radians = (rel_z).atan2(-rel_x);
let mut fraction = angle_radians / (PI * 2.0);
if fraction < 0.0 {
fraction += 1.0;
}
return (period, period * fraction);
}
pub fn format_seconds_to_hour_min(seconds: f64) -> String {
return format!("{:02.0}:{:02.0}", seconds / 3600.0, (seconds % 3600.0) / 60.0);
}