You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
martian-chess/src/main.rs

162 lines
4.3 KiB
Rust

mod audio;
mod credits;
mod debug;
mod display2d;
mod display3d;
mod game;
mod loading;
mod menu;
mod prelude;
use std::time::Duration;
use bevy::{
asset::{ChangeWatcher, HandleId},
input::{keyboard::KeyboardInput, ButtonState},
};
use crate::prelude::*;
fn main() {
if std::env::var_os("CARGO_MANIFEST_DIR").is_none() {
std::env::set_var("CARGO_MANIFEST_DIR", ".");
}
App::new()
.add_state::<GameState>()
.add_systems(Update, state.run_if(resource_changed::<State<GameState>>()))
.add_systems(Update, loading.run_if(in_state(GameState::Loading)))
.add_systems(
Update,
toggle_display_mode.run_if(on_event::<KeyboardInput>()),
)
.add_plugins((
DefaultPlugins
.set(ImagePlugin::default_nearest())
.set(WindowPlugin {
primary_window: Some(Window {
title: "Martian Chess".into(),
resolution: (640., 480.).into(),
..default()
}),
..default()
})
.set(AssetPlugin {
watch_for_changes: ChangeWatcher::with_delay(Duration::from_millis(200)),
..default()
}),
audio::AudioPlugin,
credits::CreditsPlugin,
debug::DebugPlugin,
display2d::Display2dPlugin,
display3d::Display3dPlugin,
game::GamePlugin,
loading::LoadingPlugin,
menu::MenuPlugin,
))
.run();
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default, States, Component)]
pub enum GameState {
#[default]
Loading,
Menu,
Credits,
Display2d,
Display3d,
}
fn loading(
server: Res<AssetServer>,
sprites: Res<Assets<Image>>,
gltfs: Res<Assets<Gltf>>,
mut next_state: ResMut<NextState<GameState>>,
) {
let s_ids = sprites
.ids()
.filter(|&id| matches!(id, HandleId::AssetPathId(_)))
.collect::<Vec<HandleId>>();
let g_ids = gltfs
.ids()
.filter(|&id| matches!(id, HandleId::AssetPathId(_)))
.collect::<Vec<HandleId>>();
debug!(
"Sprite len: {:?} | GLTF len: {:?}",
s_ids.len(),
g_ids.len()
);
if s_ids.len() > 0 && g_ids.len() > 0 {
let s_ready = s_ids
.iter()
.all(|&id| server.get_load_state(id) == LoadState::Loaded);
let g_ready = g_ids
.iter()
.all(|&id| server.get_load_state(id) == LoadState::Loaded);
if s_ready && g_ready {
next_state.set(GameState::Menu)
}
}
}
/// System for printing the current state
///
/// Only runs when state is modified.
fn state(state: Res<State<GameState>>) {
info!("State is {:?}", *state);
}
fn toggle_display_mode(
mut events: EventReader<KeyboardInput>,
state: Res<State<GameState>>,
mut next_state: ResMut<NextState<GameState>>,
) {
events
.iter()
.filter(
|KeyboardInput {
key_code, state, ..
}| (*key_code, *state) == (Some(KeyCode::Space), ButtonState::Pressed),
)
.for_each(|_| match state.get() {
GameState::Display2d => next_state.set(GameState::Display3d),
GameState::Display3d => next_state.set(GameState::Display2d),
_ => (),
})
}
fn activate<Marker: Component>(
mut cameras: Query<&mut Camera, With<Marker>>,
mut entities: Query<&mut Visibility, With<Marker>>,
) {
cameras.iter_mut().for_each(|mut camera| {
camera.is_active = true;
});
entities.iter_mut().for_each(|mut visibility| {
*visibility = Visibility::Visible;
});
}
fn deactivate<Marker: Component>(
mut cameras: Query<&mut Camera, With<Marker>>,
mut entities: Query<&mut Visibility, With<Marker>>,
) {
cameras.iter_mut().for_each(|mut camera| {
camera.is_active = false;
});
entities.iter_mut().for_each(|mut visibility| {
*visibility = Visibility::Hidden;
});
}
pub(crate) fn any_component_changed<C: Component>(q: Query<Entity, Changed<C>>) -> bool {
!q.is_empty()
}
pub(crate) fn any_component_added<C: Component>(q: Query<Entity, Added<C>>) -> bool {
!q.is_empty()
}