diff --git a/src/plugins/game.rs b/src/plugins/game.rs index 6823b57..c3314b3 100644 --- a/src/plugins/game.rs +++ b/src/plugins/game.rs @@ -1,14 +1,32 @@ -use bevy::prelude::*; +use std::f32::consts::FRAC_PI_2; + +use bevy::{ + input::mouse::MouseMotion, + prelude::*, + window::{CursorGrabMode, PrimaryWindow}, +}; // use bevy_rapier3d::prelude::*; #[derive(Default)] -pub struct GamePlugin {} +pub struct GamePlugin; + +#[derive(Component, Default)] +pub struct MainCamera; + +#[derive(Component, Default)] +pub struct CameraRoot; +#[derive(Component, Default)] +pub struct CameraPitch(pub f32); +#[derive(Component)] +pub struct Unfocused; impl Plugin for GamePlugin { fn build(&self, app: &mut bevy::app::App) { // app.add_plugins(RapierPhysicsPlugin::::default()); app.add_systems(Startup, (setup_scene, spawn_ship)); + + app.add_systems(Update, ((camera_yaw, camera_pitch).chain(), camera_toggle, fly_camera)); } } @@ -16,8 +34,23 @@ fn setup_scene( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, + mut window: Single<&mut Window, With>, ) { - commands.spawn((Camera3d::default(), Transform::from_xyz(0.0, 1.3, 0.0))); + window.cursor_options.visible = false; + window.cursor_options.grab_mode = CursorGrabMode::Locked; + + commands.spawn(( + Name::new("Camera Root"), + Transform::from_xyz(0.0, 1.3, 0.0), + CameraRoot::default(), + Visibility::default(), + children![( + Camera3d::default(), + CameraPitch::default(), + MainCamera::default(), + Transform::default() + )], + )); commands.spawn(( DirectionalLight { @@ -83,3 +116,84 @@ fn spawn_ship( ], )); } + +pub fn camera_toggle( + key: Res>, + window_query: Single<&mut Window, With>, + camera: Single>, + mut commands: Commands, +) { + let mut window = window_query.into_inner(); + if key.just_pressed(KeyCode::Escape) { + if window.cursor_options.visible { + commands.entity(camera.into_inner()).remove::(); + window.cursor_options.grab_mode = CursorGrabMode::Locked; + window.cursor_options.visible = false; + } else { + commands.entity(camera.into_inner()).insert(Unfocused); + window.cursor_options.grab_mode = CursorGrabMode::None; + window.cursor_options.visible = true; + } + } +} + +const FLY_SPEED: f32 = 10.0; +pub fn fly_camera( + cam_query: Single<&mut Transform, (With, Without)>, + cam_pitch: Single<&CameraPitch>, + key: Res>, + time: Res