Skip to content

Commit

Permalink
feat(controller): add simple blocking HUD
Browse files Browse the repository at this point in the history
Added initial HUD without actions DigitalExtinction#22
Added node for minimap DigitalExtinction#100
  • Loading branch information
Polostor committed Jan 30, 2023
1 parent df501a5 commit 1ff75f7
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 4 deletions.
47 changes: 46 additions & 1 deletion crates/controller/src/hud.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
use bevy::prelude::*;
use de_core::{screengeom::ScreenRect, stages::GameStage, state::AppState};
use iyes_loopless::prelude::*;

use de_core::{
screengeom::ScreenRect,
stages::GameStage,
state::{AppState, GameState},
};

use crate::hud_components;

const SELECTION_BOX_COLOR: Color = Color::rgba(0., 0.5, 0.8, 0.2);

pub(crate) struct HudPlugin;

impl Plugin for HudPlugin {
fn build(&self, app: &mut App) {
app.add_event::<UpdateSelectionBoxEvent>()
.add_enter_system(GameState::Playing, spawn_hud)
.add_system_set_to_stage(
GameStage::PostUpdate,
SystemSet::new().with_system(process_events.run_in_state(AppState::InGame)),
Expand Down Expand Up @@ -79,3 +87,40 @@ fn process_events(
}
}
}

pub fn spawn_hud(mut commands: Commands) {
hud_components::spawn_details(&mut commands);
hud_components::spawn_action_bar(&mut commands);
hud_components::spawn_map(&mut commands);
}

#[derive(Component)]
pub struct HudTopVisibleNode;

#[derive(SystemParam)]
pub(crate) struct HudNodes<'w, 's> {
hud: Query<'w, 's, (&'static GlobalTransform, &'static Node), With<HudTopVisibleNode>>,
windows: Res<'w, Windows>,
}

impl<'w, 's> HudNodes<'w, 's> {
pub(crate) fn contains_point(
&mut self,
point: &Vec2,
) -> bool {
let window = self.windows.get_primary().unwrap();
let win_size = Vec2::new(window.width(), window.height());
self.hud.iter().any(|(box_transform, node)| {
// WARNING: This is because mouse y starts on bottom, GlobalTransform on top
let mouse_position = Vec2::new(point.x, win_size.y - point.y);

let box_size = node.size();
let box_transform: Vec3 = box_transform.translation();
// WARNING: This is because GlobalTransform is centered, width/2 to left and to right, same on vertical
let box_position = box_transform.xy() - box_size / 2.;

mouse_position.cmpge(box_position).all()
&& mouse_position.cmple(box_position + box_size).all()
})
}
}
76 changes: 76 additions & 0 deletions crates/controller/src/hud_components.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use bevy::prelude::*;

use crate::hud::HudTopVisibleNode;

const HUD_COLOR: Color = Color::BLACK;

pub(crate) fn spawn_details(commands: &mut Commands) {
commands.spawn((
NodeBundle {
style: Style {
size: Size {
width: Val::Percent(20.),
height: Val::Percent(30.),
},
align_items: AlignItems::Stretch,
flex_direction: FlexDirection::Column,
position_type: PositionType::Absolute,
position: UiRect::new(
Val::Percent(0.), Val::Percent(20.),
Val::Percent(70.), Val::Percent(100.),
),
..default()
},
background_color: HUD_COLOR.into(),
..default()
},
HudTopVisibleNode
));
}

pub(crate) fn spawn_action_bar(commands: &mut Commands) {
commands.spawn((
NodeBundle {
style: Style {
size: Size {
width: Val::Percent(60.),
height: Val::Percent(15.),
},
flex_direction: FlexDirection::Row,
position_type: PositionType::Absolute,
position: UiRect::new(
Val::Percent(20.), Val::Percent(80.),
Val::Percent(85.), Val::Percent(100.),
),
..default()
},
background_color: HUD_COLOR.into(),
..default()
},
HudTopVisibleNode,
));
}

pub(crate) fn spawn_map(commands: &mut Commands) {
commands.spawn((
NodeBundle {
style: Style {
size: Size {
width: Val::Percent(20.),
height: Val::Percent(30.),
},
align_items: AlignItems::Stretch,
flex_direction: FlexDirection::Column,
position_type: PositionType::Absolute,
position: UiRect::new(
Val::Percent(80.), Val::Percent(100.),
Val::Percent(70.), Val::Percent(100.),
),
..default()
},
background_color: HUD_COLOR.into(),
..default()
},
HudTopVisibleNode
));
}
1 change: 1 addition & 0 deletions crates/controller/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ mod draft;
mod dragselect;
mod frustum;
mod hud;
mod hud_components;
mod keyboard;
mod menu;
mod mouse;
Expand Down
20 changes: 17 additions & 3 deletions crates/controller/src/mouse.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
use ahash::AHashMap;
use bevy::{
input::{mouse::MouseButtonInput, ButtonState},
ecs::system::SystemParam,
input::{ButtonState, mouse::MouseButtonInput},
prelude::*,
};
use de_core::{screengeom::ScreenRect, stages::GameStage, state::GameState};
use glam::Vec3Swizzles;
use iyes_loopless::prelude::*;

use de_core::{
screengeom::ScreenRect,
stages::GameStage,
state::GameState,
};

use crate::hud::HudNodes;

const DRAGGING_THRESHOLD: f32 = 0.02;
const DOUBLE_CLICK_TIME: f64 = 0.5;

Expand Down Expand Up @@ -212,11 +221,16 @@ enum DragResolution {
Rect(ScreenRect),
}

fn update_position(windows: Res<Windows>, mut mouse: ResMut<MousePosition>) {
fn update_position(
windows: Res<Windows>,
mut hud: HudNodes,
mut mouse: ResMut<MousePosition>,
) {
let window = windows.get_primary().unwrap();
mouse.set_position(
window
.cursor_position()
.filter(|position| !hud.contains_point(position))
.map(|position| position / Vec2::new(window.width(), window.height()))
.map(|normalised_position| normalised_position.clamp(Vec2::ZERO, Vec2::ONE)),
);
Expand Down

0 comments on commit 1ff75f7

Please sign in to comment.