164 lines
4.9 KiB
Rust
164 lines
4.9 KiB
Rust
use bevy::prelude::*;
|
|
|
|
#[derive(Component, Default)]
|
|
struct HeadSelector(pub usize);
|
|
|
|
#[derive(Component, Default)]
|
|
struct HeadImage(pub usize);
|
|
|
|
#[derive(Resource, Default)]
|
|
struct HeadsImages {
|
|
heads: Vec<Handle<Image>>,
|
|
}
|
|
|
|
#[derive(Resource, Default)]
|
|
struct ActiveHeads {
|
|
heads: [Option<usize>; 5],
|
|
current_slot: usize,
|
|
}
|
|
|
|
#[derive(Event)]
|
|
pub struct HeadChanged(pub usize);
|
|
|
|
pub fn plugin(app: &mut App) {
|
|
app.add_systems(Startup, setup);
|
|
app.add_systems(Update, (update, toggle_heads));
|
|
}
|
|
|
|
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|
let bg = asset_server.load("ui/head_bg.png");
|
|
let regular = asset_server.load("ui/head_regular.png");
|
|
let selector = asset_server.load("ui/selector.png");
|
|
|
|
commands
|
|
.spawn(Node {
|
|
position_type: PositionType::Absolute,
|
|
bottom: Val::Px(20.0),
|
|
right: Val::Px(100.0),
|
|
height: Val::Px(74.0),
|
|
..default()
|
|
})
|
|
.with_children(|parent| {
|
|
spawn_head_ui(parent, bg.clone(), regular.clone(), selector.clone(), 0);
|
|
spawn_head_ui(parent, bg.clone(), regular.clone(), selector.clone(), 1);
|
|
spawn_head_ui(parent, bg.clone(), regular.clone(), selector.clone(), 2);
|
|
spawn_head_ui(parent, bg.clone(), regular.clone(), selector.clone(), 3);
|
|
spawn_head_ui(parent, bg.clone(), regular.clone(), selector.clone(), 4);
|
|
});
|
|
|
|
let head_01 = asset_server.load("ui/heads/angry demonstrator.png");
|
|
let head_02 = asset_server.load("ui/heads/commando.png");
|
|
let head_03 = asset_server.load("ui/heads/goblin.png");
|
|
let head_04 = asset_server.load("ui/heads/highland hammer thrower.png");
|
|
let head_05 = asset_server.load("ui/heads/legionnaire.png");
|
|
|
|
commands.insert_resource(HeadsImages {
|
|
heads: vec![head_01, head_02, head_03, head_04, head_05],
|
|
});
|
|
|
|
commands.insert_resource(ActiveHeads {
|
|
heads: [Some(0), Some(1), Some(2), Some(3), Some(4)],
|
|
current_slot: 0,
|
|
});
|
|
}
|
|
|
|
fn spawn_head_ui(
|
|
parent: &mut ChildBuilder,
|
|
bg: Handle<Image>,
|
|
regular: Handle<Image>,
|
|
selector: Handle<Image>,
|
|
head: usize,
|
|
) {
|
|
parent
|
|
.spawn((Node {
|
|
position_type: PositionType::Relative,
|
|
justify_content: JustifyContent::Center,
|
|
width: Val::Px(74.0),
|
|
..default()
|
|
},))
|
|
.with_children(|parent| {
|
|
parent.spawn((
|
|
Node {
|
|
position_type: PositionType::Absolute,
|
|
top: Val::Px(-20.0),
|
|
..default()
|
|
},
|
|
Visibility::Hidden,
|
|
ImageNode::new(selector),
|
|
HeadSelector(head),
|
|
));
|
|
parent.spawn((
|
|
Node {
|
|
position_type: PositionType::Absolute,
|
|
..default()
|
|
},
|
|
ImageNode::new(bg),
|
|
));
|
|
parent.spawn((
|
|
Node {
|
|
position_type: PositionType::Absolute,
|
|
left: Val::Px(2.0),
|
|
right: Val::Px(2.0),
|
|
top: Val::Px(2.0),
|
|
bottom: Val::Px(2.0),
|
|
..default()
|
|
},
|
|
ImageNode::default(),
|
|
Visibility::Hidden,
|
|
HeadImage(head),
|
|
));
|
|
parent.spawn((
|
|
Node {
|
|
position_type: PositionType::Absolute,
|
|
..default()
|
|
},
|
|
ImageNode::new(regular),
|
|
));
|
|
});
|
|
}
|
|
|
|
fn update(
|
|
res: Res<ActiveHeads>,
|
|
heads_images: Res<HeadsImages>,
|
|
mut head_image: Query<(&HeadImage, &mut Visibility, &mut ImageNode), Without<HeadSelector>>,
|
|
mut head_selector: Query<(&HeadSelector, &mut Visibility), Without<HeadImage>>,
|
|
) {
|
|
if res.is_changed() {
|
|
for (HeadImage(head), mut vis, mut image) in head_image.iter_mut() {
|
|
if let Some(head) = res.heads[*head] {
|
|
*vis = Visibility::Visible;
|
|
image.image = heads_images.heads[head].clone();
|
|
} else {
|
|
*vis = Visibility::Hidden;
|
|
}
|
|
}
|
|
for (HeadSelector(head), mut vis) in head_selector.iter_mut() {
|
|
*vis = if *head == res.current_slot {
|
|
Visibility::Visible
|
|
} else {
|
|
Visibility::Hidden
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
fn toggle_heads(
|
|
mut commands: Commands,
|
|
mut res: ResMut<ActiveHeads>,
|
|
keys: Res<ButtonInput<KeyCode>>,
|
|
) {
|
|
let changed = if keys.just_pressed(KeyCode::KeyE) {
|
|
res.current_slot = (res.current_slot + 1) % 5;
|
|
true
|
|
} else if keys.just_pressed(KeyCode::KeyQ) {
|
|
res.current_slot = (res.current_slot + 4) % 5;
|
|
true
|
|
} else {
|
|
false
|
|
};
|
|
|
|
if changed {
|
|
commands.trigger(HeadChanged(res.heads[res.current_slot].unwrap()));
|
|
}
|
|
}
|