Artemis-odb框架:规避庞大EntityManager子类的Entity实例化方案问询
拆分Artemis-odb实体创建逻辑的实用方案
嘿,我太懂你这种烦恼了——把所有实体创建逻辑塞进一个EntityManager子类里,到后期代码臃肿得像个大球,找个方法都要翻半天!针对Artemis-odb里的实体实例化拆分,我有几个实战中常用的方案,你可以按需选择:
1. 按实体类型拆分独立工厂类
这是最直观的拆分方式:给每种实体(比如工人、建筑)单独写一个工厂类,专门负责该类型实体的所有创建逻辑,依赖EntityManager完成实际的实体创建和组件添加。
举个工人实体工厂的例子:
public class WorkerFactory { private final EntityManager entityManager; // 通过构造注入EntityManager,避免硬依赖 public WorkerFactory(EntityManager entityManager) { this.entityManager = entityManager; } public Entity createMinerWorker(int x, int y) { Entity worker = entityManager.createEntity(); worker.edit() .add(new PositionComponent(x, y)) .add(new WorkerComponent(WorkerType.MINER)) .add(new HealthComponent(100)) .add(new AnimationComponent("miner_sprite")); return worker; } public Entity createFarmerWorker(int x, int y) { Entity worker = entityManager.createEntity(); worker.edit() .add(new PositionComponent(x, y)) .add(new WorkerComponent(WorkerType.FARMER)) .add(new HealthComponent(120)) .add(new AnimationComponent("farmer_sprite")); return worker; } }
建筑工厂的逻辑类似:
public class BuildingFactory { private final EntityManager entityManager; public BuildingFactory(EntityManager entityManager) { this.entityManager = entityManager; } public Entity createIronMine(int x, int y) { Entity mine = entityManager.createEntity(); mine.edit() .add(new PositionComponent(x, y)) .add(new BuildingComponent(BuildingType.IRON_MINE)) .add(new ProductionComponent(ResourceType.IRON, 5)) .add(new HealthComponent(500)); return mine; } }
使用时只需要在游戏初始化时实例化这些工厂,传入EntityManager即可:
EntityManager em = new EntityManager(); WorkerFactory workerFactory = new WorkerFactory(em); BuildingFactory buildingFactory = new BuildingFactory(em); // 创建矿工 Entity miner = workerFactory.createMinerWorker(10, 20); // 创建铁矿 Entity ironMine = buildingFactory.createIronMine(30, 40);
这种方式的核心优势是职责单一,每个工厂只聚焦一类实体,代码可读性和维护性拉满——新增实体类型只需要加新的工厂类,完全不会污染原有代码。
2. 实体原型+复制模式
如果你的同类型实体有大量重复的基础配置(比如所有矿工的初始血量、精灵都一致),可以先创建一个“原型实体”,然后通过复制原型来快速生成新实体。Artemis-odb原生支持实体复制,结合工厂管理原型会更高效:
public class EntityPrototypeFactory { private final EntityManager entityManager; private final Map<String, Entity> prototypes = new HashMap<>(); public EntityPrototypeFactory(EntityManager entityManager) { this.entityManager = entityManager; initPrototypes(); } private void initPrototypes() { // 创建矿工原型 Entity minerPrototype = entityManager.createEntity(); minerPrototype.edit() .add(new WorkerComponent(WorkerType.MINER)) .add(new HealthComponent(100)) .add(new AnimationComponent("miner_sprite")); prototypes.put("miner", minerPrototype); // 创建农民原型 Entity farmerPrototype = entityManager.createEntity(); farmerPrototype.edit() .add(new WorkerComponent(WorkerType.FARMER)) .add(new HealthComponent(120)) .add(new AnimationComponent("farmer_sprite")); prototypes.put("farmer", farmerPrototype); } public Entity createFromPrototype(String prototypeId, int x, int y) { Entity prototype = prototypes.get(prototypeId); if (prototype == null) { throw new IllegalArgumentException("Unknown prototype: " + prototypeId); } // 复制原型实体 Entity newEntity = entityManager.copy(prototype); // 覆盖位置组件(每个实体位置不同) newEntity.edit().add(new PositionComponent(x, y)); return newEntity; } }
使用示例:
EntityPrototypeFactory prototypeFactory = new EntityPrototypeFactory(em); Entity miner = prototypeFactory.createFromPrototype("miner", 10, 20);
这种方式能极大减少重复代码,修改原型就能批量更新同类型实体的基础属性,非常适合批量生成的实体。
3. 构建器模式(灵活配置场景)
如果实体的组件配置需要灵活定制(比如偶尔要创建血量更高的特殊工人),构建器模式会是绝佳选择——它允许你链式调用配置实体的各个属性,代码可读性拉满:
public class WorkerBuilder { private final EntityManager entityManager; private int x = 0; private int y = 0; private WorkerType type = WorkerType.MINER; private int health = 100; private String sprite = "default_worker"; public WorkerBuilder(EntityManager entityManager) { this.entityManager = entityManager; } public WorkerBuilder position(int x, int y) { this.x = x; this.y = y; return this; } public WorkerBuilder type(WorkerType type) { this.type = type; // 根据类型自动设置默认属性 if (type == WorkerType.FARMER) { this.health = 120; this.sprite = "farmer_sprite"; } else if (type == WorkerType.MINER) { this.health = 100; this.sprite = "miner_sprite"; } return this; } public WorkerBuilder health(int health) { this.health = health; return this; } public WorkerBuilder sprite(String sprite) { this.sprite = sprite; return this; } public Entity build() { Entity worker = entityManager.createEntity(); worker.edit() .add(new PositionComponent(x, y)) .add(new WorkerComponent(type)) .add(new HealthComponent(health)) .add(new AnimationComponent(sprite)); return worker; } }
使用时可以灵活定制:
WorkerBuilder builder = new WorkerBuilder(em); Entity superMiner = builder.position(10,20) .type(WorkerType.MINER) .health(150) // 自定义血量 .sprite("super_miner_sprite") .build();
这种方式完美解决了构造函数参数过多的问题,同时保留了配置的灵活性,适合需要个性化定制的实体场景。
内容的提问来源于stack exchange,提问作者Kerial
相关产品推荐
相关产品推荐

