Mizu is Entity Component System framework for Ebitengine.
Mizu is based on ento, which is made by wfranczyk.
The name is short for Mizutaki, a japenese dish, where chicken pieces and vegetables stewed in a simple stock, and eaten with dipping sauce such as ponzu.
To check all examples, visit this page.
Mizu uses Go 1.20 at the current moment.
Getting the latest version reflection API
:
go get -u github.com/sedyh/mizu
Getting the latest version generics API
:
go get -u github.com/sedyh/mizu@experimental
Import this package
import "github.com/sedyh/mizu/pkg/engine"
Define components, attributes of your game objects.
// Position for any entity, if it needs
type Pos struct {
X, Y float64 // Just a 2D point
}
// Velocity for any entity, if it needs
type Vel struct {
L, M float64 // Also, 2D point
}
// Radius for any entity, if it needs
type Rad struct {
Value float64 // Width value
}
Define entities, your game objects.
// Your game object
type Ball struct {
Pos // Ball position
Vel // Ball velocity
Rad // Ball radius
}
Define systems, your game mechanics that will work for a specific set of components.
// You can go through all entities that have a certain set of
// components specifying the requirements in the fields of the system
type Velocity struct {
*Pos // Current entity position
*Vel // Current entity velocity
}
// Apply velocity for each entity that has Pos and Vel
func (v *Velocity) Update(w engine.World) {
// If they are registered components, they will not be nil
v.Pos.X += v.Vel.L
v.Pos.Y += v.Vel.M
}
// When you need many sets of components
// in one system, you can use the views
type Render struct {}
// Render one frame
func (r *Render) Draw(w engine.World, screen *ebiten.Image) {
// But choose the right entities yourself
view := w.View(Pos{}, Rad{})
view.Each(func(entity engine.Entity) {
var pos *Pos
var rad *Rad
entity.Get(&pos, &rad)
ebitenutil.DrawRect(
screen,
pos.X-rad.Value/2, pos.Y-rad.Value/2,
rad.Value, rad.Value,
colornames.Aliceblue,
)
})
}
Define scenes, where will all this live.
type Game struct{}
// Main scene, you can use that for settings or main menu
func (g *Game) Setup(w engine.World) {
w.AddComponents(Pos{}, Vel{}, Rad{})
w.AddEntities(&Ball{Pos{0, 0}, Vel{4, 4}, Rad{10}})
w.AddSystems(&Velocity{}, &Render{})
}
Run the game.
// Provides its own ebiten.Game implementation
g := engine.NewGame(&Game{})
if err := ebiten.RunGame(g); err != nil {
log.Fatal(err)
}
Please visit our wiki for a helpful articles and best practices about Mizu.