Entities and Components
Hopefully by now you have read a little about Entities
and Components
from the ECS architecture.
Necessary imports
The Blizzard Engine comes with a default way of creating Entities
and Components
. Add the following to the top of your server.rs
file:
extern crate blizzard_engine_derive;
use blizzard_engine::ecs::{ComponentRegistry, EntityManager, World};
use blizzard_engine_derive::ComponentRegistry;
use std::collections::HashMap;
The top of your file should now look something like the following:
extern crate blizzard_engine;
extern crate blizzard_engine_derive;
use blizzard_engine::ecs::{ComponentRegistry, EntityManager, World};
use blizzard_engine_derive::ComponentRegistry;
use std::collections::HashMap;
Add Entities to your world
Adding entities to the world is very simple:
#[derive(Debug, Clone)]
struct MyWorld {
entity_manager: EntityManager,
}
impl World<Input> for MyWorld {
fn new() -> Self {
Self {
entity_manager: EntityManager::new(),
}
}
fn run_systems(&mut self, input: Input) {
// runs future systems
}
}
See the ecs
part of the Blizzard Game Engine docs to see all the methods available for adding and managing entities.
Let's add components to our World
.
Adding Components
Adding components is very easy, that's what the engine_derive
library is for, it provides a macro to generate components easily! Let's create two types of components, a Player
and a Position
:
#[derive(ComponentRegistry, Debug, Clone)]
struct PositionRegistry {
components: HashMap<u32, Position>,
}
#[derive(ComponentRegistry, Debug, Clone)]
struct PlayerRegistry {
components: HashMap<u32, usize>,
}
Our components are stored in a registry, hence the struct names end with "Registry". Components are stored inside a HashMap, the first key MUST be of type u32, since that is the UID that is associated to an Entity
when a Component
is created. The second key of the HashMap is of any type that is needed. This won't compile yet because Position
is not defined. Let's define it:
use std::ops::AddAssign;
#[derive(Debug, Clone, Copy)]
pub struct Position {
x: i32,
y: i32,
}
impl Position {
pub fn new() -> Self {
Self { x: 0, y: 0 }
}
pub fn displacement(x: i32, y: i32) -> Self {
Self { x, y }
}
}
impl AddAssign for Position {
fn add_assign(&mut self, other: Self) {
*self = Self {
x: self.x + other.x,
y: self.y + other.y,
};
}
}
Now the only thing left to do is add the component registries to the World
:
#[derive(Debug, Clone)]
struct MyWorld {
entity_manager: EntityManager,
positions: PositionRegistry,
players: PlayerRegistry,
}
Great! Let's now learn how to add Systems
in order to manipulate components.