use bevy::math::f32::Vec3; use bevy::prelude::*; use bevy::reflect::TypePath; use bevy_common_assets::xml::XmlAssetPlugin; fn main() { App::new() .add_plugins((DefaultPlugins, XmlAssetPlugin::::new(&["level.xml"]))) .init_state::() .add_systems(Startup, setup) .add_systems(Update, spawn_level.run_if(in_state(AppState::Loading))) .run(); } fn setup(mut commands: Commands, asset_server: Res) { let level = LevelHandle(asset_server.load("trees.level.xml")); commands.insert_resource(level); let tree = ImageHandle(asset_server.load("tree.png")); commands.insert_resource(tree); commands.spawn((Camera2d, Msaa::Off)); } fn spawn_level( mut commands: Commands, level: Res, tree: Res, mut levels: ResMut>, mut state: ResMut>, ) { if let Some(level) = levels.remove(level.0.id()) { for position in level.positions { commands.spawn(( Sprite::from_image(tree.0.clone()), Transform::from_translation(Vec3::new(position.x, position.y, position.z)), )); } state.set(AppState::Level); } } #[derive(serde::Deserialize, Asset, TypePath)] struct Level { #[serde(rename = "Position")] positions: Vec, } #[derive(serde::Deserialize)] struct Position { #[serde(rename = "@x")] x: f32, #[serde(rename = "@y")] y: f32, #[serde(rename = "@z")] z: f32, } #[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Hash, States)] enum AppState { #[default] Loading, Level, } #[derive(Resource)] struct ImageHandle(Handle); #[derive(Resource)] struct LevelHandle(Handle);