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 #22
Added node for minimap #100
  • Loading branch information
Polostor committed Jan 31, 2023
1 parent df501a5 commit 78f5fae
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 3 deletions.
47 changes: 45 additions & 2 deletions 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 bevy::{ecs::system::SystemParam, prelude::*};
use de_core::{
screengeom::ScreenRect,
stages::GameStage,
state::{AppState, GameState},
};
use glam::Vec3Swizzles;
use iyes_loopless::prelude::*;

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,38 @@ 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);
}

/// Top-level non-transparent UI node. All such nodes are marked with this component and no descendants have it attached
#[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()
})
}
}
77 changes: 77 additions & 0 deletions crates/controller/src/hud_components.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
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.),
},
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.),
},
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.),
},
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
5 changes: 4 additions & 1 deletion crates/controller/src/mouse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use bevy::{
use de_core::{screengeom::ScreenRect, stages::GameStage, state::GameState};
use iyes_loopless::prelude::*;

use crate::hud::HudNodes;

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

Expand Down Expand Up @@ -212,11 +214,12 @@ 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 78f5fae

Please sign in to comment.