generated from tipragot/rust
Click-on tile handle system #74
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
pub mod generation;
|
pub mod generation;
|
||||||
pub mod hex;
|
pub mod hex;
|
||||||
pub mod renderer;
|
|
||||||
pub mod selection;
|
pub mod selection;
|
||||||
|
pub mod renderer;
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
//! All programs related to the selection of tiles.
|
//! All programs related to the selection of tiles.
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy::sprite::Anchor;
|
|
||||||
|
|
||||||
use super::Tile;
|
use super::Tile;
|
||||||
|
|
||||||
/// A component that mark a tile as selected.
|
/// The event that is triggered when a tile is selected.
|
||||||
#[derive(Component)]
|
///
|
||||||
pub struct SelectedTile;
|
/// The event contains the index (ID) of the selected tile.
|
||||||
|
#[derive(Event)]
|
||||||
/// A component that mark an entity as a selection.
|
pub struct TileJustClicked(pub u32);
|
||||||
#[derive(Component)]
|
|
||||||
struct Selection;
|
|
||||||
|
|
||||||
/// A event that is triggered when a mouse button is clicked.
|
/// A event that is triggered when a mouse button is clicked.
|
||||||
///
|
///
|
||||||
|
@ -19,14 +16,13 @@ struct Selection;
|
||||||
#[derive(Event)]
|
#[derive(Event)]
|
||||||
struct ClickOnTheWorld(Vec2);
|
struct ClickOnTheWorld(Vec2);
|
||||||
|
|
||||||
/// A plugin that handles and render the selection of tiles.
|
/// A plugin that handles the selection of tiles.
|
||||||
pub struct SelectorPlugin;
|
pub struct SelectorPlugin;
|
||||||
|
|
||||||
impl Plugin for SelectorPlugin {
|
impl Plugin for SelectorPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_systems(PreUpdate, mouse_handler)
|
app.add_systems(PreUpdate, mouse_handler)
|
||||||
.add_systems(PreUpdate, select_closest_tile)
|
.add_systems(PreUpdate, select_closest_tile)
|
||||||
.add_systems(Update, render_selection)
|
|
||||||
.add_event::<ClickOnTheWorld>();
|
.add_event::<ClickOnTheWorld>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,11 +62,9 @@ fn mouse_handler(
|
||||||
/// Selects the closest tile to the cursor and marks it as selected.
|
/// Selects the closest tile to the cursor and marks it as selected.
|
||||||
/// It also unmarks the old selection if there is one.
|
/// It also unmarks the old selection if there is one.
|
||||||
fn select_closest_tile(
|
fn select_closest_tile(
|
||||||
mut commands: Commands,
|
|
||||||
tiles: Query<(Entity, &Transform, &Tile)>,
|
tiles: Query<(Entity, &Transform, &Tile)>,
|
||||||
mut old_selection: Query<Entity, With<SelectedTile>>,
|
|
||||||
mut selected_tile: Local<Option<u32>>,
|
|
||||||
mut click_event_reader: EventReader<ClickOnTheWorld>,
|
mut click_event_reader: EventReader<ClickOnTheWorld>,
|
||||||
|
mut select_tile_event_writer: EventWriter<TileJustClicked>,
|
||||||
) {
|
) {
|
||||||
for click_event in click_event_reader.read() {
|
for click_event in click_event_reader.read() {
|
||||||
// The closest tile and its distance to the cursor.
|
// The closest tile and its distance to the cursor.
|
||||||
|
@ -93,46 +87,7 @@ fn select_closest_tile(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(tile_entity) = closest_entity {
|
if let Some(tile_entity) = closest_entity {
|
||||||
if *selected_tile == Some(tile_entity.index()) {
|
select_tile_event_writer.send(TileJustClicked(tile_entity.index()));
|
||||||
return;
|
|
||||||
}
|
|
||||||
commands.entity(tile_entity).insert(SelectedTile);
|
|
||||||
*selected_tile = Some(tile_entity.index());
|
|
||||||
}
|
|
||||||
|
|
||||||
for entity in old_selection.iter_mut() {
|
|
||||||
commands.entity(entity).remove::<SelectedTile>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Renders the selection with a sprite.
|
|
||||||
///
|
|
||||||
/// The position updates when the selected tile changes.
|
|
||||||
fn render_selection(
|
|
||||||
mut commands: Commands,
|
|
||||||
asset_server: Res<AssetServer>,
|
|
||||||
query: Query<&Transform, Added<SelectedTile>>,
|
|
||||||
mut selection_query: Query<&mut Transform, (With<Selection>, Without<SelectedTile>)>,
|
|
||||||
) {
|
|
||||||
for target_transform in query.iter() {
|
|
||||||
let mut transform = *target_transform;
|
|
||||||
transform.translation.z += 1.0;
|
|
||||||
if selection_query.is_empty() {
|
|
||||||
commands
|
|
||||||
.spawn(SpriteBundle {
|
|
||||||
sprite: Sprite {
|
|
||||||
anchor: Anchor::BottomRight,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
transform,
|
|
||||||
// TODO: This image is a temporary image of the selection.
|
|
||||||
texture: asset_server.load("selection.png"),
|
|
||||||
..default()
|
|
||||||
})
|
|
||||||
.insert(Selection);
|
|
||||||
} else if let Ok(mut selection_transform) = selection_query.get_single_mut() {
|
|
||||||
*selection_transform = transform;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue