use bevy::audio::{AudioPlugin, SpatialScale}; use bevy::diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin}; use bevy::prelude::{default, *}; use bevy::window::{PrimaryWindow, WindowMode}; mod assets; mod camera; mod main_menu; mod movement; mod player; mod statue; #[derive(States, Default, Debug, Clone, PartialEq, Eq, Hash)] pub enum Game { #[default] Running, Paused, } #[derive(States, Default, Debug, Clone, PartialEq, Eq, Hash)] pub enum View { // #[default] // LoadingScreen, #[default] MainMenu, InGame, } #[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)] struct MainMenuSet; #[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)] struct InGameSet; fn main() { let mut app = App::new(); app.init_resource::(); app.insert_state(View::default()); app.insert_state(Game::default()); app.add_plugins(( DefaultPlugins .set(WindowPlugin { primary_window: Some(Window { title: "Kodo Tag".into(), mode: bevy::window::WindowMode::BorderlessFullscreen, // resolution: (640. * 2., 360. * 2.).into(), ..default() }), ..default() }) .set(AudioPlugin { default_spatial_scale: SpatialScale::new_2d(1.), global_volume: GlobalVolume::new(1.), ..default() }) .set(ImagePlugin::default_nearest()), FrameTimeDiagnosticsPlugin, )) .add_systems(OnEnter(View::MainMenu), main_menu::startup) .add_systems(OnExit(View::MainMenu), main_menu::exit) .add_systems(OnEnter(View::InGame), (player::startup, statue::startup)) .add_systems(OnExit(View::InGame), (player::exit, statue::exit)) .add_systems(Startup, (startup, assets::startup, camera::startup)) .add_systems( Update, ( update, ( player::sprite_select, player::controls, movement::update_velocity_by_heading, movement::resolve_velocity.after(movement::update_velocity_by_heading), movement::ysort.after(movement::update_velocity_by_heading), camera::update .after(player::controls) .after(movement::resolve_velocity), ) .in_set(InGameSet) .run_if(in_state(View::InGame)), (main_menu::update) .in_set(MainMenuSet) .run_if(in_state(View::MainMenu)), ), ) .insert_resource(ClearColor(Color::rgb(0.3, 0.1, 0.5))) .insert_resource(AmbientLight { color: Color::rgb(1., 1., 1.), brightness: 1., }); app.run() } fn toggle_fullscreen(mut window: Mut) { if window.mode == WindowMode::Windowed { window.mode = WindowMode::BorderlessFullscreen } else { window.mode = WindowMode::Windowed } } #[derive(Component)] struct FpsText; fn startup(mut commands: Commands, assets: Res) { commands.spawn(( FpsText, TextBundle::from_sections([ TextSection::new( "FPS: ", TextStyle { font: assets.fonts.iosevkalytemin.clone(), font_size: 60., ..default() }, ), TextSection::from_style(TextStyle { font: assets.fonts.iosevkalytemin.clone(), font_size: 60., color: Color::Hsla { hue: 0.5, saturation: 0.5, lightness: 0.5, alpha: 0.5, }, }), ]) .with_style(Style { position_type: PositionType::Absolute, bottom: Val::Px(5.0), right: Val::Px(5.0), ..default() }), )); } fn update( diagnostics: Res, mut query: Query<&mut Text, With>, keyboard: Res>, mut window: Query<&mut Window, With>, ) { if keyboard.just_pressed(KeyCode::Enter) && (keyboard.pressed(KeyCode::AltLeft) || keyboard.pressed(KeyCode::AltRight)) { if let Ok(window) = window.get_single_mut() { toggle_fullscreen(window) } } for mut text in &mut query { if let Some(fps) = diagnostics.get(&FrameTimeDiagnosticsPlugin::FPS) { if let Some(value) = fps.smoothed() { text.sections[1].value = format!("{value:.2}"); } } } }