card playing 1/2

This commit is contained in:
rendo 2026-01-27 05:56:42 +05:00
commit c24a9f3cec
7 changed files with 117 additions and 2 deletions

View file

@ -1,6 +1,7 @@
use bevy::prelude::*; use bevy::prelude::*;
#[derive(Component)] #[derive(Component)]
#[require(Transform)]
pub struct AnimatedTransform { pub struct AnimatedTransform {
pub translation: Vec3, pub translation: Vec3,
} }
@ -11,6 +12,11 @@ impl AnimatedTransform {
translation: Vec3 { x, y, z }, translation: Vec3 { x, y, z },
} }
} }
pub fn identity() -> Self {
AnimatedTransform {
translation: Vec3::ZERO,
}
}
} }
pub fn transform_animation(query: Query<(&mut Transform, &AnimatedTransform)>) { pub fn transform_animation(query: Query<(&mut Transform, &AnimatedTransform)>) {

View file

@ -5,6 +5,9 @@ use crate::{
card::{CardInHand, Hand, InsertCard}, card::{CardInHand, Hand, InsertCard},
}; };
#[derive(EntityEvent)]
pub struct CardDropped(pub Entity);
#[derive(Component)] #[derive(Component)]
pub struct DraggableCard; pub struct DraggableCard;
@ -69,6 +72,7 @@ pub fn card_drag_end(
dragged: Single<Entity, With<DraggedCard>>, dragged: Single<Entity, With<DraggedCard>>,
) { ) {
commands.trigger(InsertCard(dragged.entity())); commands.trigger(InsertCard(dragged.entity()));
commands.trigger(CardDropped(dragged.entity()));
commands commands
.entity(dragged.entity()) .entity(dragged.entity())
.remove::<DraggedCard>() .remove::<DraggedCard>()

View file

@ -3,8 +3,10 @@ use std::f32;
use crate::animation::transform::AnimatedTransform; use crate::animation::transform::AnimatedTransform;
use bevy::prelude::*; use bevy::prelude::*;
use drag::*; use drag::*;
use playing::*;
pub mod drag; pub mod drag;
pub mod playing;
pub struct CardPlugin; pub struct CardPlugin;
@ -35,12 +37,14 @@ impl Plugin for CardPlugin {
.add_systems(Update, card_arrange) .add_systems(Update, card_arrange)
.add_observer(card_add) .add_observer(card_add)
.add_observer(card_clear) .add_observer(card_clear)
.add_observer(insert_card); .add_observer(insert_card)
.add_observer(despawn_card);
app.insert_resource(MousePosition(Vec3::new(0., 0., 0.))) app.insert_resource(MousePosition(Vec3::new(0., 0., 0.)))
.add_systems(PreUpdate, mouse_position_system) .add_systems(PreUpdate, mouse_position_system)
.add_observer(card_drag_start) .add_observer(card_drag_start)
.add_observer(card_drag) .add_observer(card_drag)
.add_observer(card_drag_end); .add_observer(card_drag_end);
app.add_observer(card_playing_system);
} }
} }
@ -133,3 +137,17 @@ fn insert_card(
} }
hand_query.1.0.insert(decided_index, event.0); hand_query.1.0.insert(decided_index, event.0);
} }
fn despawn_card(event: On<Despawn>, mut hand_query: Single<&mut Hand>, cards_query: Query<&Card>) {
if let Err(_) = cards_query.get(event.entity) {
return;
}
if hand_query.0.contains(&event.entity) {
let index = hand_query
.0
.iter()
.position(|x| *x == event.entity)
.unwrap();
hand_query.0.remove(index);
}
}

26
src/card/playing.rs Normal file
View file

@ -0,0 +1,26 @@
use bevy::prelude::*;
use crate::{
animation::transform::AnimatedTransform,
card::drag::{CardDropped, MousePosition},
grid::Grid,
unit::UnitTextures,
};
pub fn card_playing_system(
event: On<CardDropped>,
mut commands: Commands,
mut grid: Single<&mut Grid>,
mouse_position: Res<MousePosition>,
textures: Res<UnitTextures>,
) {
let fosma = commands
.spawn((
AnimatedTransform::identity(),
Sprite::from_image(textures.fosma_texture()),
))
.id();
grid.try_set(mouse_position.0.truncate(), fosma);
commands.entity(event.0).despawn();
}

View file

@ -12,7 +12,7 @@ impl Plugin for GridPlugin {
} }
#[derive(Component)] #[derive(Component)]
struct Grid { pub struct Grid {
bounds: Rect, bounds: Rect,
columns: usize, columns: usize,
rows: usize, rows: usize,
@ -42,9 +42,43 @@ impl Grid {
.extend(0.) .extend(0.)
} }
pub fn is_in_grid(&self, position: Vec2) -> bool {
self.bounds.contains(position)
}
pub fn is_occupied(&self, position: Vec2) -> bool {
if self.is_in_grid(position) == false {
return true;
}
match self.elements[self.indexify_position(position)] {
Some(_) => true,
None => false,
}
}
pub fn is_free(&self, position: Vec2) -> bool {
self.is_occupied(position) == false
}
pub fn try_set(&mut self, position: Vec2, entity: Entity) -> bool {
if self.is_occupied(position) {
return false;
}
let index = self.indexify_position(position);
self.elements[index] = Some(entity);
true
}
fn cell_size(&self) -> Vec2 { fn cell_size(&self) -> Vec2 {
self.bounds.size() / vec2(self.columns as f32, -(self.rows as f32)) self.bounds.size() / vec2(self.columns as f32, -(self.rows as f32))
} }
fn indexify_position(&self, position: Vec2) -> usize {
let indexified_position = (position / self.cell_size()).floor();
indexified_position.x as usize + indexified_position.y as usize * self.columns
}
} }
fn setup_grid(mut commands: Commands) { fn setup_grid(mut commands: Commands) {

View file

@ -6,6 +6,7 @@ mod card;
mod dev_tools; mod dev_tools;
mod grid; mod grid;
mod turns; mod turns;
mod unit;
fn main() { fn main() {
App::new() App::new()
@ -17,6 +18,7 @@ fn main() {
dev_tools::DevToolsPlugin, dev_tools::DevToolsPlugin,
grid::GridPlugin, grid::GridPlugin,
turns::TurnSystemPlugin, turns::TurnSystemPlugin,
unit::UnitPlugin,
)) ))
.add_systems(Startup, setup) .add_systems(Startup, setup)
.run(); .run();

25
src/unit/mod.rs Normal file
View file

@ -0,0 +1,25 @@
use bevy::prelude::*;
pub struct UnitPlugin;
impl Plugin for UnitPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Startup, unit_setup);
}
}
fn unit_setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.insert_resource(UnitTextures {
fosma: asset_server.load("sprites/units/fosma.png"),
});
}
#[derive(Resource)]
pub struct UnitTextures {
fosma: Handle<Image>,
}
impl UnitTextures {
pub fn fosma_texture(&self) -> Handle<Image> {
self.fosma.clone()
}
}