11个稳定版本
1.4.1 | 2023年2月24日 |
---|---|
1.4.0 |
|
1.3.1 | 2022年11月18日 |
1.2.2 | 2022年10月31日 |
在游戏开发类别中排名#294
35KB
643 行
一个高性能、无依赖的ECS库,具有良好的API,用Rust编写。
用法
# Cargo.toml
[dependecies]
kiwi-ecs = "1.3"
// lib.rs
use kiwi_ecs::*;
世界
首先,创建一个新的World
。这是ecs的起点。程序可以有多个独立的世界。
pub fn main() {
let mut world = World::new();
}
组件
组件定义如下
#[derive(Component)]
struct Position {
x: u32,
y: u32
}
标志
单元结构不能用作组件,这是您需要使用标志的地方。标志表示为一个枚举
#[flags]
enum Flags {
Player,
Enemy,
Ground,
}
实体
要创建具有给定组件的新实体
// spawn_entity macro accepts the world as the first parameter, and the
// components to add to the entity as the other parameters
let entity_id = spawn_entity!(world, Position { x: 0, y: 0 });
您可以使用set_flag
方法给实体一个标志
world.set_flag(entity_id, Flags::Player);
系统
定义系统有两种方式。
第一种是使用system
宏
// immutable system
#[system(pos: Position)]
fn print_positions(world: &World) {
println!("{:?}", pos);
}
// mutable system
#[system(pos: Position, vel: Vel)]
fn move_entities(world: &mut World) {
pos.x += vel.x;
pos.y += vel.y
}
// query entity ids as well
#[system(id: EntityId, pos: Position)]
/// prints all entities ids having the position component
fn print_entity_ids(world: &World) {
println!("{id}");
}
pub fn main() {
let mut world = World::new();
//--snip
// Call the systems
print_positions(&world);
move_entities(&mut world);
print_entity_ids(&world);
}
要创建一个可变系统,函数应将其第一个参数作为world: &mut World
,对于不可变的一个,添加world: &World
。
函数可以包含任何数量的您可以在调用时传递给它的参数。
函数可以返回任何类型的Result<(), Any>
。如果此函数具有给定的结果返回类型,则在系统结束时将返回Ok(())
。
第二种是使用query
和query_mut
宏
pub fn main() {
let mut world = World::new();
//--snip
let query_result = query!(world, Position);
let query_result = query_mut!(world, Position, Velocity);
let query_result = query!(world, EntityId, Position);
// You can now loop over the components
query_result.for_each(|components| {
// ...
});
}
查询中的标志
您可以使用标志进一步过滤查询
#[system(id: EntityId, pos: Position)]
fn on_player(world: &World) {
if world.has_flag(id, Flags::Player) {
// ...
}
}
let query_result = query!(world, EntityId, Position)
.filter(|(id, _pos)| world.has_flag(*id, Flags::Player));
特性标志
try
此crate的try功能允许在系统中提前返回。
要启用它
# Cargo.toml
[dependencies]
kiwi-ecs = { version = "*", features = ["try"] }
用法
使用try
标记返回类型为Result
的ok类型()
的系统
#[system(try, id: EntityId, pos: Position)]
fn a_system_with_a_fallible_condition(world: &World) -> Result<(), String> {
let mesh = get_mesh(id)?; // fallible function
render(mesh, pos)?;
}
除了返回 Err
外,您还可以使用 return std::ops::ControlFlow::Continue(())
来跳过当前实体并继续到下一个,或者使用 return std::ops::ControlFlow::Break(())
来在没有错误的情况下跳出函数。
贡献
欢迎贡献者。如果您发现任何错误,请随意提出问题。如果您愿意,PR 也会受到赞赏!
许可证
MIT 许可证下授权。
依赖项
~1.5MB
~35K SLoC