M crates/unified/src/client/mod.rs => crates/unified/src/client/mod.rs +6 -3
@@ 4,14 4,15 @@ use crate::client::planet::indicators::indicators_plugin;
use crate::client::starfield::starfield_plugin;
use crate::client::ui::ui_plugin;
use crate::client::zoom::zoom_plugin;
-use crate::client::starguide::starguide_plugin;
+use crate::client::starguide::init::starguide_init_plugin;
+use crate::client::starguide::input::starguide_input_plugin;
use crate::ecs::{Hi, Part, Player};
use aeronet_websocket::client::WebSocketClient;
use bevy::dev_tools::picking_debug::DebugPickingMode;
use crate::prelude::*;
use planet::incoming_planets::incoming_planets_plugin;
use crate::client::ship::attachment::client_attachment_plugin;
-use crate::ecs::{Me, STARGUIDE_LAYER};
+use crate::ecs::{Me, GameplayState, STARGUIDE_LAYER};
pub mod colors;
pub mod key_input;
@@ 55,7 56,9 @@ impl Plugin for ClientPlugin {
.add_plugins(ui_plugin)
.add_plugins(zoom_plugin)
.add_plugins(client_attachment_plugin)
- .add_plugins(starguide_plugin)
+ .add_plugins(starguide_init_plugin)
+ .add_plugins(starguide_input_plugin)
+ .insert_state(GameplayState::Main)
.insert_resource(DebugPickingMode::Disabled);
// These are only needed if we're actually doing network things
M crates/unified/src/client/rendering/mod.rs => crates/unified/src/client/rendering/mod.rs +2 -5
@@ 2,13 2,13 @@ use bevy::anti_alias::fxaa::Fxaa;
use bevy::app::{App, Startup};
use bevy::core_pipeline::tonemapping::DebandDither;
use bevy::post_process::bloom::Bloom;
-use crate::ecs::{MainCamera, StarguideCamera, Me, MAIN_LAYER};
+use crate::ecs::{GameplayState, MainCamera, StarguideCamera, Me, MAIN_LAYER};
use crate::prelude::*;
pub fn render_plugin(app: &mut App) {
app
.add_systems(Startup, setup_graphics)
- .add_systems(Update, follow_camera);
+ .add_systems(Update, follow_camera.run_if(in_state(GameplayState::Main)));
}
@@ 32,11 32,8 @@ fn follow_camera(
player: Query<&Transform, With<Me>>,
) {
let mut camera = camera.single_mut().unwrap();
- let mut starguide_camera = starguide_camera.single_mut().unwrap();
let Ok(player) = player.single() else {
return;
};
camera.translation = player.translation;
- starguide_camera.translation = player.translation;
-
}
R crates/unified/src/client/starguide.rs => crates/unified/src/client/starguide/init.rs +1 -1
@@ 3,7 3,7 @@ use crate::ecs::{StarguideCamera, STARGUIDE_LAYER};
use crate::config::planet::SpecialSpriteProperties;
use crate::config::planet::Planet;
-pub fn starguide_plugin(app: &mut App) {
+pub fn starguide_init_plugin(app: &mut App) {
app.add_systems(Startup, init_starguide);
}
A crates/unified/src/client/starguide/input.rs => crates/unified/src/client/starguide/input.rs +44 -0
@@ 0,0 1,44 @@
+use crate::prelude::*;
+use crate::client::input::CursorWorldCoordinates;
+use crate::ecs::StarguideCamera;
+
+pub fn starguide_input_plugin(app: &mut App) {
+ app
+ .add_systems(Update, (on_click, starguide_drag))
+ .insert_resource(StarguideDrag::default());
+}
+
+#[derive(Resource, Default)]
+struct StarguideDrag {
+ is_dragging: bool,
+ init_cursor_pos: Vec2,
+ init_camera_pos: Vec2,
+}
+
+fn on_click(
+ ev: Res<ButtonInput<MouseButton>>,
+ mut drag: ResMut<StarguideDrag>,
+ camera: Single<&Transform, With<StarguideCamera>>,
+ cursor: Res<CursorWorldCoordinates>
+) {
+ let Some(cursor) = cursor.0 else { return };
+ if ev.just_pressed(MouseButton::Left) {
+ drag.is_dragging = true;
+ drag.init_cursor_pos = cursor;
+ drag.init_camera_pos = camera.translation.truncate();
+ }
+ if ev.just_released(MouseButton::Left) {
+ drag.is_dragging = false;
+ }
+}
+
+fn starguide_drag(
+ drag: ResMut<StarguideDrag>,
+ mut camera: Single<&mut Transform, (With<StarguideCamera>)>,
+ cursor: Res<CursorWorldCoordinates>,
+) {
+ if !drag.is_dragging { return }
+ let Some(cursor) = cursor.0 else { return };
+
+ camera.translation = drag.init_camera_pos.extend(0.0) - (cursor - drag.init_cursor_pos).extend(0.0);
+}
A crates/unified/src/client/starguide/mod.rs => crates/unified/src/client/starguide/mod.rs +2 -0
@@ 0,0 1,2 @@
+pub mod init;
+pub mod input;
M crates/unified/src/client/zoom.rs => crates/unified/src/client/zoom.rs +10 -3
@@ 6,7 6,7 @@ use bevy::{
use crate::{
client::starfield::{BACK_STARFIELD_SIZE, FRONT_STARFIELD_SIZE, MID_STARFIELD_SIZE, StarfieldSize}, ecs::{MainCamera, Me, StarfieldBack, StarfieldFront, StarfieldMid}
};
-use crate::ecs::StarguideCamera;
+use crate::ecs::{StarguideCamera, GameplayState};
pub fn zoom_plugin(app: &mut App) {
app.add_systems(Update, on_scroll);
@@ 14,6 14,8 @@ pub fn zoom_plugin(app: &mut App) {
fn on_scroll(
mut scroll_events: MessageReader<MouseWheel>,
+ gameplay_state: Res<State<GameplayState>>,
+ mut gameplay_next_state: ResMut<NextState<GameplayState>>,
window: Single<&Window>,
starfield_back: Single<
(&mut Sprite, &mut Transform, &mut Visibility, Option<&StarfieldSize>),
@@ 87,17 89,22 @@ fn on_scroll(
camera.1.scale *= 1.03;
starguide_camera.1.scale *= 1.03;
}
- if camera.1.scale.z > 30.0 {
+ if camera.1.scale.z > 20.0 && matches!(gameplay_state.get(), GameplayState::Main) {
camera.0.is_active = false;
starguide_camera.0.is_active = true;
+
+ starguide_camera.1.translation = player.translation;
+ gameplay_next_state.set(GameplayState::Starguide);
+
starfield_back.image_mode = SpriteImageMode::Auto;
starfield_mid.image_mode = SpriteImageMode::Auto;
starfield_front.image_mode = SpriteImageMode::Auto;
*visibility_back = Visibility::Hidden;
*visibility_mid = Visibility::Hidden;
*visibility_front = Visibility::Hidden;
- } else {
+ } else if camera.1.scale.z <= 20.0 && matches!(gameplay_state.get(), GameplayState::Starguide) {
camera.0.is_active = true;
+ gameplay_next_state.set(GameplayState::Main);
starguide_camera.0.is_active = false;
if matches!(*visibility_back, Visibility::Hidden) {
if let Some(size_back) = size_back {
M crates/unified/src/ecs.rs => crates/unified/src/ecs.rs +6 -0
@@ 11,6 11,12 @@ use avian2d::prelude::*;
use crate::thrust::ThrustSolution;
use std::sync::LazyLock;
+#[derive(States, Debug, Clone, PartialEq, Eq, Hash)]
+pub enum GameplayState {
+ Main,
+ Starguide,
+}
+
pub const MAIN_LAYER: RenderLayers = RenderLayers::layer(0);
pub const STARGUIDE_LAYER: RenderLayers = RenderLayers::layer(1);
pub static MAIN_STAR_LAYERS: LazyLock<RenderLayers> = LazyLock::new(|| RenderLayers::from_layers(&[0, 1]));