#inventory #ecs #static #bevy

bevy_mod_static_inventory

Bevy的静态库存

1个不稳定版本

0.1.0 2023年9月12日

#1019游戏开发

MIT/Apache

33KB
524

静态库存

Bevy的静态库存概念证明。静态库存意味着每种物品类型都是一个具有特定特质的结构体(或枚举)。这种方法的优点是出色的编辑器支持和编译时对某些操作的验证,例如,您不能将木棍和苹果放在同一个物品堆中。

它还打开了对ECS中库存请求部分支持的途径。例如,可以使用Bevy的查询过滤器仅对具有苹果的实体的系统进行调用。

这还允许您为每个单独的物品添加参数,例如工具的颜色或耐用性。

然而,目前(希望不久后)这种方法的缺点是无法在运行时创建物品。

安装

cargo add bevy_mod_static_inventory

使用方法

use std::{any::TypeId, time::Duration};

use bevy::{app::ScheduleRunnerPlugin, prelude::*};
use bevy_mod_static_inventory::{HasInInventory, Inventory, Item, Key};

fn main() {
    App::new()
        .add_plugins(
            MinimalPlugins.set(ScheduleRunnerPlugin::run_loop(Duration::from_secs_f64(1.0))),
        )
        .add_systems(Startup, setup)
        .add_systems(
            Update,
            (log_when_apple_in_inventory, log_when_stick_in_hand_slot),
        )
        .run();
}

pub struct HandSlot;

// TODO: Create derive macro
impl From<HandSlot> for Key {
    fn from(_: HandSlot) -> Self {
        Key::Type(TypeId::of::<HandSlot>())
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Apple;

// TODO: Create derive macro
impl Item for Apple {}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Stick;

impl Item for Stick {}

fn setup(mut commands: Commands) {
    let mut inv = Inventory::new().with_slot_count(4);

    inv.add(Apple).unwrap(); // add 1 apple
    inv.add((Apple, 2)).unwrap(); // add 2 apples
    inv.add((2, Apple)).unwrap(); // you also can swap count and item

    commands.spawn(inv);
    println!("Spawned entity with apples in inventory");

    let mut inv = Inventory::new().with_custom_slot(HandSlot);

    inv.insert(HandSlot, Stick).unwrap();

    commands.spawn(inv);
    println!("Spawned entity with apples in inventory");
}

fn log_when_apple_in_inventory(entities_with_apples: Query<DebugName, HasInInventory<Apple>>) {
    for e in entities_with_apples.iter() {
        println!("{:?} has Apple in inventory", e);
    }
}

fn log_when_stick_in_hand_slot(
    entities_with_apples: Query<DebugName, HasInInventory<Stick, HandSlot>>,
) {
    for e in entities_with_apples.iter() {
        println!("{:?} has Stick in hand slot", e);
    }
}


进度

  • 类型化和装箱的ItemStacks
  • 编号和自定义槽位
  • 为自定义槽定义ItemKey的宏
  • 高级查询过滤器(添加/删除物品等)
  • 完整文档
  • 支持动态物品注册(用于模组)
  • 在所有位置删除对TypeId的依赖,因为它在构建之间是不稳定的
  • 支持枚举槽位(例如,包含HeadBodyLegs变体的ArmorSlot
  • 支持向下转换以获取更具体的特质,这些特质将Item作为超特质(现在只能通过intertraitlinkme在运行时实现)

依赖关系

~20–29MB
~426K SLoC