generated from 2ndbeam/bevy-template
feat: unfinished item drag and drop
This commit is contained in:
parent
c46fa75e54
commit
0add3e4c20
9 changed files with 191 additions and 15 deletions
133
Cargo.lock
generated
133
Cargo.lock
generated
|
|
@ -273,6 +273,24 @@ dependencies = [
|
||||||
"futures-lite",
|
"futures-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-io"
|
||||||
|
version = "2.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"cfg-if",
|
||||||
|
"concurrent-queue",
|
||||||
|
"futures-io",
|
||||||
|
"futures-lite",
|
||||||
|
"parking",
|
||||||
|
"polling",
|
||||||
|
"rustix 1.1.3",
|
||||||
|
"slab",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-lock"
|
name = "async-lock"
|
||||||
version = "3.4.2"
|
version = "3.4.2"
|
||||||
|
|
@ -921,6 +939,7 @@ dependencies = [
|
||||||
"bevy_post_process",
|
"bevy_post_process",
|
||||||
"bevy_ptr",
|
"bevy_ptr",
|
||||||
"bevy_reflect",
|
"bevy_reflect",
|
||||||
|
"bevy_remote",
|
||||||
"bevy_render",
|
"bevy_render",
|
||||||
"bevy_scene",
|
"bevy_scene",
|
||||||
"bevy_shader",
|
"bevy_shader",
|
||||||
|
|
@ -1201,6 +1220,31 @@ dependencies = [
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bevy_remote"
|
||||||
|
version = "0.18.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c0129e24bf3e281dd52996a9290c35f8c4821ca09e1ce8b8b222671e1ad9da0c"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"async-channel",
|
||||||
|
"async-io",
|
||||||
|
"bevy_app",
|
||||||
|
"bevy_asset",
|
||||||
|
"bevy_derive",
|
||||||
|
"bevy_ecs",
|
||||||
|
"bevy_log",
|
||||||
|
"bevy_platform",
|
||||||
|
"bevy_reflect",
|
||||||
|
"bevy_tasks",
|
||||||
|
"bevy_utils",
|
||||||
|
"http-body-util",
|
||||||
|
"hyper",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"smol-hyper",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_render"
|
name = "bevy_render"
|
||||||
version = "0.18.0"
|
version = "0.18.0"
|
||||||
|
|
@ -1394,6 +1438,7 @@ checksum = "990ffedd374dd2c4fe8f0fd4bcefd5617d1ee59164b6c3fcc356a69b48e26e8e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-channel",
|
"async-channel",
|
||||||
"async-executor",
|
"async-executor",
|
||||||
|
"async-io",
|
||||||
"async-task",
|
"async-task",
|
||||||
"atomic-waker",
|
"atomic-waker",
|
||||||
"bevy_platform",
|
"bevy_platform",
|
||||||
|
|
@ -2816,6 +2861,72 @@ version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
|
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"itoa",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http-body"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"http",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http-body-util"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"futures-core",
|
||||||
|
"http",
|
||||||
|
"http-body",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "httparse"
|
||||||
|
version = "1.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "httpdate"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hyper"
|
||||||
|
version = "1.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11"
|
||||||
|
dependencies = [
|
||||||
|
"atomic-waker",
|
||||||
|
"bytes",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"http",
|
||||||
|
"http-body",
|
||||||
|
"httparse",
|
||||||
|
"httpdate",
|
||||||
|
"itoa",
|
||||||
|
"pin-project-lite",
|
||||||
|
"pin-utils",
|
||||||
|
"smallvec",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "image"
|
name = "image"
|
||||||
version = "0.25.9"
|
version = "0.25.9"
|
||||||
|
|
@ -4367,6 +4478,19 @@ dependencies = [
|
||||||
"xkeysym",
|
"xkeysym",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smol-hyper"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7428a49d323867702cd12b97b08a6b0104f39ec13b49117911f101271321bc1a"
|
||||||
|
dependencies = [
|
||||||
|
"async-executor",
|
||||||
|
"async-io",
|
||||||
|
"futures-io",
|
||||||
|
"hyper",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smol_str"
|
name = "smol_str"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
|
@ -4582,6 +4706,15 @@ version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio"
|
||||||
|
version = "1.50.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d"
|
||||||
|
dependencies = [
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.9.12+spec-1.1.0"
|
version = "0.9.12+spec-1.1.0"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bevy = { version = "0.18.0", features = ["debug"] }
|
bevy = { version = "0.18.0", features = ["bevy_remote", "debug"] }
|
||||||
bevy_common_assets = { version = "0.15.0", features = ["toml"] }
|
bevy_common_assets = { version = "0.15.0", features = ["toml"] }
|
||||||
bevy_input = { version = "0.18.0", features = ["serde", "serialize"] }
|
bevy_input = { version = "0.18.0", features = ["serde", "serialize"] }
|
||||||
leafwing-input-manager = "0.20.0"
|
leafwing-input-manager = "0.20.0"
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use std::mem::swap;
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
#[derive(Component, Clone, Debug)]
|
#[derive(Component, Clone, Debug, Reflect)]
|
||||||
pub struct Item {
|
pub struct Item {
|
||||||
pub size: UVec2,
|
pub size: UVec2,
|
||||||
pub position: Option<UVec2>,
|
pub position: Option<UVec2>,
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,13 @@ use bevy::prelude::*;
|
||||||
pub mod item;
|
pub mod item;
|
||||||
pub mod ui;
|
pub mod ui;
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component, Reflect)]
|
||||||
pub struct Inventory {
|
pub struct Inventory {
|
||||||
pub size: UVec2,
|
pub size: UVec2,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Marker that this inventory will show up when UI is built
|
/// Marker that this inventory will show up when UI is built
|
||||||
#[derive(Component)]
|
#[derive(Component, Reflect)]
|
||||||
pub struct ActiveInventory;
|
pub struct ActiveInventory;
|
||||||
|
|
||||||
impl Inventory {
|
impl Inventory {
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,45 @@
|
||||||
use std::f32::consts::FRAC_PI_2;
|
use std::f32::consts::FRAC_PI_2;
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::{ecs::component::{ComponentId, ComponentIdFor}, prelude::*};
|
||||||
|
|
||||||
use crate::{inventory::{ActiveInventory, Inventory, item::Item}, ui::{UiRoot, WindowSize}};
|
use crate::{inventory::{ActiveInventory, Inventory, item::Item}, ui::{UiRoot, WindowSize}};
|
||||||
|
|
||||||
const UI_SLOT_ASSET_PATH: &'static str = "sprites/ui/inventory_slot.png";
|
const UI_SLOT_ASSET_PATH: &'static str = "sprites/ui/inventory_slot.png";
|
||||||
const TEMP_ITEM_PATH: &'static str = "sprites/items/choco_bar.png";
|
const TEMP_ITEM_PATH: &'static str = "sprites/items/choco_bar.png";
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component, Reflect)]
|
||||||
#[require(Node)]
|
#[require(Node)]
|
||||||
pub struct UiInventory;
|
pub struct UiInventory;
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component, Reflect)]
|
||||||
#[require(Node, ImageNode)]
|
#[require(Node, ImageNode)]
|
||||||
pub struct UiInventorySlot(UVec2);
|
pub struct UiInventorySlot(UVec2);
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component, Reflect)]
|
||||||
#[require(Node, ImageNode)]
|
#[require(Node, ImageNode)]
|
||||||
pub struct UiItem(Entity);
|
pub struct UiItem(Entity);
|
||||||
|
|
||||||
fn ui_inventory_bundle(inventory: &Inventory, window_size: &Res<WindowSize>) -> impl Bundle {
|
fn on_item_drag_drop(
|
||||||
|
event: On<Pointer<DragDrop>>,
|
||||||
|
ui_item_query: Query<&UiItem>,
|
||||||
|
slot_query: Query<(&UiInventorySlot, Option<&Children>)>,
|
||||||
|
) {
|
||||||
|
info!("dragdrop {} {}", event.dropped, event.event_target());
|
||||||
|
let Ok(ui_item) = ui_item_query.get(event.dropped) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let Ok((slot, _)) = slot_query.get(event.event_target()) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
info!("Item {:?} dropped on {:?}", ui_item.0, slot.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ui_inventory_bundle(
|
||||||
|
inventory: &Inventory,
|
||||||
|
window_size: &Res<WindowSize>,
|
||||||
|
_slot_id: ComponentId,
|
||||||
|
) -> impl Bundle {
|
||||||
let window_ratio = window_size.aspect_ratio();
|
let window_ratio = window_size.aspect_ratio();
|
||||||
let (width, height) = {
|
let (width, height) = {
|
||||||
if window_ratio >= 1. {
|
if window_ratio >= 1. {
|
||||||
|
|
@ -41,6 +61,10 @@ fn ui_inventory_bundle(inventory: &Inventory, window_size: &Res<WindowSize>) ->
|
||||||
grid_auto_rows: vec![GridTrack::percent(100. / inventory.size.y as f32)],
|
grid_auto_rows: vec![GridTrack::percent(100. / inventory.size.y as f32)],
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
Pickable::IGNORE,
|
||||||
|
GlobalZIndex::default(),
|
||||||
|
Observer::new(on_item_drag_drop)
|
||||||
|
// .with_component(slot_id),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -60,6 +84,10 @@ fn inventory_slot_bundle(x: u32, y: u32, image: Handle<Image>) -> impl Bundle {
|
||||||
align_items: AlignItems::Start,
|
align_items: AlignItems::Start,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
Pickable {
|
||||||
|
should_block_lower: true,
|
||||||
|
is_hoverable: true,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,6 +125,10 @@ fn ui_item_bundle(item: &Item, item_entity: Entity, image: Handle<Image>) -> imp
|
||||||
BackgroundColor(Color::hsla(0., 0., 0., 0.5)),
|
BackgroundColor(Color::hsla(0., 0., 0., 0.5)),
|
||||||
ui_transform,
|
ui_transform,
|
||||||
GlobalZIndex(1),
|
GlobalZIndex(1),
|
||||||
|
Pickable {
|
||||||
|
should_block_lower: false,
|
||||||
|
is_hoverable: true,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,6 +138,7 @@ pub fn setup_ui_inventory(
|
||||||
inventory_query: Query<(&Inventory, Option<&Children>), With<ActiveInventory>>,
|
inventory_query: Query<(&Inventory, Option<&Children>), With<ActiveInventory>>,
|
||||||
item_query: Query<&Item>,
|
item_query: Query<&Item>,
|
||||||
root_query: Query<Entity, With<UiRoot>>,
|
root_query: Query<Entity, With<UiRoot>>,
|
||||||
|
slot_id: ComponentIdFor<UiInventorySlot>,
|
||||||
window_size: Res<WindowSize>,
|
window_size: Res<WindowSize>,
|
||||||
) {
|
) {
|
||||||
let Ok(root) = root_query.single() else {
|
let Ok(root) = root_query.single() else {
|
||||||
|
|
@ -129,7 +162,7 @@ pub fn setup_ui_inventory(
|
||||||
}
|
}
|
||||||
None => Vec::new(),
|
None => Vec::new(),
|
||||||
};
|
};
|
||||||
let inventory_entity = commands.spawn(ui_inventory_bundle(inventory, &window_size))
|
let inventory_entity = commands.spawn(ui_inventory_bundle(inventory, &window_size, slot_id.get()))
|
||||||
.with_children(|commands| {
|
.with_children(|commands| {
|
||||||
for x in 0..inventory.size.x { for y in 0..inventory.size.y {
|
for x in 0..inventory.size.x { for y in 0..inventory.size.y {
|
||||||
let mut slot_commands = commands.spawn(inventory_slot_bundle(x, y, ui_slot_image.clone()));
|
let mut slot_commands = commands.spawn(inventory_slot_bundle(x, y, ui_slot_image.clone()));
|
||||||
|
|
@ -139,7 +172,8 @@ pub fn setup_ui_inventory(
|
||||||
}
|
}
|
||||||
} }
|
} }
|
||||||
}).id();
|
}).id();
|
||||||
commands.entity(root).add_child(inventory_entity);
|
commands.entity(root)
|
||||||
|
.add_child(inventory_entity);
|
||||||
|
|
||||||
// for simplicity we'll show only first inventory
|
// for simplicity we'll show only first inventory
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,12 @@ impl Plugin for ExpeditionPlugin {
|
||||||
ui::update_window_size,
|
ui::update_window_size,
|
||||||
))
|
))
|
||||||
.add_systems(OnEnter(GameState::Inventory), inventory::ui::setup_ui_inventory)
|
.add_systems(OnEnter(GameState::Inventory), inventory::ui::setup_ui_inventory)
|
||||||
.add_systems(OnExit(GameState::Inventory), inventory::ui::clear_ui_inventory);
|
.add_systems(OnExit(GameState::Inventory), inventory::ui::clear_ui_inventory)
|
||||||
|
.register_type::<inventory::Inventory>()
|
||||||
|
.register_type::<inventory::ActiveInventory>()
|
||||||
|
.register_type::<inventory::item::Item>()
|
||||||
|
.register_type::<inventory::ui::UiItem>()
|
||||||
|
.register_type::<inventory::ui::UiInventorySlot>()
|
||||||
|
.register_type::<inventory::ui::UiInventory>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use bevy::prelude::*;
|
use bevy::{prelude::*, remote::{RemotePlugin, http::RemoteHttpPlugin}};
|
||||||
|
|
||||||
use expedition_demo::ExpeditionPlugin;
|
use expedition_demo::ExpeditionPlugin;
|
||||||
|
|
||||||
|
|
@ -6,5 +6,7 @@ fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
|
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
|
||||||
.add_plugins(ExpeditionPlugin)
|
.add_plugins(ExpeditionPlugin)
|
||||||
|
.add_plugins(RemotePlugin::default())
|
||||||
|
.add_plugins(RemoteHttpPlugin::default())
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use leafwing_input_manager::prelude::*;
|
||||||
|
|
||||||
use crate::{GameState, InputAction as Action, inventory::{ActiveInventory, Inventory, item::Item}};
|
use crate::{GameState, InputAction as Action, inventory::{ActiveInventory, Inventory, item::Item}};
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component, Reflect)]
|
||||||
pub struct Player {
|
pub struct Player {
|
||||||
// px/s
|
// px/s
|
||||||
speed: f32,
|
speed: f32,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use bevy::{prelude::*, window::WindowResized};
|
use bevy::{prelude::*, window::WindowResized};
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component, Reflect)]
|
||||||
#[require(Node)]
|
#[require(Node)]
|
||||||
pub struct UiRoot;
|
pub struct UiRoot;
|
||||||
|
|
||||||
|
|
@ -24,6 +24,7 @@ impl UiRoot {
|
||||||
justify_self: JustifySelf::Center,
|
justify_self: JustifySelf::Center,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
Pickable::IGNORE,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue