diff --git a/src/animation/transform.rs b/src/animation/transform.rs index dda954f..b42c8a7 100644 --- a/src/animation/transform.rs +++ b/src/animation/transform.rs @@ -15,6 +15,6 @@ impl AnimatedTransform { pub fn transform_animation(query: Query<(&mut Transform, &AnimatedTransform)>) { for (mut transform, anim_transform) in query { - transform.translation = transform.translation.lerp(anim_transform.translation, 0.5); + transform.translation = transform.translation.lerp(anim_transform.translation, 0.25); } } diff --git a/src/card/drag.rs b/src/card/drag.rs index adfa2ee..8352be9 100644 --- a/src/card/drag.rs +++ b/src/card/drag.rs @@ -1,4 +1,68 @@ use bevy::prelude::*; +use crate::{animation::transform::AnimatedTransform, card::Hand}; + #[derive(Component)] pub struct DraggableCard; + +#[derive(Component)] +pub struct DraggedCard; + +#[derive(Resource)] +pub struct MousePosition(pub Vec3); + +pub fn mouse_position_system( + mut mouse: ResMut, + window: Single<&Window>, + camera: Single<(&Camera, &GlobalTransform)>, +) { + if let Some(Ok(mouse_pos)) = window + .cursor_position() + .and_then(|viewport_pos| Some(camera.0.viewport_to_world_2d(camera.1, viewport_pos))) + { + mouse.0 = Vec3 { + x: mouse_pos.x, + y: mouse_pos.y, + z: 0., + } + } +} + +pub fn card_drag_start( + event: On>, + mut commands: Commands, + card_query: Query<(), With>, + dragged_option: Option>, +) { + if dragged_option.is_some() { + return; + } + if let Err(_) = card_query.get(event.entity) { + return; + } + + commands + .entity(event.entity) + .insert(DraggedCard) + .remove_parent_in_place(); +} + +pub fn card_drag( + _: On>, + mut card_transform: Single<&mut AnimatedTransform, With>, + mouse_pos: Res, +) { + card_transform.translation = mouse_pos.0; +} + +pub fn card_drag_end( + _: On>, + mut commands: Commands, + dragged: Single>, + hand: Single>, +) { + commands + .entity(dragged.entity()) + .remove::() + .set_parent_in_place(hand.entity()); +} diff --git a/src/card/mod.rs b/src/card/mod.rs index 1ea841e..a8bf6bc 100644 --- a/src/card/mod.rs +++ b/src/card/mod.rs @@ -1,5 +1,6 @@ use crate::animation::transform::AnimatedTransform; use bevy::prelude::*; +use drag::*; pub mod drag; @@ -26,6 +27,11 @@ impl Plugin for CardPlugin { .add_systems(Update, card_arrange) .add_observer(card_add) .add_observer(card_clear); + app.insert_resource(MousePosition(Vec3::new(0., 0., 0.))) + .add_systems(PreUpdate, mouse_position_system) + .add_observer(card_drag_start) + .add_observer(card_drag) + .add_observer(card_drag_end); } } @@ -42,19 +48,18 @@ fn hand_setup(mut commands: Commands, asset_server: Res) { } fn card_arrange( - query: Query<(Entity, &mut AnimatedTransform, &Sprite, &ChildOf), With>, + mut query: Query<(&mut AnimatedTransform, &Sprite), With>, hand: Single<(Entity, &Children), With>, assets: Res>, ) { let cards_amount = hand.1.len(); - for (entity, mut transform, sprite, child_of) in query { - if child_of.parent() != hand.0 { + for (index, card) in hand.1.iter().enumerate() { + let Ok((mut transform, sprite)) = query.get_mut(card) else { continue; - } + }; let size = assets.get(&sprite.image).unwrap().size_f32(); let left_boundary = -size.x * (cards_amount as f32) / 2.0 + size.x / 2.0; - transform.translation.x = - left_boundary + size.x * (hand.1.iter().position(|x| x == entity).unwrap_or(0) as f32); + transform.translation.x = left_boundary + size.x * index as f32; transform.translation.y = size.y / 2.0; } } @@ -71,6 +76,8 @@ fn card_add( AnimatedTransform::from_xyz(0., 0., 0.), Card, ChildOf(hand.entity()), + DraggableCard, + Pickable::default(), )); } diff --git a/src/dev_tools/mod.rs b/src/dev_tools/mod.rs index e23daea..44ff836 100644 --- a/src/dev_tools/mod.rs +++ b/src/dev_tools/mod.rs @@ -18,13 +18,16 @@ impl Plugin for DevToolsPlugin { fn setup_debug_menu(mut commands: Commands) { let root = commands - .spawn(Node { - width: percent(100.), - height: percent(100.), - align_items: AlignItems::Start, - justify_content: JustifyContent::End, - ..default() - }) + .spawn(( + Node { + width: percent(100.), + height: percent(100.), + align_items: AlignItems::Start, + justify_content: JustifyContent::End, + ..default() + }, + Pickable::IGNORE, + )) .id(); let panel = commands .spawn((