use std::f32; use crate::animation::transform::AnimatedTransform; use bevy::prelude::*; use drag::*; pub mod drag; pub struct CardPlugin; #[derive(Component)] pub struct Card; #[derive(Component)] pub struct CardInHand; #[derive(Component)] pub struct Hand(Vec); #[derive(Resource)] pub struct CardImage(Handle); #[derive(Event)] pub struct AddCard; #[derive(EntityEvent)] pub struct InsertCard(Entity); #[derive(Event)] pub struct ClearCards; impl Plugin for CardPlugin { fn build(&self, app: &mut App) { app.add_systems(Startup, hand_setup) .add_systems(Update, card_arrange) .add_observer(card_add) .add_observer(card_clear) .add_observer(insert_card); 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); } } fn hand_setup(mut commands: Commands, asset_server: Res) { commands.spawn(( Hand(Vec::new()), Transform::from_xyz(0., -360., 0.), InheritedVisibility::VISIBLE, )); commands.insert_resource(CardImage( asset_server.load::("sprites/cards/units/fosma.png"), )); } fn card_arrange( mut query: Query<(&mut AnimatedTransform, &Sprite), With>, hand: Single<(Entity, &Hand, &Transform)>, assets: Res>, ) { let cards_amount = hand.1.0.len(); for (index, card) in hand.1.0.iter().enumerate() { let Ok((mut transform, sprite)) = query.get_mut(card.clone()) 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 * index as f32 + hand.2.translation.x; transform.translation.y = size.y / 2.0 + hand.2.translation.y; } } fn card_add( _: On, mut commands: Commands, card_image: Res, mut hand: Single<&mut Hand>, ) { let card = commands .spawn(( Sprite::from_image(card_image.0.clone()), Transform::from_xyz(0., 0., 0.), AnimatedTransform::from_xyz(0., 0., 0.), Card, DraggableCard, CardInHand, Pickable::default(), )) .id(); hand.0.push(card); } fn card_clear(_: On, mut commands: Commands, mut hand: Single<&mut Hand>) { for card in &hand.0 { let entity = card.clone(); commands.entity(entity).despawn(); } hand.0.clear(); } fn insert_card( event: On, mut hand_query: Single<(Entity, &mut Hand)>, transform_query: Query<&Transform, With>, ) { let Ok(inserted_transform) = transform_query.get(event.0) else { return; }; let mut decided_index: usize = 0; let mut decided_diff: f32 = f32::INFINITY; for (index, card) in hand_query.1.0.iter().enumerate() { let Ok(card_transform) = transform_query.get(card.clone()) else { continue; }; let calculated_diff = (inserted_transform.translation - card_transform.translation).length(); if decided_diff > calculated_diff { decided_diff = calculated_diff; decided_index = index; } } if let Some(pos) = hand_query.1.0.iter().position(|ent| *ent == event.0) { hand_query.1.0.remove(pos); } hand_query.1.0.insert(decided_index, event.0); }