diff --git a/src/main.rs b/src/main.rs index 500ad27..aa15696 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,7 @@ mod ui; use crate::states::game::state::MainGameState; use crate::states::main_menu::state::MainMenuState; use crate::states::settings_menu::state::SettingsMenuState; +use crate::states::linear::plugin::LinearPlugin; const FACTOR: u32 = 80; const WIDTH: u32 = 16; @@ -36,6 +37,7 @@ fn main() { MainMenuState, SettingsMenuState, MainGameState, + LinearPlugin, )) .add_systems(Startup, setup) .add_systems(Update, exit_system) diff --git a/src/states/app_states.rs b/src/states/app_states.rs index 41eee3a..77f2b45 100644 --- a/src/states/app_states.rs +++ b/src/states/app_states.rs @@ -8,4 +8,5 @@ pub enum AppState { GameState, GameRestart, LevelState, + LinearState, } \ No newline at end of file diff --git a/src/states/game/systems.rs b/src/states/game/systems.rs index 2023023..d2be510 100644 --- a/src/states/game/systems.rs +++ b/src/states/game/systems.rs @@ -9,7 +9,7 @@ pub fn restart_game_button_system( ) { for interaction in &interaction_query { if matches!(interaction, Interaction::Pressed) { - println!("πŸ”„ Кнопка Restart Π½Π°ΠΆΠ°Ρ‚Π°! ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ Π² Restarting..."); + println!("Бброс состояния"); next_state.set(AppState::GameRestart); } } diff --git a/src/states/level/components_cannon.rs b/src/states/level/components_cannon.rs index 94556d1..49aa22d 100644 --- a/src/states/level/components_cannon.rs +++ b/src/states/level/components_cannon.rs @@ -30,7 +30,7 @@ impl CannonState { let cur = self.current_type; self.current_type = self.next_type; self.next_type = cur; - + } } diff --git a/src/states/linear/components.rs b/src/states/linear/components.rs new file mode 100644 index 0000000..8fb44ec --- /dev/null +++ b/src/states/linear/components.rs @@ -0,0 +1,4 @@ +use bevy::prelude::*; + +#[derive(Component)] +pub struct LinearStateMarker; \ No newline at end of file diff --git a/src/states/linear/components_track.rs b/src/states/linear/components_track.rs new file mode 100644 index 0000000..36ab136 --- /dev/null +++ b/src/states/linear/components_track.rs @@ -0,0 +1,17 @@ +use bevy::prelude::*; + +#[derive(Component)] +pub struct Track{ + pub start_point: Vec2, + pub start_direction: Vec2, // Π±ΡƒΠ΄Π΅Ρ‚ Π½ΠΎΡ€ΠΌΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½ΠΎ ΠΏΡ€ΠΈ построСнии + pub segments: Vec, +} + +// линия всСгда строится ΠΎΡ‚ Ρ‚ΠΎΡ‡ΠΊΠΈ старта ΠΏΠΎ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΡŽ +// Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ измСняСтся сСгмСнтами ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚Π° +// left ΠΏΡ€ΠΈ истинС - ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ ΠΏΡ€ΠΎΡ‚ΠΈΠ² часовой стрСлки, лоТь - ΠΏΠΎ часовой +#[derive(Clone, Copy)] +pub enum PathSegment{ + Line { length: f32 }, + Turn { radius: f32, left: bool }, +} \ No newline at end of file diff --git a/src/states/linear/mod.rs b/src/states/linear/mod.rs new file mode 100644 index 0000000..c9c5a5f --- /dev/null +++ b/src/states/linear/mod.rs @@ -0,0 +1,13 @@ +pub mod plugin; + +mod components; +pub use components::*; + +mod systems; +pub use systems::*; + +mod components_track; +pub use components_track::*; + +mod systems_track; +pub use systems_track::*; diff --git a/src/states/linear/plugin.rs b/src/states/linear/plugin.rs new file mode 100644 index 0000000..d1b4e7f --- /dev/null +++ b/src/states/linear/plugin.rs @@ -0,0 +1,22 @@ +use bevy::prelude::*; +use crate::states::AppState::LinearState; +use crate::states::linear::*; + +pub struct LinearPlugin; + +impl Plugin for LinearPlugin { + fn build(&self, app: &mut App) { + app + .add_systems(OnEnter (LinearState), (setup, setup_linear_track).chain()) + .add_systems(Update, (draw_track_gizmos).run_if(in_state(LinearState))) + .add_systems(OnExit (LinearState), cleanup); + } +} + +fn setup(mut commands: Commands) {} + +fn cleanup(mut commands: Commands, query: Query>) { + for entity in query.iter() { + commands.entity(entity).despawn(); + } +} \ No newline at end of file diff --git a/src/states/linear/systems.rs b/src/states/linear/systems.rs new file mode 100644 index 0000000..ab89b70 --- /dev/null +++ b/src/states/linear/systems.rs @@ -0,0 +1,60 @@ +use crate::states; +use bevy::prelude::*; +use states::linear::*; +use std::f32::consts::{FRAC_PI_2, PI}; + +const PINK: Color = Color::srgb_u8(250, 0, 155); +const BLUE: Color = Color::srgb_u8(0, 0, 255); +const GREEN: Color = Color::srgb_u8(0, 255, 0); + +pub fn draw_track_gizmos(query: Query<&Track>, mut gizmos: Gizmos) { + println!("РисуСм Ρ‚Ρ€Π΅ΠΊ ΠΈΠ· ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²ΠΎΠ²"); + for track in &query { + let mut current_pos = track.start_point; + let mut current_dir = track.start_direction.normalize(); + + // Ρ‚ΠΎΡ‡ΠΊΠ° старта + gizmos.circle_2d(current_pos, 5.0, BLUE); + + // рисуСм сСгмСнты + for segment in &track.segments { + match segment { + PathSegment::Line { length } => { + let end_pos = current_pos + current_dir * length; + gizmos.line_2d(current_pos, end_pos, PINK); + current_pos = end_pos + } + + PathSegment::Turn { radius, left } => { + // вычисляСм Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚Π° ΠΈ Π·Π½Π°ΠΊ для ΡƒΠ³Π»Π° + let (normal, sign): (Vec2, f32) = if *left { + (Vec2::new(-current_dir.y, current_dir.x), -1.0) + } else { + (Vec2::new(current_dir.y, -current_dir.x), 1.0) + }; + + let center = current_pos + normal * radius; + let start_vec = current_pos - center; + let initial_vec = if *left { + -start_vec.perp() + } else { + -start_vec + }; + + gizmos.arc_2d( + Isometry2d::new(center, Rot2::radians(initial_vec.to_angle())), + FRAC_PI_2, + *radius, + GREEN, + ); + // current_pos = center + current_dir * radius; + // current_pos = center + normal.perp() * radius; + current_pos = center + normal.perp() * radius * sign; + current_dir = normal; + } + } + } + // рисуСм Ρ„ΠΈΠ½ΠΈΡˆ + gizmos.circle_2d(current_pos, 5.0, Color::WHITE); + } +} diff --git a/src/states/linear/systems_track.rs b/src/states/linear/systems_track.rs new file mode 100644 index 0000000..0a223f0 --- /dev/null +++ b/src/states/linear/systems_track.rs @@ -0,0 +1,44 @@ +use crate::states::linear::*; +use crate::{FACTOR, HEIGHT, WIDTH}; +use bevy::prelude::*; + +pub const CENTER_X: f32 = 0.0; +pub const CENTER_Y: f32 = 0.0; + +// pub const FACTOR_RADIUS: f32 = FACTOR as f32 / 2.0; + +pub const STEP: f32 = FACTOR as f32 / SCALE; +pub const SCALE: f32 = 2.0; + + +pub fn setup_linear_track(mut commands: Commands) { + println!("ΠŸΠΎΡΡ‚Ρ€ΠΎΠ΅Π½ΠΈΠ΅ Ρ‚Ρ€Π΅ΠΊΠ° Π½Π°Ρ‡Π°Ρ‚ΠΎ"); + + commands.spawn(( + Track { + start_point: Vec2 { + x: CENTER_X - FACTOR as f32 * 7.0, + y: CENTER_Y - FACTOR as f32 * 4.0, + }, + start_direction: Vec2::X, + segments: vec![ + PathSegment::Line { length: STEP * 2.0 }, + PathSegment::Turn { radius: STEP, left: true }, + PathSegment::Line { length: STEP }, + PathSegment::Turn { radius: STEP, left: false }, + PathSegment::Line { length: STEP * 10.0 }, + PathSegment::Turn { radius: STEP, left: true }, + PathSegment::Line { length: STEP * 4.0 }, + PathSegment::Turn { radius: STEP, left: true }, + PathSegment::Turn { radius: STEP, left: false }, + PathSegment::Line { length: STEP * 2.0 }, + PathSegment::Turn { radius: STEP, left: true }, + PathSegment::Line { length: STEP * 6.0 }, + PathSegment::Turn { radius: STEP, left: true }, + PathSegment::Line { length: STEP * 1.0 }, + PathSegment::Turn { radius: STEP, left: true }, + ], + }, + LinearStateMarker, + )); +} diff --git a/src/states/main_menu/components.rs b/src/states/main_menu/components.rs index 3aa4de4..0de024f 100644 --- a/src/states/main_menu/components.rs +++ b/src/states/main_menu/components.rs @@ -7,4 +7,7 @@ pub struct MainMenuRootMarker; pub struct MainMenuNewGameButton; #[derive(Component, Copy, Clone)] -pub struct MainMenuSettingsButton; \ No newline at end of file +pub struct MainMenuSettingsButton; + +#[derive(Component, Copy, Clone)] +pub struct MainMenuLinearButton; \ No newline at end of file diff --git a/src/states/main_menu/mod.rs b/src/states/main_menu/mod.rs index 5b3d45a..a89aad4 100644 --- a/src/states/main_menu/mod.rs +++ b/src/states/main_menu/mod.rs @@ -1,5 +1,7 @@ -pub mod state; -pub mod components; +pub(crate) mod state; +pub use state::*; +mod components; pub use components::*; -pub mod systems; +mod systems; +pub use systems::*; pub mod plugin; diff --git a/src/states/main_menu/plugin.rs b/src/states/main_menu/plugin.rs index 3c87e16..3743fea 100644 --- a/src/states/main_menu/plugin.rs +++ b/src/states/main_menu/plugin.rs @@ -1,5 +1,5 @@ use bevy::prelude::*; -use crate::states::main_menu::{MainMenuNewGameButton, MainMenuSettingsButton}; +use crate::states::main_menu::*; use crate::ui::button_click::ButtonClickMessage; use crate::ui::click::handle_click_system; @@ -12,11 +12,13 @@ impl Plugin for MainMenuUiPlugin { fn build(&self, app: &mut App) { app.add_message::>() .add_message::>() + .add_message::>() .add_systems( Update, ( handle_click_system::, handle_click_system::, + handle_click_system::, ).in_set(MainMenuButtonSet) ); } diff --git a/src/states/main_menu/state.rs b/src/states/main_menu/state.rs index eca3c88..ad6bb60 100644 --- a/src/states/main_menu/state.rs +++ b/src/states/main_menu/state.rs @@ -1,6 +1,5 @@ -use crate::states::AppState; -use crate::states::main_menu::{MainMenuNewGameButton, MainMenuRootMarker, MainMenuSettingsButton}; -use crate::states::main_menu::systems::*; +use crate::states::*; +use crate::states::main_menu::*; use crate::ui::button_hover::button_hover; use crate::ui::{ButtonStyle, spawn_background, spawn_button}; use bevy::prelude::*; @@ -20,6 +19,7 @@ impl Plugin for MainMenuState { button_hover, new_game_button_system, settings_button_system, + linear_button_system, ) .run_if(in_state(AppState::MainMenu)), ) @@ -92,6 +92,14 @@ fn setup_main_menu(mut commands: Commands, asset_server: Res) { MainMenuNewGameButton, ); + spawn_button( + &mut commands, + menu_root, + "Π›ΠΈΠ½Π΅ΠΉΠ½ΠΎΠ΅", + &mm_button_style, + MainMenuLinearButton, + ); + spawn_button( &mut commands, menu_root, diff --git a/src/states/main_menu/systems.rs b/src/states/main_menu/systems.rs index e82d451..bdc9082 100644 --- a/src/states/main_menu/systems.rs +++ b/src/states/main_menu/systems.rs @@ -1,5 +1,5 @@ use crate::states::AppState; -use crate::states::main_menu::{MainMenuNewGameButton, MainMenuSettingsButton}; +use crate::states::main_menu::*; use bevy::prelude::*; pub fn new_game_button_system( @@ -23,3 +23,15 @@ pub fn settings_button_system( } } } + +pub fn linear_button_system( + interaction_query: Query<&Interaction, (Changed, With)>, + mut next_state: ResMut>, +) { + for interaction in &interaction_query { + if matches!(interaction, Interaction::Pressed) { + println!("Π›ΠΈΠ½Π΅ΠΉΠ½ΠΎΠ΅ Π½Π°ΠΆΠ°Ρ‚Π°"); + next_state.set(AppState::LinearState); + } + } +} \ No newline at end of file diff --git a/src/states/mod.rs b/src/states/mod.rs index c2219c2..964eb1d 100644 --- a/src/states/mod.rs +++ b/src/states/mod.rs @@ -5,4 +5,5 @@ pub mod main_menu; pub mod settings_menu; pub mod game; -mod level; \ No newline at end of file +mod level; +pub mod linear; \ No newline at end of file