diff --git a/src/main.rs b/src/main.rs index a25a4de..58e63d5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,9 @@ use goal::{check_goal, GoalBundle}; use ground_detection::GroundDetectionPlugin; use level_structure::{WallBundle, WallPlugin}; use logging::log_positions; +use menu::spawn_box; use player::PlayerPlugin; +use state::GameState; mod animations; mod camera; @@ -16,13 +18,15 @@ mod goal; mod ground_detection; mod level_structure; mod logging; +mod menu; mod player; - +mod state; pub const GRID_SIZE: i32 = 16; fn main() { App::new() .add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest())) + .insert_state(GameState::MainMenu) .add_plugins(( LdtkPlugin, RapierPhysicsPlugin::::pixels_per_meter(100.0), @@ -46,6 +50,7 @@ fn main() { .register_ldtk_entity::("Goal") .register_ldtk_int_cell::(1) .add_systems(Startup, setup) + .add_systems(Update, spawn_box.run_if(in_state(GameState::MainMenu))) .add_plugins(CameraPlugin) .add_plugins(ShockingAnimationPlugin) .add_systems(Update, (translate_grid_coords_entities, check_goal)) @@ -53,7 +58,10 @@ fn main() { .run(); } -fn setup(mut commands: Commands, asset_server: Res) { +fn setup( + mut commands: Commands, + asset_server: Res, +) { commands.spawn(LdtkWorldBundle { ldtk_handle: asset_server.load("shocked-miguel.ldtk"), ..Default::default() diff --git a/src/menu.rs b/src/menu.rs new file mode 100644 index 0000000..45ad637 --- /dev/null +++ b/src/menu.rs @@ -0,0 +1,54 @@ +use bevy::prelude::*; +use bevy::{ + color::Color, + ecs::system::Commands, + ui::{node_bundles::NodeBundle, JustifyContent, Style, UiRect, Val}, +}; +pub(crate) fn spawn_box(mut commands: Commands) { + let container = NodeBundle { + style: Style { + width: Val::Percent(100.0), + height: Val::Percent(100.0), + justify_content: JustifyContent::Center, + ..default() + }, + ..default() + }; + + let square = NodeBundle { + style: Style { + width: Val::Px(200.), + border: UiRect::all(Val::Px(2.)), + ..default() + }, + background_color: Color::srgb(0., 0.65, 0.65).into(), + ..default() + }; + + let parent = commands.spawn(container).id(); + let child = commands.spawn(square).id(); + + commands.entity(parent).push_children(&[child]); +} +pub(crate) fn spawn_text(mut commands: Commands) { + let text = "Hello world!"; + + commands.spawn( + TextBundle::from_section( + text, + TextStyle { + font_size: 100.0, + color: Color::WHITE, + ..default() + }, + ) // Set the alignment of the Text + .with_text_justify(JustifyText::Center) + // Set the style of the TextBundle itself. + .with_style(Style { + position_type: PositionType::Absolute, + bottom: Val::Px(5.0), + right: Val::Px(5.0), + ..default() + }), + ); +} diff --git a/src/player.rs b/src/player.rs index 78a22be..4b4d8c4 100644 --- a/src/player.rs +++ b/src/player.rs @@ -6,13 +6,14 @@ use crate::{ animations::{AnimationIndices, AnimationTimer}, colliders::ColliderBundle, ground_detection::GroundDetection, + state::GameState, }; pub struct PlayerPlugin; impl Plugin for PlayerPlugin { fn build(&self, app: &mut App) { - app.add_systems(Update, player_movement) + app.add_systems(Update, player_movement.run_if(in_state(GameState::InGame))) .register_ldtk_entity::("Player"); } } diff --git a/src/state.rs b/src/state.rs new file mode 100644 index 0000000..e803c40 --- /dev/null +++ b/src/state.rs @@ -0,0 +1,20 @@ +use bevy::{ + ecs::system::ResMut, + state::state::{NextState, States}, +}; + +#[derive(Debug, Clone, Eq, PartialEq, Hash, Default, States)] +pub(crate) enum GameState { + #[default] + MainMenu, + InGame, + GamePaused, +} + +fn start_game(mut next_state: ResMut>) { + next_state.set(GameState::InGame); +} + +fn pause_game(mut next_state: ResMut>) { + next_state.set(GameState::GamePaused); +}