use bevy::prelude::*; use bevy::reflect::TypePath; use bevy_common_assets::json::JsonAssetPlugin; use bevy_common_assets::ron::RonAssetPlugin; fn main() { App::new() // You can add loaders for different asset types, but also multiple loaders for the same asset type // The important thing is: they all need distinct extensions! .add_plugins(( DefaultPlugins, RonAssetPlugin::::new(&["level.ron"]), JsonAssetPlugin::::new(&["level.json"]), )) .init_state::() .add_systems(Startup, setup) .add_systems(Update, check_loading.run_if(in_state(AppState::Loading))) .add_systems(OnEnter(AppState::Level), spawn_level) .run(); } #[derive(serde::Deserialize, Asset, TypePath)] struct Level { positions: Vec<[f32; 3]>, } fn setup(mut commands: Commands, asset_server: Res) { let json_trees: Handle = asset_server.load("trees.level.json"); let ron_trees: Handle = asset_server.load("trees.level.ron"); commands.insert_resource(Levels(vec![json_trees, ron_trees])); let tree = ImageHandle(asset_server.load("tree.png")); commands.insert_resource(tree); commands.spawn((Camera2d, Msaa::Off)); } fn spawn_level( mut commands: Commands, levels: Res, tree: Res, mut level_assets: ResMut>, ) { for handle in levels.0.iter() { let level = level_assets.remove(handle).unwrap(); for position in level.positions { commands.spawn(( Sprite::from_image(tree.0.clone()), Transform::from_translation(position.into()), )); } } } fn check_loading( asset_server: Res, handles: Res, mut state: ResMut>, ) { for handle in &handles.0 { if asset_server .get_load_state(handle) .map(|state| !state.is_loaded()) .unwrap_or(true) { return; } } state.set(AppState::Level); } #[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Hash, States)] enum AppState { #[default] Loading, Level, } #[derive(Resource)] struct ImageHandle(Handle); #[derive(Resource)] struct Levels(Vec>);