generated from tipragot/rust
Merge branch 'improve-selection' into text-info
Some checks failed
Rust Checks / checks (push) Failing after 10s
Some checks failed
Rust Checks / checks (push) Failing after 10s
This commit is contained in:
commit
a5af0d486b
|
@ -5,6 +5,7 @@ use border_wars::camera::CameraPlugin;
|
||||||
use border_wars::map::click_tile::TilesClickable;
|
use border_wars::map::click_tile::TilesClickable;
|
||||||
use border_wars::map::generation::{MapGenerationPlugin, StartMapGeneration};
|
use border_wars::map::generation::{MapGenerationPlugin, StartMapGeneration};
|
||||||
use border_wars::map::renderer::RendererPlugin;
|
use border_wars::map::renderer::RendererPlugin;
|
||||||
|
use border_wars::map::selected_tile::SelectTilePlugin;
|
||||||
use border_wars::scenes::ScenesPlugin;
|
use border_wars::scenes::ScenesPlugin;
|
||||||
use border_wars::ui::tiles_info::TilesInfoPlugin;
|
use border_wars::ui::tiles_info::TilesInfoPlugin;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
//! Contains all the logic related to the map.
|
//! Contains all the logic related to the map.
|
||||||
|
|
||||||
pub mod click_tile;
|
|
||||||
pub mod generation;
|
pub mod generation;
|
||||||
pub mod hex;
|
pub mod hex;
|
||||||
pub mod renderer;
|
pub mod renderer;
|
||||||
|
pub mod selected_tile;
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ impl Plugin for RendererPlugin {
|
||||||
|
|
||||||
/// The gap between the center of the tiles in the map.
|
/// The gap between the center of the tiles in the map.
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
struct TilesGap(Vec2);
|
pub struct TilesGap(pub Vec2);
|
||||||
|
|
||||||
/// The size of the tiles in the map.
|
/// The size of the tiles in the map.
|
||||||
#[derive(Resource, Clone, Copy)]
|
#[derive(Resource, Clone, Copy)]
|
||||||
|
@ -81,7 +81,7 @@ fn render_map(
|
||||||
|
|
||||||
commands.entity(entity).insert(SpriteBundle {
|
commands.entity(entity).insert(SpriteBundle {
|
||||||
sprite: Sprite {
|
sprite: Sprite {
|
||||||
anchor: Anchor::BottomLeft,
|
anchor: Anchor::BottomCenter,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
texture,
|
texture,
|
||||||
|
|
|
@ -1,16 +1,11 @@
|
||||||
//! All programs related to the clicking on a tile.
|
//! All programs related to the selection of a tile.
|
||||||
|
|
||||||
use bevy::input::mouse::MouseButtonInput;
|
use bevy::input::mouse::MouseButtonInput;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
use super::renderer::TilesGap;
|
||||||
use super::Tile;
|
use super::Tile;
|
||||||
|
|
||||||
/// The event that is triggered when a tile is clicked.
|
|
||||||
///
|
|
||||||
/// The event contains the index (ID) of the clicked tile.
|
|
||||||
#[derive(Event)]
|
|
||||||
pub struct TileJustClicked(pub u32);
|
|
||||||
|
|
||||||
/// An event that is triggered when a mouse button is clicked.
|
/// An event that is triggered when a mouse button is clicked.
|
||||||
///
|
///
|
||||||
/// The event contains the position of the cursor in the world.
|
/// The event contains the position of the cursor in the world.
|
||||||
|
@ -22,15 +17,37 @@ struct ClickOnTheWorld(Vec2);
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct ZoneNotClickable;
|
pub struct ZoneNotClickable;
|
||||||
|
|
||||||
/// A plugin that handles the selection of tiles.
|
/// The currently selected tile.
|
||||||
pub struct TilesClickable;
|
#[derive(Resource, Default, Debug)]
|
||||||
|
pub enum SelectedTile {
|
||||||
|
/// The entity of the selected tile.
|
||||||
|
Tile(Entity),
|
||||||
|
|
||||||
impl Plugin for TilesClickable {
|
/// Zero tile selected.
|
||||||
|
#[default]
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SelectedTile {
|
||||||
|
/// Returns the index (ID) of the selected tile.
|
||||||
|
/// Returns `None` if no tile is selected.
|
||||||
|
pub const fn get_entity(&self) -> Option<Entity> {
|
||||||
|
match self {
|
||||||
|
Self::Tile(entity) => Some(*entity),
|
||||||
|
Self::None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A plugin that handles the selection of tiles.
|
||||||
|
pub struct SelectTilePlugin;
|
||||||
|
|
||||||
|
impl Plugin for SelectTilePlugin {
|
||||||
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_event::<ClickOnTheWorld>()
|
.add_event::<ClickOnTheWorld>()
|
||||||
.add_event::<TileJustClicked>();
|
.init_resource::<SelectedTile>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,25 +95,30 @@ fn mouse_handler(
|
||||||
events_writer.send(ClickOnTheWorld(cursor_position_in_world));
|
events_writer.send(ClickOnTheWorld(cursor_position_in_world));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the closest tile to the cursor and send it in an event.
|
/// Get the closest tile to the cursor and select it.
|
||||||
fn select_closest_tile(
|
fn select_closest_tile(
|
||||||
tiles: Query<(Entity, &Transform, &Tile)>,
|
tiles: Query<(Entity, &Transform, &Tile)>,
|
||||||
mut click_event_reader: EventReader<ClickOnTheWorld>,
|
mut click_event_reader: EventReader<ClickOnTheWorld>,
|
||||||
mut clicked_tile_event_writer: EventWriter<TileJustClicked>,
|
tile_gap: Res<TilesGap>,
|
||||||
|
mut current_entity: ResMut<SelectedTile>,
|
||||||
) {
|
) {
|
||||||
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.
|
||||||
let mut closest_entity: Option<Entity> = None;
|
let mut closest_entity: Option<Entity> = None;
|
||||||
let mut closest_position: Option<f32> = None;
|
let mut closest_position: Option<f32> = None;
|
||||||
|
|
||||||
|
// To keep the aspect ratio.
|
||||||
|
let click_position = click_event.0 / tile_gap.0;
|
||||||
|
|
||||||
for (tile_entity, tile_transform, tile_type) in tiles.iter() {
|
for (tile_entity, tile_transform, tile_type) in tiles.iter() {
|
||||||
let mut tile_position = tile_transform.translation.truncate();
|
|
||||||
let tile_size = tile_type.get_image_size();
|
let tile_size = tile_type.get_image_size();
|
||||||
let tile_scale = tile_transform.scale.truncate();
|
let tile_scale = tile_transform.scale.truncate();
|
||||||
|
|
||||||
tile_position += (tile_size / 2.0) * tile_scale;
|
let mut tile_position = tile_transform.translation.truncate() / tile_gap.0;
|
||||||
|
// The origine of the tile is the bottom center.
|
||||||
|
tile_position.y += (tile_size.y / 2.0) * tile_scale.y / tile_gap.0.y;
|
||||||
|
|
||||||
let distance_to_cursor = tile_position.distance(click_event.0);
|
let distance_to_cursor = tile_position.distance(click_position);
|
||||||
|
|
||||||
if closest_position.is_none() || closest_position > Some(distance_to_cursor) {
|
if closest_position.is_none() || closest_position > Some(distance_to_cursor) {
|
||||||
closest_entity = Some(tile_entity);
|
closest_entity = Some(tile_entity);
|
||||||
|
@ -104,7 +126,11 @@ fn select_closest_tile(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(tile_entity) = closest_entity {
|
if let Some(tile_entity) = closest_entity {
|
||||||
clicked_tile_event_writer.send(TileJustClicked(tile_entity.index()));
|
if current_entity.get_entity() == Some(tile_entity) {
|
||||||
|
*current_entity = SelectedTile::None;
|
||||||
|
} else {
|
||||||
|
*current_entity = SelectedTile::Tile(tile_entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue