mirror of
https://github.com/eliasstepanik/voxel-simulation.git
synced 2026-01-25 20:48:47 +00:00
Add JSON-configurable options menu
This commit is contained in:
parent
9e2d294d69
commit
d0c4abd38b
@ -12,6 +12,7 @@ build = "build.rs"
|
|||||||
bevy = { version = "0.16.1", features = ["jpeg", "trace_tracy", "trace_tracy_memory", "serialize"] }
|
bevy = { version = "0.16.1", features = ["jpeg", "trace_tracy", "trace_tracy_memory", "serialize"] }
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
toml = "0.8"
|
toml = "0.8"
|
||||||
big_space = { git = "https://github.com/aevyrie/big_space.git", rev = "5345af11d4ce138bacf5a9a3ab53d1c3b3b103c7" }
|
big_space = { git = "https://github.com/aevyrie/big_space.git", rev = "5345af11d4ce138bacf5a9a3ab53d1c3b3b103c7" }
|
||||||
noise = "0.9.0"
|
noise = "0.9.0"
|
||||||
|
|||||||
8
client/assets/options_menu.json
Normal file
8
client/assets/options_menu.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"items": [
|
||||||
|
{ "label": "Toggle Wireframe", "action": "toggle_wireframe" },
|
||||||
|
{ "label": "Toggle Grid", "action": "toggle_grid" },
|
||||||
|
{ "label": "Toggle Edit Mode", "action": "toggle_edit_mode" },
|
||||||
|
{ "label": "Exit", "action": "exit" }
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -1,2 +1,4 @@
|
|||||||
pub mod systems;
|
pub mod systems;
|
||||||
pub mod ui_plugin;
|
pub mod ui_plugin;
|
||||||
|
|
||||||
|
pub mod options;
|
||||||
|
|||||||
118
client/src/plugins/ui/options/mod.rs
Normal file
118
client/src/plugins/ui/options/mod.rs
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
use crate::plugins::environment::systems::voxels::structure::SparseVoxelOctree;
|
||||||
|
use crate::plugins::input::systems::voxels::VoxelEditMode;
|
||||||
|
use bevy::prelude::*;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Deserialize, Resource)]
|
||||||
|
pub struct OptionsMenuConfig {
|
||||||
|
pub items: Vec<OptionItem>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Clone)]
|
||||||
|
pub struct OptionItem {
|
||||||
|
pub label: String,
|
||||||
|
pub action: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
struct MenuButton {
|
||||||
|
action: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct OptionsMenuPlugin;
|
||||||
|
impl Plugin for OptionsMenuPlugin {
|
||||||
|
fn build(&self, app: &mut App) {
|
||||||
|
let config: OptionsMenuConfig = load_config();
|
||||||
|
app.insert_resource(config);
|
||||||
|
app.add_systems(Startup, setup_menu);
|
||||||
|
app.add_systems(Update, handle_buttons);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_config() -> OptionsMenuConfig {
|
||||||
|
let path = "client/assets/options_menu.json";
|
||||||
|
let data = std::fs::read_to_string(path).expect("failed to read options_menu.json");
|
||||||
|
serde_json::from_str(&data).expect("invalid options_menu.json")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup_menu(
|
||||||
|
mut commands: Commands,
|
||||||
|
config: Res<OptionsMenuConfig>,
|
||||||
|
asset_server: Res<AssetServer>,
|
||||||
|
) {
|
||||||
|
commands
|
||||||
|
.spawn(NodeBundle {
|
||||||
|
style: Style {
|
||||||
|
position_type: PositionType::Absolute,
|
||||||
|
left: Val::Px(10.0),
|
||||||
|
top: Val::Px(10.0),
|
||||||
|
flex_direction: FlexDirection::Column,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
background_color: Color::rgba(0.1, 0.1, 0.1, 0.5).into(),
|
||||||
|
..default()
|
||||||
|
})
|
||||||
|
.with_children(|parent| {
|
||||||
|
for item in config.items.iter() {
|
||||||
|
parent
|
||||||
|
.spawn((
|
||||||
|
ButtonBundle {
|
||||||
|
style: Style {
|
||||||
|
margin: UiRect::all(Val::Px(2.0)),
|
||||||
|
padding: UiRect::all(Val::Px(4.0)),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
background_color: Color::GRAY.into(),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
MenuButton {
|
||||||
|
action: item.action.clone(),
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.with_children(|p| {
|
||||||
|
p.spawn(TextBundle::from_section(
|
||||||
|
item.label.clone(),
|
||||||
|
TextStyle {
|
||||||
|
font: asset_server.load("fonts/minecraft_font.ttf"),
|
||||||
|
font_size: 16.0,
|
||||||
|
color: Color::WHITE,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_buttons(
|
||||||
|
mut interactions: Query<(&Interaction, &MenuButton), (Changed<Interaction>, With<Button>)>,
|
||||||
|
mut octrees: Query<&mut SparseVoxelOctree>,
|
||||||
|
mut exit: EventWriter<AppExit>,
|
||||||
|
mut edit_mode: ResMut<VoxelEditMode>,
|
||||||
|
) {
|
||||||
|
for (interaction, button) in &mut interactions {
|
||||||
|
if *interaction == Interaction::Pressed {
|
||||||
|
match button.action.as_str() {
|
||||||
|
"toggle_wireframe" => {
|
||||||
|
for mut o in &mut octrees {
|
||||||
|
o.show_wireframe = !o.show_wireframe;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"toggle_grid" => {
|
||||||
|
for mut o in &mut octrees {
|
||||||
|
o.show_world_grid = !o.show_world_grid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"toggle_edit_mode" => {
|
||||||
|
*edit_mode = match *edit_mode {
|
||||||
|
VoxelEditMode::Single => VoxelEditMode::Sphere,
|
||||||
|
VoxelEditMode::Sphere => VoxelEditMode::Single,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
"exit" => {
|
||||||
|
exit.send(AppExit);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
use crate::plugins::ui::options::OptionsMenuPlugin;
|
||||||
use crate::plugins::ui::systems::ui_system::*;
|
use crate::plugins::ui::systems::ui_system::*;
|
||||||
use bevy::app::{App, FixedUpdate, Plugin, PreUpdate, Startup};
|
use bevy::app::{App, FixedUpdate, Plugin, PreUpdate, Startup};
|
||||||
|
|
||||||
@ -6,5 +7,6 @@ impl Plugin for UiPlugin {
|
|||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_systems(Startup, setup);
|
app.add_systems(Startup, setup);
|
||||||
app.add_systems(FixedUpdate, update);
|
app.add_systems(FixedUpdate, update);
|
||||||
|
app.add_plugins(OptionsMenuPlugin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user