bevyjam/src/main.rs
2022-08-28 00:10:41 +02:00

155 lines
3.9 KiB
Rust

#![allow(clippy::too_many_arguments)]
#[cfg(not(target_arch = "wasm32"))]
mod audio;
#[cfg(not(target_arch = "wasm32"))]
mod editor;
mod filters;
mod game;
mod levels;
mod menu;
mod particle_effect;
use bevy::{
asset::{Asset, HandleId, LoadState},
prelude::*,
window::{WindowMode, WindowResizeConstraints},
};
use bevy_common_assets::json::JsonAssetPlugin;
use bevy_rapier2d::prelude::*;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
enum AppState {
Loading,
Menu,
Game,
Win,
Editor,
}
struct UseEditor(bool);
struct LoadingAssets(Vec<HandleId>);
impl LoadingAssets {
fn add<T: Asset>(&mut self, handle: Handle<T>) -> Handle<T> {
self.0.push(handle.id);
handle
}
}
fn main() {
let (audio_event_sender, audio_event_receiver) =
crossbeam_channel::bounded::<game::AudioMsg>(512);
#[cfg(not(target_arch = "wasm32"))]
std::thread::spawn(move || audio::setup(audio_event_receiver));
#[cfg(not(target_arch = "wasm32"))]
let (first_level, use_editor) = {
let mut args = std::env::args().skip(1);
(
game::LevelId(args.next().map_or(0, |s| s.parse().unwrap_or(0))),
args.next().map_or(false, |s| s == "e"),
)
};
#[cfg(target_arch = "wasm32")]
let (first_level, use_editor) = (game::LevelId(0), false);
let mut app = App::new();
app.insert_resource(Msaa { samples: 4 })
.insert_resource(WindowDescriptor {
width: 640.0,
height: 480.0,
resize_constraints: WindowResizeConstraints {
min_width: 256.,
min_height: 256.,
max_width: f32::INFINITY,
max_height: f32::INFINITY,
},
resizable: true,
title: "Lux synthesĕ".into(),
..Default::default()
})
.insert_resource(audio_event_sender)
.insert_resource(UseEditor(use_editor))
.add_state(AppState::Loading)
.insert_resource(game::FirstLevel(first_level))
.insert_resource(ClearColor(Color::BLACK))
.add_plugins(DefaultPlugins)
//.add_plugin(RapierDebugRenderPlugin::default())
//.add_plugin(bevy_inspector_egui::WorldInspectorPlugin::new())
.add_plugin(JsonAssetPlugin::<levels::StoredLevels>::new(&[
"levels.json",
]));
if !use_editor {
app.add_plugin(RapierPhysicsPlugin::<NoUserData>::pixels_per_meter(64.0))
.add_plugin(menu::MenuPlugin)
.add_plugin(game::GamePlugin)
.add_plugin(particle_effect::ParticleEffectPlugin);
}
#[cfg(not(target_arch = "wasm32"))]
if use_editor {
app.add_plugin(editor::EditorPlugin);
}
app.add_system(keyboard_util_system)
.add_startup_system(setup)
.add_system_set(SystemSet::on_update(AppState::Loading).with_system(loading_system))
.run();
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
let mut assets = LoadingAssets(Vec::new());
commands.insert_resource(
assets.add(asset_server.load::<levels::StoredLevels, _>("game.levels.json")),
);
commands.insert_resource(assets.add(asset_server.load::<Font, _>("UacariLegacy-Thin.ttf")));
commands.insert_resource([
assets.add(asset_server.load::<Image, _>("bevy.png")),
assets.add(asset_server.load("melty.png")),
]);
commands.insert_resource(assets);
commands.spawn_bundle(Camera2dBundle::default());
commands.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 0.6,
});
}
fn loading_system(
asset_server: Res<AssetServer>,
use_editor: Res<UseEditor>,
assets: Res<LoadingAssets>,
mut app_state: ResMut<State<AppState>>,
) {
if asset_server.get_group_load_state(assets.0.iter().copied()) == LoadState::Loaded {
app_state
.replace(if use_editor.0 {
AppState::Editor
} else {
AppState::Menu
})
.ok();
}
}
fn keyboard_util_system(keyboard_input: Res<Input<KeyCode>>, mut windows: ResMut<Windows>) {
#[cfg(not(target_arch = "wasm32"))]
{
if keyboard_input.just_released(KeyCode::Escape) {
std::process::exit(0);
}
if keyboard_input.just_pressed(KeyCode::F11) {
if let Some(window) = windows.get_primary_mut() {
window.set_mode(match window.mode() {
WindowMode::Windowed => WindowMode::Fullscreen,
_ => WindowMode::Windowed,
});
}
}
}
}