add speedometer text

This commit is contained in:
yuni 2024-04-28 06:29:01 +02:00
parent 95b1c87194
commit 133fa9122f
3 changed files with 54 additions and 13 deletions

View file

@ -75,6 +75,7 @@ impl Plugin for HudPlugin {
#[derive(Component)] struct NodeHud; #[derive(Component)] struct NodeHud;
#[derive(Component)] struct NodeConsole; #[derive(Component)] struct NodeConsole;
#[derive(Component)] struct NodeChoiceText; #[derive(Component)] struct NodeChoiceText;
#[derive(Component)] struct NodeSpeedometerText;
#[derive(Component)] struct NodeCurrentChatLine; #[derive(Component)] struct NodeCurrentChatLine;
#[derive(Component)] struct Reticule; #[derive(Component)] struct Reticule;
#[derive(Component)] struct Speedometer; #[derive(Component)] struct Speedometer;
@ -224,6 +225,12 @@ fn setup(
color: settings.hud_color_choices, color: settings.hud_color_choices,
..default() ..default()
}; };
let style_speedometer = TextStyle {
font: font_handle.clone(),
font_size: settings.font_size_speedometer,
color: settings.hud_color_speedometer,
..default()
};
let style = TextStyle { let style = TextStyle {
font: font_handle, font: font_handle,
font_size: settings.font_size_hud, font_size: settings.font_size_hud,
@ -325,7 +332,6 @@ fn setup(
}); });
// Add Speedometer // Add Speedometer
let speedometer_height = 10.0;
let speedometer_handle: Handle<Image> = asset_server.load("sprites/speedometer.png"); let speedometer_handle: Handle<Image> = asset_server.load("sprites/speedometer.png");
commands.spawn(( commands.spawn((
NodeBundle { NodeBundle {
@ -382,6 +388,21 @@ fn setup(
}, },
)); ));
}); });
let mut bundle_speedometer_text = TextBundle::from_sections([
TextSection::new("", style_speedometer.clone()), // speed relative to target
TextSection::new("", style_speedometer.clone()), // speed relative to orbit
]).with_style(Style {
position_type: PositionType::Absolute,
left: Val::VMin(2.0),
bottom: Val::VMin(4.0),
..default()
}).with_text_justify(JustifyText::Left);
bundle_speedometer_text.visibility = visibility;
commands.spawn((
NodeSpeedometerText,
ToggleableHudElement,
bundle_speedometer_text,
));
// Chat "subtitles" and choices // Chat "subtitles" and choices
commands.spawn(NodeBundle { commands.spawn(NodeBundle {
@ -446,11 +467,14 @@ fn setup(
fn update_speedometer( fn update_speedometer(
q_camera: Query<&LinearVelocity, With<actor::PlayerCamera>>, q_camera: Query<&LinearVelocity, With<actor::PlayerCamera>>,
q_target: Query<&LinearVelocity, With<IsTargeted>>,
mut q_speedometer: Query<&mut Style, (With<Speedometer>, Without<Speedometer2>)>, mut q_speedometer: Query<&mut Style, (With<Speedometer>, Without<Speedometer2>)>,
mut q_speedometer2: Query<&mut Style, (With<Speedometer2>, Without<Speedometer>)>, mut q_speedometer2: Query<&mut Style, (With<Speedometer2>, Without<Speedometer>)>,
mut q_node_speed: Query<&mut Text, With<NodeSpeedometerText>>,
) { ) {
if let Ok(cam_v) = q_camera.get_single() { if let Ok(cam_v) = q_camera.get_single() {
let speed = cam_v.length(); let speed = cam_v.length();
let speed_readable = nature::readable_speed(speed);
let speedometer_split = 5_000.0; let speedometer_split = 5_000.0;
if let Ok(mut speedometer) = q_speedometer.get_single_mut() { if let Ok(mut speedometer) = q_speedometer.get_single_mut() {
@ -465,6 +489,15 @@ fn update_speedometer(
let wid = (fraction * SPEEDOMETER_WIDTH).clamp(0.0, 100.0); let wid = (fraction * SPEEDOMETER_WIDTH).clamp(0.0, 100.0);
speedometer2.width = Val::VMin(wid); speedometer2.width = Val::VMin(wid);
} }
if let Ok(mut speed_text) = q_node_speed.get_single_mut() {
speed_text.sections[0].value = if let Ok(target_v) = q_target.get_single() {
let delta_v = (target_v.0 - cam_v.0).length();
format!("Δv {}\n", nature::readable_speed(delta_v))
} else {
"".to_string()
};
speed_text.sections[1].value = speed_readable;
}
} }
} }
@ -492,7 +525,7 @@ fn update_hud(
let mut freshest_line: f64 = 0.0; let mut freshest_line: f64 = 0.0;
if player.is_ok() && q_camera_result.is_ok() { if player.is_ok() && q_camera_result.is_ok() {
let (hp, suit, gforce) = player.unwrap(); let (hp, suit, gforce) = player.unwrap();
let (pos, cam_v) = q_camera_result.unwrap(); let (pos, _) = q_camera_result.unwrap();
for mut text in &mut q_node_hud { for mut text in &mut q_node_hud {
text.sections[0].value = format!("2524-03-12 03:02"); text.sections[0].value = format!("2524-03-12 03:02");
if let Some(fps) = diagnostics.get(&FrameTimeDiagnosticsPlugin::FPS) { if let Some(fps) = diagnostics.get(&FrameTimeDiagnosticsPlugin::FPS) {
@ -578,9 +611,7 @@ fn update_hud(
// }; // };
let dev_speed = ""; let dev_speed = "";
let gforce = gforce.gforce; let gforce = gforce.gforce;
let speed = cam_v.length(); text.sections[14].value = format!("\n{gforce:.1}g{dev_speed}");
let speed_readable = nature::readable_distance(speed);
text.sections[14].value = format!("\n{speed_readable}/s\n{gforce:.1}g{dev_speed}");
if target_multiple { if target_multiple {
text.sections[15].value = "\n\nERROR: MULTIPLE TARGETS".to_string(); text.sections[15].value = "\n\nERROR: MULTIPLE TARGETS".to_string();
@ -588,7 +619,7 @@ fn update_hud(
else if target_error { else if target_error {
text.sections[15].value = "\n\nERROR: FAILED TO AQUIRE TARGET".to_string(); text.sections[15].value = "\n\nERROR: FAILED TO AQUIRE TARGET".to_string();
} }
else if let Ok((clickable, _, target_v_maybe)) = q_target.get_single() { else if let Ok((clickable, _, _)) = q_target.get_single() {
let distance = if dist_scalar.is_nan() { let distance = if dist_scalar.is_nan() {
"UNKNOWN".to_string() "UNKNOWN".to_string()
} else if dist_scalar != 0.0 { } else if dist_scalar != 0.0 {
@ -596,19 +627,13 @@ fn update_hud(
} else { } else {
"ERROR".to_string() "ERROR".to_string()
}; };
let speed: f64 = if let Some(target_v) = target_v_maybe {
(target_v.0 - cam_v.0).length()
} else {
cam_v.length()
};
let speed_readable = nature::readable_distance(speed);
let target_name = clickable.name.clone().unwrap_or("Unnamed".to_string()); let target_name = clickable.name.clone().unwrap_or("Unnamed".to_string());
let pronoun = if let Some(pronoun) = &clickable.pronoun { let pronoun = if let Some(pronoun) = &clickable.pronoun {
format!("Pronoun: {pronoun}\n") format!("Pronoun: {pronoun}\n")
} else { } else {
"".to_string() "".to_string()
}; };
text.sections[15].value = format!("\n\nTarget: {target_name}\n{pronoun}Distance: {distance}\nΔv {speed_readable}/s"); text.sections[15].value = format!("\n\nTarget: {target_name}\n{pronoun}Distance: {distance}");
} }
else { else {
text.sections[15].value = "".to_string(); text.sections[15].value = "".to_string();

View file

@ -120,6 +120,18 @@ pub fn readable_distance(distance: f64) -> String {
return format!("{distance:.1}m"); return format!("{distance:.1}m");
} }
pub fn readable_speed(speed: f64) -> String {
let abs = speed.abs();
if abs > C * 0.0005 {
let lightyears = abs / C;
return format!("{lightyears:.4} c");
}
else {
let kmh = abs * 1.0e-3 * 3600.0;
return format!("{kmh:.0} km/h");
}
}
pub fn lorenz_factor(speed: f64) -> f64 { pub fn lorenz_factor(speed: f64) -> f64 {
(1.0 - (speed.powf(2.0) / C.powf(2.0))).sqrt() (1.0 - (speed.powf(2.0) / C.powf(2.0))).sqrt()
} }

View file

@ -44,6 +44,7 @@ pub struct Settings {
pub font_size_conversations: f32, pub font_size_conversations: f32,
pub font_size_choices: f32, pub font_size_choices: f32,
pub font_size_console: f32, pub font_size_console: f32,
pub font_size_speedometer: f32,
pub hud_color: Color, pub hud_color: Color,
pub hud_color_console: Color, pub hud_color_console: Color,
pub hud_color_console_warn: Color, pub hud_color_console_warn: Color,
@ -51,6 +52,7 @@ pub struct Settings {
pub hud_color_alert: Color, pub hud_color_alert: Color,
pub hud_color_subtitles: Color, pub hud_color_subtitles: Color,
pub hud_color_choices: Color, pub hud_color_choices: Color,
pub hud_color_speedometer: Color,
pub chat_speed: f32, pub chat_speed: f32,
pub hud_active: bool, pub hud_active: bool,
pub map_active: bool, pub map_active: bool,
@ -147,6 +149,7 @@ impl Default for Settings {
font_size_conversations: 32.0, font_size_conversations: 32.0,
font_size_choices: 28.0, font_size_choices: 28.0,
font_size_console: 20.0, font_size_console: 20.0,
font_size_speedometer: 34.0,
hud_color: Color::rgb(0.1, 0.5, 0.1), hud_color: Color::rgb(0.1, 0.5, 0.1),
hud_color_console: Color::rgb(0.1, 0.5, 0.1), hud_color_console: Color::rgb(0.1, 0.5, 0.1),
hud_color_console_warn: Color::rgb(1.0, 0.3, 0.3), hud_color_console_warn: Color::rgb(1.0, 0.3, 0.3),
@ -154,6 +157,7 @@ impl Default for Settings {
hud_color_alert: Color::rgb(0.6, 0.094, 0.322), hud_color_alert: Color::rgb(0.6, 0.094, 0.322),
hud_color_subtitles: Color::rgb(0.8, 0.8, 0.8), hud_color_subtitles: Color::rgb(0.8, 0.8, 0.8),
hud_color_choices: Color::rgb(0.45, 0.45, 0.45), hud_color_choices: Color::rgb(0.45, 0.45, 0.45),
hud_color_speedometer: Color::rgb(0.749, 0.0745, 0.31765),
chat_speed: DEFAULT_CHAT_SPEED * if dev_mode { 2.5 } else { 1.0 }, chat_speed: DEFAULT_CHAT_SPEED * if dev_mode { 2.5 } else { 1.0 },
hud_active: false, hud_active: false,
map_active: false, map_active: false,