Golang新实体组件系统Ark的发布与应用
Golang新实体组件系统Ark的发布与应用 Ark 是一个基于原型的 Go 语言实体组件系统。
它建立在构建我的第一个 Go ECS —— Arche 时所获得的经验之上。
特性
- 为性能而设计并高度优化。
- 文档完善、类型安全的 API 以及全面的用户指南。
- 将实体关系作为一等特性。
- 用于批量操作的快速批处理。
- 没有系统。只有查询。使用你自己的结构(或工具)。
- 世界序列化与反序列化(通过 ark-serde)。
目标
在构建我的第一个 Go ECS —— Arche 时,我学到了很多,是时候重新开始了。与 Arche 相比,Ark 的主要目标是:
- 更好地支持实体关系。
- 围绕通用、类型安全的 API 构建。
- 使其比 Arche(甚至)更快。
- 通过更好地规划特性,使内部结构更加清晰。
经过 3 周的开发,所有这些目标都已实现。就初始计划而言,Ark 现在功能已经完备。
非常感谢您的反馈,特别是关于 API 和用户指南的反馈!
更多关于Golang新实体组件系统Ark的发布与应用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang新实体组件系统Ark的发布与应用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Ark 看起来是一个很有潜力的 ECS 实现,特别是它强调类型安全和性能。以下是一个简单的示例,展示如何定义组件、创建实体并进行查询:
package main
import (
"fmt"
"github.com/mlange-42/ark"
)
// 定义位置组件
type Position struct {
X, Y float64
}
// 定义速度组件
type Velocity struct {
X, Y float64
}
func main() {
// 创建世界
world := ark.NewWorld()
// 注册组件类型
posType := ark.RegisterComponent[Position]()
velType := ark.RegisterComponent[Velocity]()
// 创建实体并添加组件
entity := world.NewEntity()
world.Add(entity, posType, &Position{X: 0, Y: 0})
world.Add(entity, velType, &Velocity{X: 1, Y: 1})
// 查询所有同时拥有位置和速度组件的实体
query := world.Query(ark.All(posType, velType))
for query.Next() {
pos := query.Get(posType).(*Position)
vel := query.Get(velType).(*Velocity)
// 更新位置
pos.X += vel.X
pos.Y += vel.Y
fmt.Printf("实体位置: (%.2f, %.2f)\n", pos.X, pos.Y)
}
}
对于实体关系的支持,Ark 提供了 Relation 类型:
// 定义关系组件
type Parent struct {
ark.Relation
}
func main() {
world := ark.NewWorld()
parentType := ark.RegisterComponent[Parent]()
posType := ark.RegisterComponent[Position]()
// 创建父实体
parent := world.NewEntity()
world.Add(parent, posType, &Position{X: 10, Y: 10})
// 创建子实体并建立关系
child := world.NewEntity()
world.Add(child, posType, &Position{X: 0, Y: 0})
world.Add(child, parentType, &Parent{Target: parent})
// 查询所有有父关系的实体
query := world.Query(ark.All(posType, parentType))
for query.Next() {
pos := query.Get(posType).(*Position)
rel := query.Get(parentType).(*Parent)
// 获取父实体的位置
parentPos := world.Get(rel.Target, posType).(*Position)
fmt.Printf("子实体位置: (%.2f, %.2f), 父实体位置: (%.2f, %.2f)\n",
pos.X, pos.Y, parentPos.X, parentPos.Y)
}
}
批量操作可以通过 Batch 实现:
// 批量创建实体
batch := world.Batch(ark.All(posType, velType))
entities := make([]ark.Entity, 100)
for i := 0; i < 100; i++ {
entity := batch.NewEntity()
world.Add(entity, posType, &Position{X: float64(i), Y: float64(i)})
world.Add(entity, velType, &Velocity{X: 0.5, Y: 0.5})
entities[i] = entity
}
batch.Commit()
这些示例展示了 Ark 的核心功能。类型安全的 API 确实让代码更加清晰,关系作为一等公民的特性也很实用。性能优化在批量操作时应该会有明显体现。

