4个版本

0.0.4 2021年9月28日
0.0.3 2021年9月25日
0.0.2 2021年9月19日
0.0.1 2021年9月15日

#733 in 游戏开发

MIT 许可证

25KB
546

ecs-rust

Build Status Crate

ecu-rust 是一个用Rust编写的微型ECS (实体组件系统)库。

在线演示

在线WebAssembly演示

Rust代码使用wasm-bindgen编译为WebAssembly,甚至可以在网页浏览器中运行。

Web Collision demo

特性

  • 微型 ECS
  • 易于使用
  • Rust保证内存安全
  • 提供清晰的ECS 设计
  • 通过编译为WebAssembly与Web应用兼容

文档

待定

示例代码

// Import ecs-rust
use ecs_rust::world::World;
use ecs_rust::entity_manager::{EntityIdAccessor, EntityManager};
use ecs_rust::component::Component;
use ecs_rust::system::System;

// Define Components and Systems

struct Namable {
  name: &'static str
}

struct Position {
  x: f32,
  y: f32
}

struct Velocity {
  x: f32,
  y: f32
}

struct Step {
  num: u32
}

struct PrintStepSystem;
struct MoveSystem;
struct PrintPositionSystem;

// Implement Components and Systems

impl Component for Namable {}
impl Component for Position {}
impl Component for Velocity {}
impl Component for Step {}

impl System for PrintStepSystem {
  fn update(&mut self, manager: &mut EntityManager, _accessor: &mut EntityIdAccessor) {
    let steps = manager.borrow_components_mut::<Step>().unwrap();
    for step in steps.iter_mut() {
      step.num += 1;
      println!("Step {}", step.num);
    }
  }
}

impl System for MoveSystem {
  fn update(&mut self, manager: &mut EntityManager, accessor: &mut EntityIdAccessor) {
    let entity_ids = accessor.borrow_ids_for_pair::<Velocity, Position>(manager).unwrap();
    for id in entity_ids.iter() {
      let (velocity, mut position) = manager.borrow_component_pair_mut::<Velocity, Position>(*id).unwrap();
      position.x += velocity.x;
      position.y += velocity.y;
    }
  }
}

impl System for PrintPositionSystem {
  fn update(&mut self, manager: &mut EntityManager, accessor: &mut EntityIdAccessor) {
    let entity_ids = accessor.borrow_ids_for_pair::<Namable, Position>(manager).unwrap();
    for id in entity_ids.iter() {
      let name = manager.borrow_component::<Namable>(*id).unwrap();
      let position = manager.borrow_component::<Position>(*id).unwrap();
      println!("{} is at ({}, {})", name.name, position.x, position.y);
    }
  }
}

// Build an application and Run

fn main() {
  // Create world
  let mut world = World::new();

  // Register Components to world
  world
    .register_component::<Step>()
    .register_component::<Namable>()
    .register_component::<Position>()
    .register_component::<Velocity>();

  // Create Entities and add Components to them
  {
    let entity_id = world.create_entity();
    world.add_component_to_entity(entity_id, Step {num: 0});
  }

  {
    let entity_id = world.create_entity();
    world
      .add_component_to_entity(entity_id, Namable {name: "Alice"})
      .add_component_to_entity(entity_id, Position {x: 0.0, y: 0.0})
      .add_component_to_entity(entity_id, Velocity {x: 1.0, y: 2.0});
  }

  {
    let entity_id = world.create_entity();
    world
      .add_component_to_entity(entity_id, Namable {name: "Bob"})
      .add_component_to_entity(entity_id, Position {x: 0.0, y: 0.0})
      .add_component_to_entity(entity_id, Velocity {x: -2.0, y: 1.0});
  }

  {
    // Unmovable
    let entity_id = world.create_entity();
    world
      .add_component_to_entity(entity_id, Namable {name: "Rock"})
      .add_component_to_entity(entity_id, Position {x: 0.0, y: 0.0});
  }

  // Add Systems to world
  world
    .add_system(PrintStepSystem {})
    .add_system(MoveSystem {})
    .add_system(PrintPositionSystem {});

  // Run
  for _i in 0..3 {
    world.update();
  }
}

/*
 * Result:
 * Step 1
 * Alice is at (1, 2)
 * Bob is at (-2, 1)
 * Rock is at (0, 0)
 * Step 2
 * Alice is at (2, 4)
 * Bob is at (-4, 2)
 * Rock is at (0, 0)
 * Step 3
 * Alice is at (3, 6)
 * Bob is at (-6, 3)
 * Rock is at (0, 0)
 */

如何导入

该库在crates.io发布。将以下行添加到您的Rust项目的Cargo.toml中。

[dependencies]
ecs_rust = "0.0.4"

在您的Rust代码中添加以下行以导入库。

use ecs_rust::world::World;
use ecs_rust::entity_manager::{EntityIdAccessor, EntityManager};
use ecs_rust::component::Component;
use ecs_rust::system::System;

如何本地构建库

$ git clone https://github.com/takahirox/ecs-rust.git
$ cd ecs-rust
$ cargo build

如何本地运行桌面示例

$ cd ecs-rust
$ cargo run --example example_name

如何本地运行Web示例

先决条件

  • 安装wasm-bindgen客户端
  • 使用$ rustup target add wasm32-unknown-unknown安装Rust wasm32-unknown-unknown目标
  • 使用http-server安装$ npm install -g http-server,或其他本地服务器
$ cd ecs-rust/web
$ bash build_examples.sh
$ http-server . -p 8080 -c-1
# Access https://127.0.0.1:8080/examples/index.html on your web browser

如何运行测试

待定

无运行时依赖