Skip to content

Commit

Permalink
Merge pull request #36 from thombruce/feat/indicators
Browse files Browse the repository at this point in the history
Indicators
  • Loading branch information
thombruce authored Oct 6, 2023
2 parents c80c059 + d190d27 commit 0349863
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Indicator system added to the HUD
- (Optional) pixelation shader for retro effect
- (Optional) chromatic aberration shader
- Source and license info to credit attributions

### Changed

- HUD module moved to new hud directory

## [0.0.10] - 2023-10-04

### Added
Expand Down
3 changes: 3 additions & 0 deletions assets/grey_arrowUpWhite.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
126 changes: 126 additions & 0 deletions src/hud/indicator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
use bevy::{math::Vec3Swizzles, prelude::*};

use crate::{ship::Ship, state::AppState};

pub struct IndicatorPlugin;
impl Plugin for IndicatorPlugin {
fn build(&self, app: &mut App) {
app.add_systems(OnExit(AppState::GameCreate), setup);
app.add_systems(Update, indicators_system.run_if(in_state(AppState::Active)));
}
}

#[derive(Component, Clone, Debug)]
pub struct Indicated {
pub color: Color,
}

#[derive(Component, Clone, Debug)]
struct Indicator {
entity: Entity,
}

#[derive(Component, Clone, Debug)]
struct Bounds {}

fn setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
entities_query: Query<(Entity, &Indicated)>,
) {
commands
.spawn((
NodeBundle {
style: Style {
position_type: PositionType::Absolute,
width: Val::Percent(100.0),
height: Val::Percent(100.0),
..default()
},
..default()
},
Name::new("Indicators"),
Bounds {},
))
.with_children(|parent| {
for (entity, indicated) in entities_query.iter() {
parent.spawn((
ImageBundle {
image: UiImage::new(asset_server.load("grey_arrowUpWhite.png")),
style: Style {
position_type: PositionType::Absolute,
width: Val::Px(15.0),
height: Val::Px(10.0),
..default()
},
// TODO: Set this value on the Indicator struct.
background_color: BackgroundColor(indicated.color),
..default()
},
Indicator { entity: entity },
));
}
});
}

fn indicators_system(
mut query: Query<(&mut Transform, &mut Style, &Indicator)>,
player_query: Query<&Transform, (With<Ship>, Without<Indicator>)>,
entity_query: Query<(&Transform, &ComputedVisibility), (With<Indicated>, Without<Indicator>)>,
bounds_query: Query<&Node, (With<Bounds>, Without<Indicator>)>,
) {
let player_transform = player_query.single();
let player_translation = player_transform.translation.xy();

for (mut indicator_transform, mut indicator_style, indicator) in &mut query {
if let Ok((entity_transform, entity_visibility)) = entity_query.get(indicator.entity) {
if entity_visibility.is_visible() {
indicator_style.display = Display::None;
continue;
}

indicator_style.display = Display::DEFAULT;

let entity_translation = entity_transform.translation.xy();

// get the vector from the entity to the player ship in 2D and normalize it.
let real_to_entity = entity_translation - player_translation;
let to_entity = real_to_entity.normalize();

// get the quaternion to rotate from the indicator pointing direction to the direction
// of the entity
let rotate_to_entity = Quat::from_rotation_arc_2d(to_entity, Vec2::Y);

// rotate the indicator towards the entity
indicator_transform.rotation = rotate_to_entity;

// get the extents of the bounding UI node (size of window)
let bounds = bounds_query.single().size();
let extents = Vec2::from(bounds / 2.0);

// reposition indicator relative to the direction of the entity
// we're using the non-normalized real_to_entity for this in order
// to get the actual size of the player-entity vector's x and y values
match real_to_entity.x > 0. {
true => {
indicator_style.right = Val::Px((extents.x - real_to_entity.x).max(0.));
indicator_style.left = Val::Auto;
}
false => {
indicator_style.left = Val::Px((extents.x + real_to_entity.x).max(0.));
indicator_style.right = Val::Auto;
}
}
match real_to_entity.y > 0. {
true => {
indicator_style.top = Val::Px((extents.y - real_to_entity.y).max(0.));
indicator_style.bottom = Val::Auto;
}
false => {
indicator_style.bottom = Val::Px((extents.y + real_to_entity.y).max(0.));
indicator_style.top = Val::Auto;
}
}
}
}
}
5 changes: 5 additions & 0 deletions src/hud.rs → src/hud/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ use bevy_rapier2d::prelude::Velocity;

use crate::{assets::UiAssets, ship::Ship, state::AppState};

pub mod indicator;

use indicator::IndicatorPlugin;

/// UI Speed component
#[derive(Component)]
pub struct UISpeed {}

pub struct HudPlugin;
impl Plugin for HudPlugin {
fn build(&self, app: &mut App) {
app.add_plugins(IndicatorPlugin);
app.add_systems(OnEnter(AppState::GameCreate), setup);
app.add_systems(Update, hud_speedometer.run_if(in_state(AppState::Active)));
}
Expand Down
7 changes: 7 additions & 0 deletions src/planetary_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use bevy::prelude::*;

use crate::{
assets::SpriteAssets,
hud::indicator::Indicated,
orbit::{orbital_positioning_system, Orbit},
planet::Planet,
star::Star,
Expand Down Expand Up @@ -73,6 +74,9 @@ fn setup(mut commands: Commands, sprites: Res<SpriteAssets>) {
// TODO: .1 is too fast, .2 is too choppy; needs more animation frames.
AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
Star {},
Indicated {
color: Color::YELLOW,
},
Name::new("Star"),
))
.with_children(|parent| {
Expand All @@ -87,6 +91,9 @@ fn setup(mut commands: Commands, sprites: Res<SpriteAssets>) {
// TODO: .1 is too fast, .2 is too choppy; needs more animation frames.
AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
Planet {},
Indicated {
color: Color::ORANGE_RED,
},
Orbit {
semi_major_axis: 500.0 / 2.0, // Divide by parent scale?
},
Expand Down

0 comments on commit 0349863

Please sign in to comment.