@react-ecs/boids
v0.0.3
Published
<h1 align="center"> <br> <a href="https://react-ecs.ldlework.com"><img src="https://i.imgur.com/Rn6yLZs.gif" alt="React ECS" width="300"></a> <br> React ECS <br> <a href="https://react-ecs.ldlework.com">react-ecs.ldlework.com</a> </h1>
Downloads
10
Maintainers
Readme
An ECS, or Entity Component System is a design pattern popular in simulations, visualizations and game-development. It eschews rich objects and complex inheritence hierarchies.
Instead:
- Entities: A simple bag of facets.
- Facets: Simple data-only objects.
- Queries: Track entities which have specific facets.
- Systems: Process the facets of entities matched by queries.
React ECS helps you build your simulations and games using this pattern, in standard React JS fashion (hooks, components, etc)
What does it look like?
First define a Facet
This facet just tracks how much its entity should spin.
// define a facet that get attached to entities
class Spinning extends Facet<Spinning> {
rotation = new Vector3(0, 0, 0);
}
Then define a System
Systems use queries to track the entities they work upon.
This system uses a query to find entities with both the ThreeView
and Spinning
facets. ThreeView
is facet provided by @react-ecs/three to visually display entities in a ThreeJS scene.
This system updates the entity's 3D rotation based on the Spinning
facet:
// define a system which processes entity facets
const SpinningSystem = () => {
// a query makes it easy to find entities the right facets
const query = useQuery((e) => e.hasAll(ThreeView, Spinning));
// systems are basically just update callbacks with priorities
return useSystem((dt: number) => {
// iterate the entities with the ThreeView and Spinning facets
query.loop([ThreeView, Spinning], (e, [view, spin]) => {
// receive typed facets for each matching entity
const transform = view.object3d; // <ThreeView> Object3D
const rotation = spin.rotation // <Spinning> facet
.clone()
.multiplyScalar(dt);
// calculate new state
const newRotation = transform.rotation.toVector3().add(rotation);
// mutate facets, state is automatically handled
transform.rotation.setFromVector3(newRotation);
});
});
};
Now put it all together
Now we can create a component to tie it all together. For more information see our documentation and examples.
export const SpinningCubeStory: FC = () => {
// declare the ECS instance
const ECS = useECS();
// drive the ECS with requestAnimationFrame hook
useAnimationFrame((_, dt) => ECS.update(dt));
return (
{/* use ECS as context provider */}
<ECS.Provider>
{/* add systems to the simulation */}
<SpinningSystem />
{/* entities are their own context provider */}
<Entity>
{/* add facets to entities */}
<Spinning rotation={new Vector3(1, 1, 1)} />
{/* use integrations like react-three-fiber */}
<ThreeView>
<Box />
</ThreeView>
</Entity>
</ECS.Provider>
);
};