diff --git a/crates/border-wars/src/camera.rs b/crates/border-wars/src/camera.rs index 6c2b50b..c19a3e2 100644 --- a/crates/border-wars/src/camera.rs +++ b/crates/border-wars/src/camera.rs @@ -46,7 +46,11 @@ impl Plugin for CameraPlugin { fn build(&self, app: &mut App) { app.add_systems(Startup, init_camera) .add_systems(Startup, init_resources_for_camera) - .add_systems(Update, movement_system.run_if(in_state(CurrentScene::Game))) + .add_systems( + Update, + (keyboard_movement_system, mouse_movement_system) + .run_if(in_state(CurrentScene::Game)), + ) .add_systems(Update, scale_system.run_if(in_state(CurrentScene::Game))); } } @@ -78,7 +82,7 @@ fn init_resources_for_camera(mut commands: Commands) { } /// Moves the camera with keyboard input. -fn movement_system( +fn keyboard_movement_system( mut query: Query<&mut Transform, With>, keys: Res>, keys_settings: Res, @@ -100,6 +104,35 @@ fn movement_system( } } +/// Moves the camera with mouse input. +fn mouse_movement_system( + mouse_button_input: Res>, + mut query: Query<&mut Transform, With>, + windows: Query<&Window>, + mut last_position: Local>, +) { + let window = windows.get_single().expect("Main window not found"); + let Some(position) = window.cursor_position() else { + return; + }; + + if mouse_button_input.just_pressed(MouseButton::Right) { + *last_position = Some(position); + } + + if mouse_button_input.just_released(MouseButton::Right) { + *last_position = None; + } + + if let Some(old_position) = *last_position { + for mut transform in query.iter_mut() { + let offset = (old_position - position).extend(0.0) * Vec3::new(1., -1., 1.); + transform.translation += offset; + } + *last_position = Some(position); + } +} + /// Scales the view with mouse input. fn scale_system( mut scroll_event: EventReader, diff --git a/crates/border-wars/src/lib.rs b/crates/border-wars/src/lib.rs index 808e0d2..fc115d4 100644 --- a/crates/border-wars/src/lib.rs +++ b/crates/border-wars/src/lib.rs @@ -8,8 +8,8 @@ use serde::{Deserialize, Serialize}; pub mod camera; pub mod map; pub mod networking; -pub mod responsive_scale; pub mod scenes; +pub mod ui; /// The current scene of the game. #[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Hash, States)] diff --git a/crates/border-wars/src/main.rs b/crates/border-wars/src/main.rs index ea58352..8019933 100644 --- a/crates/border-wars/src/main.rs +++ b/crates/border-wars/src/main.rs @@ -7,6 +7,7 @@ use border_wars::map::renderer::RendererPlugin; use border_wars::map::selected_tile::SelectTilePlugin; use border_wars::networking::NetworkingPlugin; use border_wars::scenes::ScenesPlugin; +use border_wars::ui::UiPlugin; fn main() { App::new() @@ -17,5 +18,6 @@ fn main() { .add_plugins(SelectTilePlugin) .add_plugins(NetworkingPlugin) .add_plugins(MapGenerationPlugin) + .add_plugins(UiPlugin) .run(); } diff --git a/crates/border-wars/src/scenes/mod.rs b/crates/border-wars/src/scenes/mod.rs index da18601..2a788fd 100644 --- a/crates/border-wars/src/scenes/mod.rs +++ b/crates/border-wars/src/scenes/mod.rs @@ -3,7 +3,7 @@ use bevy::prelude::*; use bevy_egui::EguiPlugin; -use crate::{responsive_scale, CurrentScene}; +use crate::CurrentScene; pub mod lobby; pub mod menu; @@ -16,7 +16,6 @@ impl Plugin for ScenesPlugin { app.add_plugins(EguiPlugin) .add_state::() .add_plugins(menu::MenuPlugin) - .add_plugins(lobby::LobbyPlugin) - .add_plugins(responsive_scale::ResponsiveScalingPlugin); + .add_plugins(lobby::LobbyPlugin); } } diff --git a/crates/border-wars/src/ui/hover.rs b/crates/border-wars/src/ui/hover.rs new file mode 100644 index 0000000..632dc07 --- /dev/null +++ b/crates/border-wars/src/ui/hover.rs @@ -0,0 +1,38 @@ +//! The file that contains the hover logic. + +use bevy::prelude::*; + +/// The plugin for the hover system. +pub struct HoverPlugin; + +impl Plugin for HoverPlugin { + fn build(&self, app: &mut App) { + app.add_systems(Update, hovering); + } +} + +/// A component that stores the hover texture and the original texture. +#[derive(Component, Clone)] +struct HoveredTexture { + /// The original texture. + texture: Handle, + + /// The hovered texture. + hovered_texture: Handle, +} + +/// The system that applies the hover logic by changing the texture. +fn hovering( + mut interaction_query: Query< + (&Interaction, &HoveredTexture, &mut UiImage), + Changed, + >, +) { + for (interaction, textures, mut image) in interaction_query.iter_mut() { + match *interaction { + Interaction::Hovered => image.texture = textures.hovered_texture.clone(), + Interaction::None => image.texture = textures.texture.clone(), + Interaction::Pressed => (), + } + } +} diff --git a/crates/border-wars/src/ui/mod.rs b/crates/border-wars/src/ui/mod.rs new file mode 100644 index 0000000..9b6dd27 --- /dev/null +++ b/crates/border-wars/src/ui/mod.rs @@ -0,0 +1,19 @@ +//! The file that contains the UI logic. + +pub mod hover; +pub mod responsive_scale; + +use bevy::prelude::*; + +use self::hover::HoverPlugin; +use self::responsive_scale::ResponsiveScalingPlugin; + +/// The plugin for the UI. +pub struct UiPlugin; + +impl Plugin for UiPlugin { + fn build(&self, app: &mut App) { + app.add_plugins(HoverPlugin) + .add_plugins(ResponsiveScalingPlugin); + } +} diff --git a/crates/border-wars/src/responsive_scale.rs b/crates/border-wars/src/ui/responsive_scale.rs similarity index 93% rename from crates/border-wars/src/responsive_scale.rs rename to crates/border-wars/src/ui/responsive_scale.rs index dbca623..81c79b5 100644 --- a/crates/border-wars/src/responsive_scale.rs +++ b/crates/border-wars/src/ui/responsive_scale.rs @@ -29,6 +29,9 @@ pub fn change_scaling( size: Res, ) { let window = windows.get_single().expect("Main window not found"); + if window.resolution.physical_height() == 0 { + return; + }; let (a, b) = ( window.resolution.width() / size.0.x, window.resolution.height() / size.0.y,