generated from 2ndbeam/bevy-template
- Added scrollable container for inventories - Fixed slots being visibly hovered when dragging items
97 lines
3.2 KiB
Rust
97 lines
3.2 KiB
Rust
use bevy::prelude::*;
|
|
use leafwing_input_manager::prelude::*;
|
|
|
|
use crate::{GameState, InputAction as Action, inventory::{ActiveInventory, Inventory, item::Item}};
|
|
|
|
#[derive(Component, Reflect)]
|
|
pub struct Player {
|
|
// px/s
|
|
speed: f32,
|
|
}
|
|
|
|
fn player_bundle(asset_server: &Res<AssetServer>) -> impl Bundle {
|
|
let image = asset_server.load("sprites/player/player.png");
|
|
(
|
|
Player {
|
|
speed: 51.2,
|
|
},
|
|
Sprite::from_image(image),
|
|
Transform::from_xyz(0f32, 0f32, 1f32),
|
|
Action::default_input_map(),
|
|
Name::new("Player"),
|
|
children![
|
|
(Inventory::new(UVec2::new(6, 2)), ActiveInventory),
|
|
(Inventory::new(UVec2::new(5, 3)), ActiveInventory),
|
|
(Inventory::new(UVec2::new(4, 4)), ActiveInventory),
|
|
],
|
|
)
|
|
}
|
|
|
|
pub fn setup_player(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|
commands.spawn(player_bundle(&asset_server));
|
|
}
|
|
|
|
pub fn try_insert_item(
|
|
mut commands: Commands,
|
|
item_query: Query<&Item>,
|
|
inventory_query: Query<(Entity, &Inventory, Option<&Children>)>,
|
|
) {
|
|
let mut item = Item::new(UVec2::new(1, 1));
|
|
let name = Name::new(format!("Item {}x{}", item.size.x, item.size.y));
|
|
for (entity, inventory, children) in inventory_query.iter().sort::<Entity>() {
|
|
let children = match children {
|
|
Some(children) => &children[..],
|
|
None => &[],
|
|
};
|
|
match inventory.find_free_space(item_query, children, item.size) {
|
|
Some((position, should_rotate)) => {
|
|
if should_rotate {
|
|
item.rotate();
|
|
}
|
|
item.position = Some(position);
|
|
info!("Spawning item {item:?}");
|
|
commands.entity(entity).with_child((item, name));
|
|
break;
|
|
},
|
|
None => (),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn handle_input(
|
|
mut commands: Commands,
|
|
time: Res<Time>,
|
|
state: Res<State<GameState>>,
|
|
mut next_state: ResMut<NextState<GameState>>,
|
|
mut player: Query<(&Player, &mut ActionState<Action>, &mut Transform, &mut Sprite)>,
|
|
) {
|
|
let player = player.single_mut().expect("Player should be single");
|
|
match state.get() {
|
|
GameState::Running => {
|
|
let (Player {speed}, mut action_state, mut transform, mut sprite) = player;
|
|
|
|
if action_state.just_released(&Action::ToggleInventory) {
|
|
next_state.set(GameState::Inventory);
|
|
action_state.reset(&Action::ToggleInventory);
|
|
}
|
|
|
|
let direction = action_state.clamped_value(&Action::Move);
|
|
|
|
transform.translation.x += direction * speed * time.delta_secs();
|
|
if direction != 0f32 {
|
|
sprite.flip_x = direction < 0f32;
|
|
}
|
|
|
|
if action_state.just_pressed(&Action::Interact) {
|
|
commands.run_system_cached(try_insert_item);
|
|
}
|
|
},
|
|
GameState::Inventory => {
|
|
let (_, mut action_state, _, _) = player;
|
|
if action_state.just_released(&Action::ToggleInventory) {
|
|
next_state.set(GameState::Running);
|
|
action_state.reset(&Action::ToggleInventory);
|
|
}
|
|
},
|
|
}
|
|
}
|