This commit is contained in:
yuni 2024-03-18 04:39:26 +01:00
parent a541591b84
commit 6a6b53d0c0
5 changed files with 89 additions and 119 deletions

View file

@ -1,7 +1,7 @@
use bevy::prelude::*; use bevy::prelude::*;
use bevy::input::mouse::MouseMotion; use bevy::input::mouse::MouseMotion;
use bevy::window::PrimaryWindow; use bevy::window::PrimaryWindow;
use std::{f32::consts::*, fmt}; use std::f32::consts::*;
use crate::{settings, audio}; use crate::{settings, audio};
pub struct CameraControllerPlugin; pub struct CameraControllerPlugin;
@ -12,9 +12,9 @@ impl Plugin for CameraControllerPlugin {
} }
} }
/// Based on Valorant's default sensitivity, not entirely sure why it is exactly 1.0 / 180.0, // Based on Valorant's default sensitivity, not entirely sure why it is exactly 1.0 / 180.0,
/// but I'm guessing it is a misunderstanding between degrees/radians and then sticking with // but I'm guessing it is a misunderstanding between degrees/radians and then sticking with
/// it because it felt nice. // it because it felt nice.
pub const RADIANS_PER_DOT: f32 = 1.0 / 180.0; pub const RADIANS_PER_DOT: f32 = 1.0 / 180.0;
#[derive(Component)] #[derive(Component)]
@ -22,15 +22,6 @@ pub struct CameraController {
pub enabled: bool, pub enabled: bool,
pub initialized: bool, pub initialized: bool,
pub sensitivity: f32, pub sensitivity: f32,
pub key_forward: KeyCode,
pub key_back: KeyCode,
pub key_left: KeyCode,
pub key_right: KeyCode,
pub key_up: KeyCode,
pub key_down: KeyCode,
pub key_run: KeyCode,
pub key_stop: KeyCode,
pub mouse_key_cursor_grab: MouseButton,
pub move_speed: f32, pub move_speed: f32,
pub friction: f32, pub friction: f32,
pub pitch: f32, pub pitch: f32,
@ -44,15 +35,6 @@ impl Default for CameraController {
enabled: true, enabled: true,
initialized: false, initialized: false,
sensitivity: 0.5, sensitivity: 0.5,
key_forward: KeyCode::KeyW,
key_back: KeyCode::KeyS,
key_left: KeyCode::KeyA,
key_right: KeyCode::KeyD,
key_up: KeyCode::ShiftLeft,
key_down: KeyCode::ControlLeft,
key_run: KeyCode::KeyR,
key_stop: KeyCode::Space,
mouse_key_cursor_grab: MouseButton::Left,
move_speed: 1.0, move_speed: 1.0,
friction: 0.1, friction: 0.1,
pitch: 1.0, // pitch=0/yaw=0 -> face sun pitch: 1.0, // pitch=0/yaw=0 -> face sun
@ -62,41 +44,14 @@ impl Default for CameraController {
} }
} }
impl fmt::Display for CameraController {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"
Freecam Controls:
Mouse\t- Move camera orientation
{:?}\t- Hold to grab cursor
{:?} & {:?}\t- Fly forward & backwards
{:?} & {:?}\t- Fly sideways left & right
{:?} & {:?}\t- Fly up & down
{:?}\t- Fly faster while held",
self.mouse_key_cursor_grab,
self.key_forward,
self.key_back,
self.key_left,
self.key_right,
self.key_up,
self.key_down,
self.key_run,
)
}
}
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn run_camera_controller( fn run_camera_controller(
time: Res<Time>, time: Res<Time>,
settings: Res<settings::Settings>, settings: Res<settings::Settings>,
mut windows: Query<&mut Window, With<PrimaryWindow>>, mut windows: Query<&mut Window, With<PrimaryWindow>>,
mut mouse_events: EventReader<MouseMotion>, mut mouse_events: EventReader<MouseMotion>,
mouse_button_input: Res<ButtonInput<MouseButton>>,
key_input: Res<ButtonInput<KeyCode>>, key_input: Res<ButtonInput<KeyCode>>,
thruster_sound_controller: Query<&AudioSink, With<audio::ComponentThrusterSound>>, thruster_sound_controller: Query<&AudioSink, With<audio::ComponentThrusterSound>>,
mut toggle_cursor_grab: Local<bool>,
mut mouse_cursor_grab: Local<bool>,
mut query: Query<(&mut Transform, &mut CameraController), With<Camera>>, mut query: Query<(&mut Transform, &mut CameraController), With<Camera>>,
) { ) {
let dt = time.delta_seconds(); let dt = time.delta_seconds();
@ -113,8 +68,6 @@ fn run_camera_controller(
controller.initialized = true; controller.initialized = true;
transform.rotation = transform.rotation =
Quat::from_euler(EulerRot::ZYX, 0.0, controller.yaw, controller.pitch); Quat::from_euler(EulerRot::ZYX, 0.0, controller.yaw, controller.pitch);
*toggle_cursor_grab = true;
info!("{}", *controller);
} }
if !controller.enabled { if !controller.enabled {
mouse_events.clear(); mouse_events.clear();
@ -124,35 +77,27 @@ fn run_camera_controller(
// Handle key input // Handle key input
let mut axis_input = Vec3::ZERO; let mut axis_input = Vec3::ZERO;
if focused { if focused {
if key_input.pressed(controller.key_forward) { if key_input.pressed(settings.key_forward) {
axis_input.z += 1.0; axis_input.z += 1.0;
} }
if key_input.pressed(controller.key_back) { if key_input.pressed(settings.key_back) {
axis_input.z -= 1.0; axis_input.z -= 1.0;
} }
if key_input.pressed(controller.key_right) { if key_input.pressed(settings.key_right) {
axis_input.x += 1.0; axis_input.x += 1.0;
} }
if key_input.pressed(controller.key_left) { if key_input.pressed(settings.key_left) {
axis_input.x -= 1.0; axis_input.x -= 1.0;
} }
if key_input.pressed(controller.key_up) { if key_input.pressed(settings.key_up) {
axis_input.y += 1.0; axis_input.y += 1.0;
} }
if key_input.pressed(controller.key_down) { if key_input.pressed(settings.key_down) {
axis_input.y -= 1.0; axis_input.y -= 1.0;
} }
} }
if mouse_button_input.just_pressed(controller.mouse_key_cursor_grab) { let friction = if key_input.pressed(settings.key_stop) {
*mouse_cursor_grab = true;
}
if mouse_button_input.just_released(controller.mouse_key_cursor_grab) {
*mouse_cursor_grab = false;
}
let cursor_grab = *mouse_cursor_grab || *toggle_cursor_grab;
let friction = if key_input.pressed(controller.key_stop) {
controller.friction.clamp(0.0, 1.0) controller.friction.clamp(0.0, 1.0)
} else { } else {
0.0 0.0
@ -177,13 +122,9 @@ fn run_camera_controller(
// Handle mouse input // Handle mouse input
let mut mouse_delta = Vec2::ZERO; let mut mouse_delta = Vec2::ZERO;
if cursor_grab {
for mouse_event in mouse_events.read() { for mouse_event in mouse_events.read() {
mouse_delta += mouse_event.delta; mouse_delta += mouse_event.delta;
} }
} else {
mouse_events.clear();
}
if mouse_delta != Vec2::ZERO { if mouse_delta != Vec2::ZERO {
// Apply look update // Apply look update

View file

@ -7,7 +7,7 @@ use std::time::SystemTime;
const HUD_REFRESH_TIME: f32 = 0.5; const HUD_REFRESH_TIME: f32 = 0.5;
const FONT: &str = "tmp/fonts/NotoSansSC-Thin.ttf"; const FONT: &str = "tmp/fonts/NotoSansSC-Thin.ttf";
const LOG_MAX: usize = 5; const LOG_MAX: usize = 5;
const LOG_MAX_TIME_S: u64 = 10; const LOG_MAX_TIME_S: u64 = 20;
pub struct HudPlugin; pub struct HudPlugin;
impl Plugin for HudPlugin { impl Plugin for HudPlugin {

View file

@ -50,10 +50,10 @@ fn handle_input(
mut settings: ResMut<settings::Settings>, mut settings: ResMut<settings::Settings>,
mut app_exit_events: ResMut<Events<bevy::app::AppExit>> mut app_exit_events: ResMut<Events<bevy::app::AppExit>>
) { ) {
if keyboard_input.pressed(KeyCode::KeyQ) { if keyboard_input.pressed(settings.key_exit) {
app_exit_events.send(bevy::app::AppExit); app_exit_events.send(bevy::app::AppExit);
} }
if keyboard_input.just_pressed(KeyCode::F12) { if keyboard_input.just_pressed(settings.key_restart) {
settings.reset(); settings.reset();
} }
} }

View file

@ -8,8 +8,19 @@ pub struct Settings {
pub volume_music: u8, pub volume_music: u8,
pub font_size_hud: f32, pub font_size_hud: f32,
pub font_size_conversations: f32, pub font_size_conversations: f32,
pub key_togglehud: KeyCode,
pub hud_active: bool, pub hud_active: bool,
pub key_togglehud: KeyCode,
pub key_exit: KeyCode,
pub key_restart: KeyCode,
pub key_fullscreen: KeyCode,
pub key_forward: KeyCode,
pub key_back: KeyCode,
pub key_left: KeyCode,
pub key_right: KeyCode,
pub key_up: KeyCode,
pub key_down: KeyCode,
pub key_run: KeyCode,
pub key_stop: KeyCode,
} }
impl Default for Settings { impl Default for Settings {
@ -21,8 +32,19 @@ impl Default for Settings {
volume_music: 100, volume_music: 100,
font_size_hud: 32.0, font_size_hud: 32.0,
font_size_conversations: 32.0, font_size_conversations: 32.0,
key_togglehud: KeyCode::Tab,
hud_active: false, hud_active: false,
key_togglehud: KeyCode::Tab,
key_exit: KeyCode::Escape,
key_restart: KeyCode::F12,
key_fullscreen: KeyCode::F11,
key_forward: KeyCode::KeyW,
key_back: KeyCode::KeyS,
key_left: KeyCode::KeyA,
key_right: KeyCode::KeyD,
key_up: KeyCode::ShiftLeft,
key_down: KeyCode::ControlLeft,
key_run: KeyCode::KeyR,
key_stop: KeyCode::Space,
} }
} }
} }

View file

@ -7,6 +7,17 @@ use bevy::pbr::CascadeShadowConfigBuilder;
use bevy::core_pipeline::bloom::{BloomCompositeMode, BloomSettings}; use bevy::core_pipeline::bloom::{BloomCompositeMode, BloomSettings};
use std::f32::consts::PI; use std::f32::consts::PI;
const ASTEROID_SIZE: f32 = 100.0;
const MOON_SIZE: f32 = 50.0;
const MARS_SIZE: f32 = 10.0;
const SUN_SIZE: f32 = 5000.0;
const ASTRONAUT_SIZE: f32 = 5.0;
const SKYBOX_BRIGHTNESS: f32 = 300.0;
const ASSET_CUBEMAP: &str = "textures/stars_cubemap.png";
const ASSET_ASTRONAUT: &str = "tmp/alien.glb#Scene0";
pub struct WorldPlugin; pub struct WorldPlugin;
impl Plugin for WorldPlugin { impl Plugin for WorldPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
@ -21,8 +32,6 @@ pub struct Cubemap {
image_handle: Handle<Image>, image_handle: Handle<Image>,
} }
const CUBEMAP_PATH: &str = "textures/stars_cubemap.png";
pub fn setup( pub fn setup(
mut commands: Commands, mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
@ -42,7 +51,7 @@ pub fn setup(
)); ));
// Add skybox // Add skybox
let skybox_handle = asset_server.load(CUBEMAP_PATH); let skybox_handle = asset_server.load(ASSET_CUBEMAP);
commands.spawn(( commands.spawn((
Camera3dBundle { Camera3dBundle {
camera: Camera { camera: Camera {
@ -55,7 +64,7 @@ pub fn setup(
camera::CameraController::default(), camera::CameraController::default(),
Skybox { Skybox {
image: skybox_handle.clone(), image: skybox_handle.clone(),
brightness: 200.0, brightness: SKYBOX_BRIGHTNESS,
}, },
BloomSettings { BloomSettings {
composite_mode: BloomCompositeMode::EnergyConserving, composite_mode: BloomCompositeMode::EnergyConserving,
@ -67,9 +76,8 @@ pub fn setup(
image_handle: skybox_handle, image_handle: skybox_handle,
}); });
// Add spheres // Add some hand-placed asteroids
let sphere_radius = 50.0; let sphere_handle = meshes.add(Sphere::new(1.0));
let sphere_handle = meshes.add(Sphere::new(sphere_radius));
let gray_handle = materials.add(StandardMaterial { let gray_handle = materials.add(StandardMaterial {
base_color: Color::GRAY, base_color: Color::GRAY,
perceptual_roughness: 1.0, perceptual_roughness: 1.0,
@ -80,33 +88,34 @@ pub fn setup(
perceptual_roughness: 1.0, perceptual_roughness: 1.0,
..default() ..default()
}); });
commands.spawn(PbrBundle { commands.spawn((
actor::Actor::default(),
PbrBundle {
mesh: sphere_handle.clone(), mesh: sphere_handle.clone(),
material: gray_handle.clone(), material: gray_handle.clone(),
transform: Transform::from_xyz( transform: Transform::from_xyz(
0.0, 0.0,
0.0, 0.0,
-500.0, -500.0,
), ).with_scale(Vec3::splat(MOON_SIZE)),
..default() ..default()
}); },
));
let sphere_radius = 10.0; commands.spawn((
let sphere_handle = meshes.add(Sphere::new(sphere_radius)); actor::Actor::default(),
commands.spawn(PbrBundle { PbrBundle {
mesh: sphere_handle.clone(), mesh: sphere_handle.clone(),
material: brown_handle.clone(), material: brown_handle.clone(),
transform: Transform::from_xyz( transform: Transform::from_xyz(
300.0, 300.0,
40.0, 40.0,
250.0, 250.0,
), ).with_scale(Vec3::splat(MARS_SIZE)),
..default() ..default()
}); },
));
// Add a bunch of asteriods // Generate a bunch of asteriods
let sphere_radius = 100.0;
let sphere_handle = meshes.add(Sphere::new(sphere_radius));
let asteroid_color_handle = materials.add(StandardMaterial { let asteroid_color_handle = materials.add(StandardMaterial {
base_color: Color::rgb(0.25, 0.2, 0.2), base_color: Color::rgb(0.25, 0.2, 0.2),
perceptual_roughness: 1.0, perceptual_roughness: 1.0,
@ -116,8 +125,8 @@ pub fn setup(
for j in -13..13 { for j in -13..13 {
for k in -14..14 { for k in -14..14 {
let offset = 500.0; let offset = 500.0;
let dist = 9000.0; let dist = 18000.0;
let wobble = 3000.0; let wobble = dist/2.0;
let (i, j, k) = (i as f32, j as f32, k as f32); let (i, j, k) = (i as f32, j as f32, k as f32);
commands.spawn(( commands.spawn((
actor::Actor::default(), actor::Actor::default(),
@ -128,7 +137,7 @@ pub fn setup(
offset + dist * i + wobble * (j+k/PI).sin() * (k+j/PI).cos(), offset + dist * i + wobble * (j+k/PI).sin() * (k+j/PI).cos(),
offset + dist * j + wobble * (k+i/PI).sin() * (i+k/PI).cos(), offset + dist * j + wobble * (k+i/PI).sin() * (i+k/PI).cos(),
offset + dist * k + wobble * (i+j/PI).sin() * (j+i/PI).cos(), offset + dist * k + wobble * (i+j/PI).sin() * (j+i/PI).cos(),
), ).with_scale(Vec3::splat(ASTEROID_SIZE)),
..default() ..default()
} }
)); ));
@ -141,8 +150,6 @@ pub fn setup(
emissive: Color::rgb_linear(1e6, 0.9e6, 1e6), emissive: Color::rgb_linear(1e6, 0.9e6, 1e6),
..default() ..default()
}); });
let sphere_radius = 5000.0;
let sphere_handle = meshes.add(Sphere::new(sphere_radius));
commands.spawn(PbrBundle { commands.spawn(PbrBundle {
mesh: sphere_handle.clone(), mesh: sphere_handle.clone(),
material: hydrogenfusion_handle.clone(), material: hydrogenfusion_handle.clone(),
@ -150,7 +157,7 @@ pub fn setup(
0.0, 0.0,
30000.0, 30000.0,
-500000.0, -500000.0,
), ).with_scale(Vec3::splat(SUN_SIZE)),
..default() ..default()
}); });
@ -163,9 +170,9 @@ pub fn setup(
100.0, 100.0,
), ),
rotation: Quat::from_rotation_y(-PI / 3.), rotation: Quat::from_rotation_y(-PI / 3.),
scale: Vec3::splat(5.0), scale: Vec3::splat(ASTRONAUT_SIZE),
}, },
scene: asset_server.load("tmp/alien.glb#Scene0"), scene: asset_server.load(ASSET_ASTRONAUT),
..default() ..default()
}); });
@ -199,7 +206,7 @@ pub fn load_cubemap_asset(
mut cubemap: ResMut<Cubemap>, mut cubemap: ResMut<Cubemap>,
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
) { ) {
cubemap.image_handle = asset_server.load(CUBEMAP_PATH); cubemap.image_handle = asset_server.load(ASSET_CUBEMAP);
cubemap.is_loaded = false; cubemap.is_loaded = false;
} }