From 570ed86c4a17efe0a45658aec2816833981582db Mon Sep 17 00:00:00 2001 From: Amatsugu Date: Tue, 1 Jul 2025 12:56:31 -0400 Subject: [PATCH] Add Asset loader, added and configured various states --- Cargo.lock | 30 +++ Cargo.toml | 1 + rustfmt.toml | 8 +- src/components/camera.rs | 100 +++++----- src/components/mod.rs | 8 +- src/components/player.rs | 98 +++++----- src/components/tags.rs | 20 +- src/macros.rs | 16 ++ src/main.rs | 79 ++++---- src/plugins/camera.rs | 122 ++++++------ src/plugins/follow_cam.rs | 56 +++--- src/plugins/game.rs | 328 +++++++++++++++++--------------- src/plugins/mod.rs | 36 ++-- src/plugins/player.rs | 328 ++++++++++++++++---------------- src/plugins/ship.rs | 206 ++++++++++---------- src/plugins/ship_cam.rs | 18 +- src/plugins/state_management.rs | 57 ++++-- src/plugins/types.rs | 46 ++--- src/states/game.rs | 9 + src/states/input.rs | 40 ++-- src/states/loading.rs | 18 ++ src/states/menu.rs | 27 +++ src/states/mod.rs | 6 +- src/states/play.rs | 23 +++ src/utils/input.rs | 18 +- src/utils/mod.rs | 4 +- src/utils/rotation.rs | 76 ++++---- 27 files changed, 975 insertions(+), 803 deletions(-) create mode 100644 src/macros.rs create mode 100644 src/states/game.rs create mode 100644 src/states/loading.rs create mode 100644 src/states/menu.rs create mode 100644 src/states/play.rs diff --git a/Cargo.lock b/Cargo.lock index 79ea65c..d57dd36 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -565,6 +565,29 @@ dependencies = [ "web-sys", ] +[[package]] +name = "bevy_asset_loader" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "653857e8685ba3c6f237a7aa67620ae440c87e975f8a843ef098c90c49b9dde6" +dependencies = [ + "anyhow", + "bevy", + "bevy_asset_loader_derive", + "path-slash", +] + +[[package]] +name = "bevy_asset_loader_derive" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea90451960d44a9908e95de892511dead119b909da68e56b92527efcfac8691" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "bevy_asset_macros" version = "0.16.1" @@ -4009,6 +4032,12 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "path-slash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" + [[package]] name = "percent-encoding" version = "2.3.1" @@ -4798,6 +4827,7 @@ version = "0.1.0" dependencies = [ "bevy", "bevy-inspector-egui", + "bevy_asset_loader", "bevy_rapier3d", ] diff --git a/Cargo.toml b/Cargo.toml index b19c2b4..161af1a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ edition = "2024" bevy = { version = "0.16.1", features = [] } # bevy_rapier3d = { version = "0.29.0", features = ["simd-stable", "parallel"] } bevy-inspector-egui = "0.31.0" +bevy_asset_loader = "0.23.0" bevy_rapier3d = "0.30.0" [features] diff --git a/rustfmt.toml b/rustfmt.toml index ec7d3d8..6f255b3 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,4 +1,4 @@ -hard_tabs = true -max_width = 120 -brace_style = "AlwaysNextLine" -control_brace_style = "AlwaysNextLine" +hard_tabs = true +max_width = 120 +brace_style = "AlwaysNextLine" +control_brace_style = "AlwaysNextLine" diff --git a/src/components/camera.rs b/src/components/camera.rs index 4b14887..599f03c 100644 --- a/src/components/camera.rs +++ b/src/components/camera.rs @@ -1,50 +1,50 @@ -use bevy::prelude::*; - -#[derive(Component, Reflect)] -pub struct FreeCam(pub bool); - -#[derive(Component, Default, Reflect)] -pub struct MainCamera; - -#[derive(Component, Default, Reflect)] -pub struct CameraRoot; -#[derive(Component, Default, Reflect)] -pub struct CameraPitch(pub f32); -#[derive(Component, Reflect)] -pub struct Unfocused; - -#[derive(Component, Reflect)] -#[require(FollowTarget)] -pub struct FollowCam { - pub target: Entity, - pub distance: f32, - pub height: f32, -} - -#[derive(Component, Reflect)] -pub struct FollowTarget { - pub pos: Vec3, - pub rot: Quat, - pub up: Dir3, -} - -impl Default for FollowTarget { - fn default() -> Self { - return Self { - pos: default(), - rot: default(), - up: Dir3::Y, - }; - } -} - -#[derive(Component, Default, Reflect)] -pub enum CameraMode { - #[default] - Player, - Ship, - Disabled, -} - -#[derive(Component, Reflect)] -pub struct CameraAttachment(pub Entity); +use bevy::prelude::*; + +#[derive(Component, Reflect)] +pub struct FreeCam(pub bool); + +#[derive(Component, Default, Reflect)] +pub struct MainCamera; + +#[derive(Component, Default, Reflect)] +pub struct CameraRoot; +#[derive(Component, Default, Reflect)] +pub struct CameraPitch(pub f32); +#[derive(Component, Reflect)] +pub struct Unfocused; + +#[derive(Component, Reflect)] +#[require(FollowTarget)] +pub struct FollowCam { + pub target: Entity, + pub distance: f32, + pub height: f32, +} + +#[derive(Component, Reflect)] +pub struct FollowTarget { + pub pos: Vec3, + pub rot: Quat, + pub up: Dir3, +} + +impl Default for FollowTarget { + fn default() -> Self { + return Self { + pos: default(), + rot: default(), + up: Dir3::Y, + }; + } +} + +#[derive(Component, Default, Reflect)] +pub enum CameraMode { + #[default] + Player, + Ship, + Disabled, +} + +#[derive(Component, Reflect)] +pub struct CameraAttachment(pub Entity); diff --git a/src/components/mod.rs b/src/components/mod.rs index 72af442..2e38c32 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -1,4 +1,4 @@ -pub mod camera; -// pub mod character_controller; -pub mod player; -pub mod tags; +pub mod camera; +// pub mod character_controller; +pub mod player; +pub mod tags; diff --git a/src/components/player.rs b/src/components/player.rs index 1bd3bbd..a34a59f 100644 --- a/src/components/player.rs +++ b/src/components/player.rs @@ -1,49 +1,49 @@ -use bevy::prelude::*; -use bevy_rapier3d::prelude::GravityScale; - -#[derive(Component, Default, Reflect)] -#[require(PlayerVelocity, MoveSpeed, JumpSpeed, PlayerDrag)] -pub struct PlayerMotion(pub Vec3); - -#[derive(Component, Default, Reflect)] -pub struct PlayerForce(pub Vec3); - -#[derive(Component, Reflect)] -#[require(GravityScale)] -pub struct GravityDirection(pub Option); - -impl Default for GravityDirection { - fn default() -> Self { - Self::DOWN - } -} - -impl GravityDirection { - pub const DOWN: GravityDirection = GravityDirection(Some(Dir3::NEG_Y)); - #[allow(dead_code)] - pub const NONE: GravityDirection = GravityDirection(None); -} - -#[derive(Component, Default, Reflect)] -pub struct PlayerVelocity(pub Vec3); - -#[derive(Component, Reflect)] -pub struct MoveSpeed(pub f32); - -impl Default for MoveSpeed { - fn default() -> Self { - Self(10.0) - } -} - -#[derive(Component, Reflect)] -pub struct JumpSpeed(pub f32); - -impl Default for JumpSpeed { - fn default() -> Self { - Self(10.0) - } -} - -#[derive(Component, Default, Reflect)] -pub struct PlayerDrag(pub f32); +use bevy::prelude::*; +use bevy_rapier3d::prelude::GravityScale; + +#[derive(Component, Default, Reflect)] +#[require(PlayerVelocity, MoveSpeed, JumpSpeed, PlayerDrag)] +pub struct PlayerMotion(pub Vec3); + +#[derive(Component, Default, Reflect)] +pub struct PlayerForce(pub Vec3); + +#[derive(Component, Reflect)] +#[require(GravityScale)] +pub struct GravityDirection(pub Option); + +impl Default for GravityDirection { + fn default() -> Self { + Self::DOWN + } +} + +impl GravityDirection { + pub const DOWN: GravityDirection = GravityDirection(Some(Dir3::NEG_Y)); + #[allow(dead_code)] + pub const NONE: GravityDirection = GravityDirection(None); +} + +#[derive(Component, Default, Reflect)] +pub struct PlayerVelocity(pub Vec3); + +#[derive(Component, Reflect)] +pub struct MoveSpeed(pub f32); + +impl Default for MoveSpeed { + fn default() -> Self { + Self(10.0) + } +} + +#[derive(Component, Reflect)] +pub struct JumpSpeed(pub f32); + +impl Default for JumpSpeed { + fn default() -> Self { + Self(10.0) + } +} + +#[derive(Component, Default, Reflect)] +pub struct PlayerDrag(pub f32); diff --git a/src/components/tags.rs b/src/components/tags.rs index aa07209..9e4f616 100644 --- a/src/components/tags.rs +++ b/src/components/tags.rs @@ -1,10 +1,10 @@ -use bevy::prelude::*; - -use crate::components::player::*; - -#[derive(Component, Reflect)] -#[require(PlayerMotion, PlayerForce, GravityDirection)] -pub struct Player; - -#[derive(Component, Reflect)] -pub struct Ship; +use bevy::prelude::*; + +use crate::components::player::*; + +#[derive(Component, Reflect)] +#[require(PlayerMotion, PlayerForce, GravityDirection)] +pub struct Player; + +#[derive(Component, Reflect)] +pub struct Ship; diff --git a/src/macros.rs b/src/macros.rs new file mode 100644 index 0000000..84f02ee --- /dev/null +++ b/src/macros.rs @@ -0,0 +1,16 @@ +#[macro_export] +macro_rules! configure_sets { + ( + $app: expr, + $system_set: expr, + $condition: expr + ) => { + $app.configure_sets(PreUpdate, $system_set.run_if($condition)) + .configure_sets(Update, $system_set.run_if($condition)) + .configure_sets(PostUpdate, $system_set.run_if($condition)) + .configure_sets(Last, $system_set.run_if($condition)); + $app.configure_sets(FixedPreUpdate, $system_set.run_if($condition)) + .configure_sets(FixedUpdate, $system_set.run_if($condition)) + .configure_sets(FixedPostUpdate, $system_set.run_if($condition)); + }; +} diff --git a/src/main.rs b/src/main.rs index 01a0958..cd03266 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,39 +1,40 @@ -mod plugins; -mod states; -mod utils; -use bevy::{prelude::*, window::PresentMode}; -use bevy_inspector_egui::{bevy_egui::EguiPlugin, quick::WorldInspectorPlugin}; -use plugins::GamePlugin; -mod components; -mod resources; -const NAME: &str = "Space Game"; -fn main() { - App::new() - .add_plugins(( - DefaultPlugins - .set(WindowPlugin { - primary_window: Some(Window { - title: NAME.into(), - name: Some(NAME.into()), - #[cfg(debug_assertions)] - resolution: (1920., 1080.).into(), - present_mode: PresentMode::AutoNoVsync, - #[cfg(not(debug_assertions))] - mode: bevy::window::WindowMode::BorderlessFullscreen, - ..default() - }), - ..default() - }) - .set(AssetPlugin { - #[cfg(not(debug_assertions))] - watch_for_changes_override: Some(true), - ..Default::default() - }), - EguiPlugin { - enable_multipass_for_primary_context: true, - }, - WorldInspectorPlugin::new(), - GamePlugin, - )) - .run(); -} +mod macros; +mod plugins; +mod states; +mod utils; +use bevy::{prelude::*, window::PresentMode}; +use bevy_inspector_egui::{bevy_egui::EguiPlugin, quick::WorldInspectorPlugin}; +use plugins::GamePlugin; +mod components; +mod resources; +const NAME: &str = "Space Game"; +fn main() { + App::new() + .add_plugins(( + DefaultPlugins + .set(WindowPlugin { + primary_window: Some(Window { + title: NAME.into(), + name: Some(NAME.into()), + #[cfg(debug_assertions)] + resolution: (1920., 1080.).into(), + present_mode: PresentMode::AutoNoVsync, + #[cfg(not(debug_assertions))] + mode: bevy::window::WindowMode::BorderlessFullscreen, + ..default() + }), + ..default() + }) + .set(AssetPlugin { + #[cfg(not(debug_assertions))] + watch_for_changes_override: Some(true), + ..Default::default() + }), + EguiPlugin { + enable_multipass_for_primary_context: true, + }, + WorldInspectorPlugin::new(), + GamePlugin, + )) + .run(); +} diff --git a/src/plugins/camera.rs b/src/plugins/camera.rs index 056d7d4..3814b87 100644 --- a/src/plugins/camera.rs +++ b/src/plugins/camera.rs @@ -1,61 +1,61 @@ -use bevy::prelude::*; -#[cfg(feature = "dev")] -use bevy::window::PrimaryWindow; - -use crate::components::camera::*; - -pub struct CameraPlugin; - -impl Plugin for CameraPlugin { - fn build(&self, app: &mut App) { - app.add_systems(Update, camera_pitch); - app.add_systems(Update, camera_attachment); - #[cfg(feature = "dev")] - app.add_systems(Update, camera_toggle); - } -} - -pub fn camera_attachment( - attachment_targets: Query<&GlobalTransform>, - cam: Single<(&mut Transform, &CameraAttachment, &CameraMode)>, -) { - let (mut transform, attach, mode) = cam.into_inner(); - - if let Ok(tgt) = attachment_targets.get(attach.0) { - match mode { - CameraMode::Player => { - transform.rotation = tgt.rotation(); - transform.translation = tgt.translation(); - } - CameraMode::Ship => todo!("Ship Mode"), - CameraMode::Disabled => (), - } - } -} - -pub fn camera_pitch(cam_query: Query<(&mut Transform, &CameraPitch)>) { - for (mut cam_transform, pitch) in cam_query { - cam_transform.rotation = Quat::from_rotation_x(pitch.0); - } -} - -#[cfg(feature = "dev")] -pub fn camera_toggle( - key: Res>, - mut window: Single<&mut Window, With>, - camera: Single<&mut CameraMode>, -) { - use bevy::window::CursorGrabMode; - let mut mode = camera.into_inner(); - if key.just_pressed(KeyCode::Escape) { - if window.cursor_options.visible { - *mode = CameraMode::Player; - window.cursor_options.grab_mode = CursorGrabMode::Locked; - window.cursor_options.visible = false; - } else { - *mode = CameraMode::Disabled; - window.cursor_options.grab_mode = CursorGrabMode::None; - window.cursor_options.visible = true; - } - } -} +use bevy::prelude::*; +#[cfg(feature = "dev")] +use bevy::window::PrimaryWindow; + +use crate::components::camera::*; + +pub struct CameraPlugin; + +impl Plugin for CameraPlugin { + fn build(&self, app: &mut App) { + app.add_systems(Update, camera_pitch); + app.add_systems(Update, camera_attachment); + #[cfg(feature = "dev")] + app.add_systems(Update, camera_toggle); + } +} + +pub fn camera_attachment( + attachment_targets: Query<&GlobalTransform>, + cam: Single<(&mut Transform, &CameraAttachment, &CameraMode)>, +) { + let (mut transform, attach, mode) = cam.into_inner(); + + if let Ok(tgt) = attachment_targets.get(attach.0) { + match mode { + CameraMode::Player => { + transform.rotation = tgt.rotation(); + transform.translation = tgt.translation(); + } + CameraMode::Ship => todo!("Ship Mode"), + CameraMode::Disabled => (), + } + } +} + +pub fn camera_pitch(cam_query: Query<(&mut Transform, &CameraPitch)>) { + for (mut cam_transform, pitch) in cam_query { + cam_transform.rotation = Quat::from_rotation_x(pitch.0); + } +} + +#[cfg(feature = "dev")] +pub fn camera_toggle( + key: Res>, + mut window: Single<&mut Window, With>, + camera: Single<&mut CameraMode>, +) { + use bevy::window::CursorGrabMode; + let mut mode = camera.into_inner(); + if key.just_pressed(KeyCode::Escape) { + if window.cursor_options.visible { + *mode = CameraMode::Player; + window.cursor_options.grab_mode = CursorGrabMode::Locked; + window.cursor_options.visible = false; + } else { + *mode = CameraMode::Disabled; + window.cursor_options.grab_mode = CursorGrabMode::None; + window.cursor_options.visible = true; + } + } +} diff --git a/src/plugins/follow_cam.rs b/src/plugins/follow_cam.rs index 24ed8ff..16014b2 100644 --- a/src/plugins/follow_cam.rs +++ b/src/plugins/follow_cam.rs @@ -1,28 +1,28 @@ -use bevy::prelude::*; - -use crate::components::camera::{FollowCam, FollowTarget}; - -pub struct FollowCamPlugin; - -impl Plugin for FollowCamPlugin { - fn build(&self, app: &mut App) { - app.add_systems(Update, (set_cam_target, follow_cam).chain()); - } -} - -fn set_cam_target(transforms: Query<&GlobalTransform>, cam_target: Single<(&mut FollowTarget, &FollowCam)>) { - let (mut tgt, cam) = cam_target.into_inner(); - if let Ok(tgt_transform) = transforms.get(cam.target) { - tgt.pos = tgt_transform.translation(); - tgt.rot = tgt_transform.rotation(); - tgt.up = tgt_transform.up(); - } -} - -fn follow_cam(cam: Single<(&mut Transform, &FollowTarget, &FollowCam)>) { - let (mut transform, tgt, cam) = cam.into_inner(); - - let offset = tgt.rot * Vec3::new(0.0, cam.height, cam.distance); - transform.translation = offset + tgt.pos; - *transform = transform.looking_at(tgt.pos, tgt.up); -} +use bevy::prelude::*; + +use crate::components::camera::{FollowCam, FollowTarget}; + +pub struct FollowCamPlugin; + +impl Plugin for FollowCamPlugin { + fn build(&self, app: &mut App) { + app.add_systems(Update, (set_cam_target, follow_cam).chain()); + } +} + +fn set_cam_target(transforms: Query<&GlobalTransform>, cam_target: Single<(&mut FollowTarget, &FollowCam)>) { + let (mut tgt, cam) = cam_target.into_inner(); + if let Ok(tgt_transform) = transforms.get(cam.target) { + tgt.pos = tgt_transform.translation(); + tgt.rot = tgt_transform.rotation(); + tgt.up = tgt_transform.up(); + } +} + +fn follow_cam(cam: Single<(&mut Transform, &FollowTarget, &FollowCam)>) { + let (mut transform, tgt, cam) = cam.into_inner(); + + let offset = tgt.rot * Vec3::new(0.0, cam.height, cam.distance); + transform.translation = offset + tgt.pos; + *transform = transform.looking_at(tgt.pos, tgt.up); +} diff --git a/src/plugins/game.rs b/src/plugins/game.rs index e5cee22..ea2b051 100644 --- a/src/plugins/game.rs +++ b/src/plugins/game.rs @@ -1,155 +1,173 @@ -use crate::{ - components::{ - camera::{CameraAttachment, CameraMode, CameraPitch, FollowCam, MainCamera}, - player::PlayerDrag, - tags::{Player, Ship}, - }, - plugins::{state_management::StateManagementPlugin, *}, - states::input::{InputState, PlayerState}, -}; -use bevy::{ - prelude::*, - window::{CursorGrabMode, PrimaryWindow}, -}; -use bevy_rapier3d::prelude::*; - -#[derive(Default)] -pub struct GamePlugin; - -impl Plugin for GamePlugin { - fn build(&self, app: &mut bevy::app::App) { - app.add_plugins(( - FollowCamPlugin, - CameraPlugin, - StateManagementPlugin, - // ShipPlugin, - TypesPlugin, - PlayerPlugin, - )); - app.add_plugins(( - RapierPhysicsPlugin::::default(), - #[cfg(feature = "dev-phys")] - RapierDebugRenderPlugin::default(), - )); - app.add_systems(Startup, (setup_scene, spawn_ship).chain()); - } -} - -fn setup_scene( - mut commands: Commands, - mut meshes: ResMut>, - mut materials: ResMut>, - mut window: Single<&mut Window, With>, -) { - window.cursor_options.visible = false; - window.cursor_options.grab_mode = CursorGrabMode::Locked; - - let player_eye = commands - .spawn(( - Name::new("Eye"), - Transform::from_translation(Vec3::new(0.0, 1.0, 0.0)), - CameraPitch::default(), - )) - .id(); - let mut player_commands = commands.spawn(( - Name::new("Player"), - Player, - PlayerDrag(0.5), - Collider::capsule_y(0.5, 0.5), - RigidBody::KinematicPositionBased, - KinematicCharacterController::default(), - Mesh3d(meshes.add(Capsule3d::new(0.5, 1.0))), - MeshMaterial3d(materials.add(Color::linear_rgb(1.0, 0.0, 0.2))), - Transform::from_translation(Vec3::new(0.0, 10.0, 10.0)), - )); - player_commands.add_child(player_eye); - - commands.spawn(( - Name::new("Camera"), - Transform::from_xyz(0.0, 1.3, 0.0), - Visibility::default(), - MainCamera, - Camera3d::default(), - CameraMode::Player, - CameraAttachment(player_eye), - )); - - commands.spawn(( - DirectionalLight { - shadows_enabled: true, - ..default() - }, - Transform::default().looking_to( - Dir3::from_xyz(-1.0, -1.0, -1.0).expect("Invaid Direction for light"), - Dir3::Y, - ), - )); - - let cube = meshes.add(Cuboid::new(100.0, 0.1, 100.0)); - let material = materials.add(Color::WHITE); - commands.spawn(( - Mesh3d(cube), - MeshMaterial3d(material), - Transform::default(), - RigidBody::Fixed, - Collider::cuboid(100.0, 0.1, 100.0), - )); -} - -fn spawn_ship( - mut commands: Commands, - mut meshes: ResMut>, - mut materials: ResMut>, -) { - let window_material = materials.add(Color::linear_rgba(1.0, 0.0, 1.0, 0.5)); - - let material = materials.add(Color::BLACK); - - commands.spawn(( - Mesh3d(meshes.add(Cuboid::new(3.0, 0.1, 6.0))), - MeshMaterial3d(material.clone()), - Name::new("Ship"), - Ship, - Velocity::zero(), - Damping::default(), - Transform::from_xyz(0.0, 1.0, 0.0), - RigidBody::Dynamic, - children![ - ( - Name::new("Back Wall"), - Mesh3d(meshes.add(Cuboid::new(3.0, 2.0, 0.1))), - Collider::cuboid(3.0, 2.0, 0.1), - MeshMaterial3d(material.clone()), - Transform::from_xyz(0.0, 1.0, 6.0 / 2.0), - ), - ( - Name::new("Front Window"), - Mesh3d(meshes.add(Cuboid::new(3.0, 2.0, 0.1))), - Collider::cuboid(3.0, 2.0, 0.1), - MeshMaterial3d(window_material), - Transform::from_xyz(0.0, 1.0, -6.0 / 2.0), - ), - ( - Name::new("Right Wall"), - Mesh3d(meshes.add(Cuboid::new(0.1, 2.0, 6.0))), - Collider::cuboid(0.1, 2.0, 6.0), - MeshMaterial3d(material.clone()), - Transform::from_xyz(3.0 / 2.0, 1.0, 0.0), - ), - ( - Name::new("Left Wall"), - Mesh3d(meshes.add(Cuboid::new(0.1, 2.0, 6.0))), - Collider::cuboid(0.1, 2.0, 6.0), - MeshMaterial3d(material.clone()), - Transform::from_xyz(-3.0 / 2.0, 1.0, 0.0), - ), - ( - Name::new("Roof"), - Mesh3d(meshes.add(Cuboid::new(3.0, 0.1, 6.0))), - Collider::cuboid(3.0, 0.1, 6.0), - MeshMaterial3d(material.clone()), - Transform::from_xyz(0.0, 2.0, 0.0), - ) - ], - )); -} +use crate::{ + components::{ + camera::{CameraAttachment, CameraMode, CameraPitch, FollowCam, MainCamera}, + player::PlayerDrag, + tags::{Player, Ship}, + }, + plugins::{state_management::StateManagementPlugin, *}, + states::{ + game::*, + input::{InputState, PlayerState}, + loading::{AssetLoadingState, StartupLoadingState}, + menu::MenuState, + }, +}; +use bevy::{ + prelude::*, + window::{CursorGrabMode, PrimaryWindow}, +}; +use bevy_asset_loader::prelude::*; +use bevy_rapier3d::prelude::*; + +#[derive(Default)] +pub struct GamePlugin; + +impl Plugin for GamePlugin { + fn build(&self, app: &mut bevy::app::App) { + app.init_state::(); + app.init_state::(); + app.insert_state(GameState::Startup); + app.init_state::(); + app.init_state::(); + app.add_loading_state( + LoadingState::new(AssetLoadingState::Loading).continue_to_state(AssetLoadingState::Finalizing), + ) + .add_loading_state( + LoadingState::new(StartupLoadingState::Loading).continue_to_state(StartupLoadingState::Finalizing), + ); + + app.add_plugins(( + FollowCamPlugin, + CameraPlugin, + StateManagementPlugin, + // ShipPlugin, + TypesPlugin, + PlayerPlugin, + )); + app.add_plugins(( + RapierPhysicsPlugin::::default(), + #[cfg(feature = "dev-phys")] + RapierDebugRenderPlugin::default(), + )); + app.add_systems(Startup, (setup_scene, spawn_ship).chain()); + } +} + +fn setup_scene( + mut commands: Commands, + mut meshes: ResMut>, + mut materials: ResMut>, + mut window: Single<&mut Window, With>, +) { + window.cursor_options.visible = false; + window.cursor_options.grab_mode = CursorGrabMode::Locked; + + let player_eye = commands + .spawn(( + Name::new("Eye"), + Transform::from_translation(Vec3::new(0.0, 1.0, 0.0)), + CameraPitch::default(), + )) + .id(); + let mut player_commands = commands.spawn(( + Name::new("Player"), + Player, + PlayerDrag(0.5), + Collider::capsule_y(0.5, 0.5), + RigidBody::KinematicPositionBased, + KinematicCharacterController::default(), + Mesh3d(meshes.add(Capsule3d::new(0.5, 1.0))), + MeshMaterial3d(materials.add(Color::linear_rgb(1.0, 0.0, 0.2))), + Transform::from_translation(Vec3::new(0.0, 10.0, 10.0)), + )); + player_commands.add_child(player_eye); + + commands.spawn(( + Name::new("Camera"), + Transform::from_xyz(0.0, 1.3, 0.0), + Visibility::default(), + MainCamera, + Camera3d::default(), + CameraMode::Player, + CameraAttachment(player_eye), + )); + + commands.spawn(( + DirectionalLight { + shadows_enabled: true, + ..default() + }, + Transform::default().looking_to( + Dir3::from_xyz(-1.0, -1.0, -1.0).expect("Invaid Direction for light"), + Dir3::Y, + ), + )); + + let cube = meshes.add(Cuboid::new(100.0, 0.1, 100.0)); + let material = materials.add(Color::WHITE); + commands.spawn(( + Mesh3d(cube), + MeshMaterial3d(material), + Transform::default(), + RigidBody::Fixed, + Collider::cuboid(100.0, 0.1, 100.0), + )); +} + +fn spawn_ship( + mut commands: Commands, + mut meshes: ResMut>, + mut materials: ResMut>, +) { + let window_material = materials.add(Color::linear_rgba(1.0, 0.0, 1.0, 0.5)); + + let material = materials.add(Color::BLACK); + + commands.spawn(( + Mesh3d(meshes.add(Cuboid::new(3.0, 0.1, 6.0))), + MeshMaterial3d(material.clone()), + Name::new("Ship"), + Ship, + Velocity::zero(), + Damping::default(), + Transform::from_xyz(0.0, 1.0, 0.0), + RigidBody::Dynamic, + children![ + ( + Name::new("Back Wall"), + Mesh3d(meshes.add(Cuboid::new(3.0, 2.0, 0.1))), + Collider::cuboid(3.0, 2.0, 0.1), + MeshMaterial3d(material.clone()), + Transform::from_xyz(0.0, 1.0, 6.0 / 2.0), + ), + ( + Name::new("Front Window"), + Mesh3d(meshes.add(Cuboid::new(3.0, 2.0, 0.1))), + Collider::cuboid(3.0, 2.0, 0.1), + MeshMaterial3d(window_material), + Transform::from_xyz(0.0, 1.0, -6.0 / 2.0), + ), + ( + Name::new("Right Wall"), + Mesh3d(meshes.add(Cuboid::new(0.1, 2.0, 6.0))), + Collider::cuboid(0.1, 2.0, 6.0), + MeshMaterial3d(material.clone()), + Transform::from_xyz(3.0 / 2.0, 1.0, 0.0), + ), + ( + Name::new("Left Wall"), + Mesh3d(meshes.add(Cuboid::new(0.1, 2.0, 6.0))), + Collider::cuboid(0.1, 2.0, 6.0), + MeshMaterial3d(material.clone()), + Transform::from_xyz(-3.0 / 2.0, 1.0, 0.0), + ), + ( + Name::new("Roof"), + Mesh3d(meshes.add(Cuboid::new(3.0, 0.1, 6.0))), + Collider::cuboid(3.0, 0.1, 6.0), + MeshMaterial3d(material.clone()), + Transform::from_xyz(0.0, 2.0, 0.0), + ) + ], + )); +} diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs index 316ba6e..6cace2a 100644 --- a/src/plugins/mod.rs +++ b/src/plugins/mod.rs @@ -1,18 +1,18 @@ -// mod character_controller; -mod camera; -mod follow_cam; -mod game; -mod player; -mod ship; -mod ship_cam; -mod state_management; -mod types; - -// pub use character_controller::*; -pub use camera::*; -pub use follow_cam::*; -pub use game::*; -pub use player::*; -pub use ship::*; -pub use ship_cam::*; -pub use types::*; +// mod character_controller; +mod camera; +mod follow_cam; +mod game; +mod player; +mod ship; +mod ship_cam; +mod state_management; +mod types; + +// pub use character_controller::*; +pub use camera::*; +pub use follow_cam::*; +pub use game::*; +pub use player::*; +pub use ship::*; +pub use ship_cam::*; +pub use types::*; diff --git a/src/plugins/player.rs b/src/plugins/player.rs index 2f4d462..eb06b5f 100644 --- a/src/plugins/player.rs +++ b/src/plugins/player.rs @@ -1,164 +1,164 @@ -use std::f32::{EPSILON, consts::FRAC_PI_2}; - -use bevy::{input::mouse::MouseMotion, prelude::*}; -use bevy_rapier3d::prelude::*; - -use crate::{ - components::{ - camera::CameraPitch, - player::{GravityDirection, JumpSpeed, MoveSpeed, PlayerDrag, PlayerForce, PlayerMotion, PlayerVelocity}, - tags::Player, - }, - states::input::PlayerInputSystems, - utils::{input::get_mouse_delta, rotation::get_alignment_rotation_preserve_twist}, -}; - -pub struct PlayerPlugin; - -impl Plugin for PlayerPlugin { - fn build(&self, app: &mut App) { - app.add_systems(PreUpdate, (keyboard_input, player_look).in_set(PlayerInputSystems)); - app.add_systems(Update, (apply_gravity, apply_forces, apply_motion, apply_drag).chain()); - app.add_systems(Update, align_with_gravity); - } -} - -fn apply_forces(player: Single<(&mut PlayerVelocity, &PlayerForce), With>, time: Res