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)]
use bevy::color::palettes::css::{DARK_GREY, DARK_ORANGE, GREY, ORANGE};
use games::*;
fn main() {
@ -15,9 +16,11 @@ fn main() {
(
dialog_engine.run_if(input_just_pressed(KeyCode::KeyN)),
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();
}
@ -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
#[derive(Component)]
struct DialogOption;
@ -159,9 +193,7 @@ fn dialog_engine(
commands.entity(*dialog_box).with_children(|parent| {
if let Some(options) = dialog.get(*idx) {
options.iter().for_each(|option| {
parent
.spawn((Text::new(*option), Button, DialogOption))
.observe(choose_dialog);
parent.spawn((Text::new(*option), DialogOption));
});
}
});
@ -170,42 +202,68 @@ fn dialog_engine(
}
/// When a dialog option is chosen (clicked on) we do the following:
/// 1. Remove the Button and DialogOption components from that entity
/// 2. Insert the DialogLine component to that entity
/// 3. Remove all other DialogOptions from the DialogBox
fn choose_dialog(trigger: Trigger<Pointer<Click>>, mut commands: Commands) {
fn choose_dialog_option(
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());
commands
.entity(trigger.target())
.remove::<Button>()
.remove::<DialogOption>()
.insert(DialogLine);
info!("Despawning dialog options");
options.iter().for_each(|e| {
commands.entity(e).despawn();
});
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 mouse_wheel_scroll(
mut events: EventReader<MouseWheel>,
mut scroll_position: Query<&mut ScrollPosition>,
fn hover_dialog_option_over(
trigger: Trigger<Pointer<Over>>,
mut query: Query<(&mut TextColor, &mut BackgroundColor)>,
) {
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);
});
if let Ok((mut tc, mut bg)) = query.get_mut(trigger.target()) {
*tc = TextColor(DARK_ORANGE.into());
bg.0.set_alpha(0.9);
}
}
/// 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>,
fn hover_dialog_option_out(
trigger: Trigger<Pointer<Out>>,
mut query: Query<(&mut TextColor, &mut BackgroundColor)>,
) {
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| {
sp.offset_y = f32::MAX;
});
/// When a (Text) dialog option is added:
/// 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