Merge branch '52-move-and-interaction-click-outside-of-grid' into 'dev'

Fix move/interaction click handling

See merge request softwaregrundprojekt/2025-2026/einzelprojekt/tutorium-moritz/bernroider-dominik/bernroider-dominik!17
This commit is contained in:
Dominik Bernroider
2025-11-29 15:27:38 +00:00
9 changed files with 62 additions and 14 deletions

View File

@@ -1,3 +1,4 @@
use super::errors::GridError;
use crate::prelude::*;
pub fn grid_start_x(grid_width: u32) -> f32 {
@@ -8,24 +9,25 @@ pub fn grid_start_y(grid_height: u32) -> f32 {
-(grid_height as f32 * TILE_SIZE) / 2.0 + TILE_SIZE / 2.0
}
pub fn world_to_grid_coords(world_pos: Vec3, grid_width: u32, grid_height: u32) -> (u32, u32) {
pub fn world_to_grid_coords(
world_pos: Vec3,
grid_width: u32,
grid_height: u32,
) -> Result<(u32, u32), GridError> {
let start_x = grid_start_x(grid_width);
let start_y = grid_start_y(grid_height);
let x = ((world_pos.x - start_x + TILE_SIZE / 2.0) / TILE_SIZE).floor();
let y = ((world_pos.y - start_y + TILE_SIZE / 2.0) / TILE_SIZE).floor();
let mut x_u32 = x as u32;
let mut y_u32 = y as u32;
if x_u32 >= grid_width {
x_u32 = grid_width - 1;
}
if y_u32 >= grid_height {
y_u32 = grid_height - 1;
if x >= grid_width as f32 || y >= grid_height as f32 || x < 0.0 || y < 0.0 {
return Err(GridError::OutOfBounds {
x: x as i32,
y: x as i32,
});
}
(x_u32, y_u32)
Ok((x as u32, y as u32))
}
pub fn grid_to_world_coords(

View File

@@ -14,6 +14,7 @@ pub fn open_settings(commands: &mut Commands) {
},
ZIndex(1),
BackgroundColor(Color::srgba(0.0, 0.0, 0.0, 0.8)),
GlobalTransform::default(),
))
.with_children(|parent| {
parent

View File

@@ -38,6 +38,7 @@ fn move_click(
camera: Single<(&Camera, &GlobalTransform), With<Camera2d>>,
config: Res<GameConfig>,
phase: Res<CurrentPhase>,
ui_query: Query<(&ComputedNode, &GlobalTransform), With<Node>>,
) {
match phase.0 {
Phase::Focus { .. } => return,
@@ -50,10 +51,17 @@ fn move_click(
let Some(cursor_pos) = window.cursor_position() else {
return;
};
if ui_blocks(window, cursor_pos, ui_query) {
return;
}
let Ok(world_pos) = cam.viewport_to_world(cam_transform, cursor_pos) else {
return;
};
let (x, y) = world_to_grid_coords(world_pos.origin, config.grid_width, config.grid_height);
let Ok((x, y)) =
world_to_grid_coords(world_pos.origin, config.grid_width, config.grid_height)
else {
return;
};
println!("Move Click: ({}, {})", x, y);
move_messages.write(MoveMessage { x, y });
@@ -67,6 +75,7 @@ fn interact_click(
camera: Single<(&Camera, &GlobalTransform), With<Camera2d>>,
config: Res<GameConfig>,
phase: Res<CurrentPhase>,
ui_query: Query<(&ComputedNode, &GlobalTransform), With<Node>>,
// for debug
grid: ResMut<Grid>,
tile_query: Query<&mut TileState>,
@@ -82,10 +91,17 @@ fn interact_click(
let Some(cursor_pos) = window.cursor_position() else {
return;
};
if ui_blocks(window, cursor_pos, ui_query) {
return;
}
let Ok(world_pos) = cam.viewport_to_world(cam_transform, cursor_pos) else {
return;
};
let (x, y) = world_to_grid_coords(world_pos.origin, config.grid_width, config.grid_height);
let Ok((x, y)) =
world_to_grid_coords(world_pos.origin, config.grid_width, config.grid_height)
else {
return;
};
println!("Interact Click: ({}, {})", x, y);
interact_messages.write(InteractStartMessage { x, y });
@@ -100,7 +116,7 @@ fn interact_click(
},
tile_query,
)
.unwrap();
.unwrap_or_else(|_| ());
}
}
}

View File

@@ -13,6 +13,7 @@ pub fn open_inventory(commands: &mut Commands, items: Query<&ItemStack>) {
},
ZIndex(1),
BackgroundColor(Color::srgba(0.0, 0.0, 0.0, 0.8)),
GlobalTransform::default(),
))
.with_children(|parent| {
parent

View File

@@ -13,6 +13,7 @@ pub fn spawn_load_popup(commands: &mut Commands) {
},
ZIndex(1),
BackgroundColor(Color::srgba(0.0, 0.0, 0.0, 0.8)),
GlobalTransform::default(),
))
.with_children(|parent| {
parent

View File

@@ -4,6 +4,7 @@ use bevy::{input::mouse::*, picking::hover::HoverMap};
pub mod components;
pub mod consts;
pub mod ui;
pub mod utils;
pub struct UiPlugin;

View File

@@ -1,3 +1,5 @@
use bevy::window::PrimaryWindow;
use crate::prelude::*;
pub fn button(

24
src/features/ui/utils.rs Normal file
View File

@@ -0,0 +1,24 @@
use crate::prelude::*;
use bevy::window::PrimaryWindow;
pub fn ui_blocks(
window: Single<&Window, With<PrimaryWindow>>,
cursor_pos: Vec2,
ui_query: Query<(&ComputedNode, &GlobalTransform), With<Node>>,
) -> bool {
let ui_point = Vec2::new(
cursor_pos.x - window.width() / 2.0,
(window.height() / 2.0) - cursor_pos.y,
);
ui_query.iter().any(|(node, global_transform)| {
let size = node.size();
let center = global_transform.translation().truncate();
let half_size = size / 2.0;
let min = center - half_size;
let max = center + half_size;
ui_point.x >= min.x && ui_point.x <= max.x && ui_point.y >= min.y && ui_point.y <= max.y
})
}

View File

@@ -14,7 +14,7 @@ pub use crate::features::{
messages::{InteractStartMessage, MoveMessage},
},
savegame::components::SavegamePath,
ui::{components::ButtonVariant, consts::*, ui::*},
ui::{components::ButtonVariant, consts::*, ui::*, utils::*},
};
pub use crate::utils::path::get_internal_path;
pub use bevy::prelude::*;