Very basic dialog works now

Still has kinks but it's a start
main
Elijah Voigt 4 months ago
parent f4ad2cd955
commit 6c12943cd4

@ -1,5 +1,6 @@
#![allow(clippy::type_complexity)] #![allow(clippy::type_complexity)]
use bevy::color::palettes::css::{DARK_GREY, DARK_ORANGE, GREY, ORANGE};
use games::*; use games::*;
fn main() { fn main() {
@ -15,9 +16,11 @@ fn main() {
( (
dialog_engine.run_if(input_just_pressed(KeyCode::KeyN)), dialog_engine.run_if(input_just_pressed(KeyCode::KeyN)),
mouse_wheel_scroll.run_if(on_event::<MouseWheel>), mouse_wheel_scroll.run_if(on_event::<MouseWheel>),
auto_scroll.run_if(any_component_added::<DialogOption>) auto_scroll.run_if(any_component_added::<DialogOption>),
), ),
) )
.add_observer(add_dialog_option)
.add_observer(add_dialog_line)
.run(); .run();
} }
@ -132,6 +135,37 @@ fn position_camera(mut query: Query<&mut Transform, (With<Camera>, With<Camera3d
}) })
} }
/// Allows user to scroll (with mouse whell) through old dialog
fn mouse_wheel_scroll(
mut events: EventReader<MouseWheel>,
mut scroll_position: Query<&mut ScrollPosition>,
) {
events.read().for_each(|MouseWheel { unit, y, .. }| {
let offset_y = match unit {
MouseScrollUnit::Line => 10.0 * y,
MouseScrollUnit::Pixel => 1.0 * y,
};
scroll_position
.iter_mut()
.for_each(|mut pos| pos.offset_y += offset_y);
});
}
/// Automatically scrolls dialog when a new batch of options are added
fn auto_scroll(
added: Query<Entity, Added<DialogOption>>,
mut scroll_positions: Query<&mut ScrollPosition>,
) {
debug_assert!(
!added.is_empty(),
"Should only scroll when dialog options are added"
);
scroll_positions.iter_mut().for_each(|mut sp| {
sp.offset_y = f32::MAX;
});
}
/// A possible line of dialog the user can choose /// A possible line of dialog the user can choose
#[derive(Component)] #[derive(Component)]
struct DialogOption; struct DialogOption;
@ -159,9 +193,7 @@ fn dialog_engine(
commands.entity(*dialog_box).with_children(|parent| { commands.entity(*dialog_box).with_children(|parent| {
if let Some(options) = dialog.get(*idx) { if let Some(options) = dialog.get(*idx) {
options.iter().for_each(|option| { options.iter().for_each(|option| {
parent parent.spawn((Text::new(*option), DialogOption));
.spawn((Text::new(*option), Button, DialogOption))
.observe(choose_dialog);
}); });
} }
}); });
@ -170,42 +202,68 @@ fn dialog_engine(
} }
/// When a dialog option is chosen (clicked on) we do the following: /// When a dialog option is chosen (clicked on) we do the following:
/// 1. Remove the Button and DialogOption components from that entity fn choose_dialog_option(
/// 2. Insert the DialogLine component to that entity trigger: Trigger<Pointer<Click>>,
/// 3. Remove all other DialogOptions from the DialogBox mut commands: Commands,
fn choose_dialog(trigger: Trigger<Pointer<Click>>, mut commands: Commands) { texts: Query<&Text>,
options: Query<Entity, With<DialogOption>>,
dialog_box: Single<Entity, With<DialogBox>>,
) {
info!("Choosing dialog {:?}", trigger.target()); info!("Choosing dialog {:?}", trigger.target());
commands
.entity(trigger.target()) info!("Despawning dialog options");
.remove::<Button>() options.iter().for_each(|e| {
.remove::<DialogOption>() commands.entity(e).despawn();
.insert(DialogLine); });
info!("Inserting dialog line");
if let Ok(t) = texts.get(trigger.target()) {
commands.entity(*dialog_box).with_children(|parent| {
parent.spawn((t.clone(), DialogLine));
});
}
} }
/// Allows user to scroll (with mouse whell) through old dialog fn hover_dialog_option_over(
fn mouse_wheel_scroll( trigger: Trigger<Pointer<Over>>,
mut events: EventReader<MouseWheel>, mut query: Query<(&mut TextColor, &mut BackgroundColor)>,
mut scroll_position: Query<&mut ScrollPosition>,
) { ) {
events.read().for_each(|MouseWheel { unit, y, .. }| { if let Ok((mut tc, mut bg)) = query.get_mut(trigger.target()) {
let offset_y = match unit { *tc = TextColor(DARK_ORANGE.into());
MouseScrollUnit::Line => 10.0 * y, bg.0.set_alpha(0.9);
MouseScrollUnit::Pixel => 1.0 * y, }
};
scroll_position
.iter_mut()
.for_each(|mut pos| pos.offset_y += offset_y);
});
} }
/// Automatically scrolls dialog when a new batch of options are added fn hover_dialog_option_out(
fn auto_scroll( trigger: Trigger<Pointer<Out>>,
added: Query<Entity, Added<DialogOption>>, mut query: Query<(&mut TextColor, &mut BackgroundColor)>,
mut scroll_positions: Query<&mut ScrollPosition>,
) { ) {
debug_assert!(!added.is_empty(), "Should only scroll when dialog options are added"); if let Ok((mut tc, mut bg)) = query.get_mut(trigger.target()) {
*tc = TextColor(ORANGE.into());
bg.0.set_alpha(0.0);
}
}
scroll_positions.iter_mut().for_each(|mut sp| { /// When a (Text) dialog option is added:
sp.offset_y = f32::MAX; /// 1. Add the Button component
}); /// 2. Change the color to Orange
/// 3. Add observers for click (select) and hover (change color)
fn add_dialog_option(trigger: Trigger<OnAdd, DialogOption>, mut commands: Commands) {
commands
.entity(trigger.target())
.insert(Button)
.insert(Node {
width: Val::Percent(100.0),
..default()
})
.insert(TextLayout::new_with_justify(JustifyText::Center))
.insert(TextColor(ORANGE.into()))
.insert(BackgroundColor(BLACK.with_alpha(0.0).into()))
.observe(choose_dialog_option)
.observe(hover_dialog_option_over)
.observe(hover_dialog_option_out);
}
fn add_dialog_line(trigger: Trigger<OnAdd, DialogLine>, mut commands: Commands) {
debug!("Adding dialog line");
} }

Loading…
Cancel
Save