Java libgdx(ashleyframeworkecs)-与另一个系统对话的正确方式是什么?
Java libgdx(ashleyframeworkecs)-与另一个系统对话的正确方式是什么?,java,libgdx,box2d,Java,Libgdx,Box2d,系统至系统 目前我正在使用ashley框架开发CharacterSystem,GunSystem,BulletSystem。我的问题是,我不知道这是否是与其他系统交谈的正确方式 我的CharacterSystem方法onProcessEntity当触发字符攻击时,我使用getEngine().getSystem(GunSystem.class).trigger(true),在GunSystem中我有一个方法生成项目符号的实体。而Bullet系统则在摄像机外处理身体的释放 子问题使用ECS框架创建
系统
至系统
目前我正在使用ashley框架开发CharacterSystem
,GunSystem
,BulletSystem
。我的问题是,我不知道这是否是与其他系统
交谈的正确方式
我的CharacterSystem
方法onProcessEntity
当触发字符攻击时,我使用getEngine().getSystem(GunSystem.class).trigger(true)
,在GunSystem
中我有一个方法生成项目符号的实体。而Bullet系统
则在摄像机外处理身体的释放
子问题使用ECS框架创建Bullet
类
的正确方法是什么?我从未将Ashley用作ECS,但通常系统
不应相互通信
原因:当系统
进行通信时,它们不会相互独立。独立的系统
允许您自由添加和删除它们,而无需担心代码中断。当一个重要的系统
丢失时,游戏逻辑可能会中断
有一个创建项目符号实体的工厂
(类)。然后在每个系统中使用工厂
,它可以构建新的bullet实体。我经常在游戏中使用Ashley ECS,在最近的一个项目()中,我遇到了类似的情况。我的方法可能不是标准的,它可能会在不同的项目设置中出现问题,但是使用事件队列对我来说是一个很好的解决方案
本质上,您有一个enum
(在我的例子中是GameEvent
),它处理所有需要传递的不同事件,比如PLAYER\u DIED
,LAUNCH\u PLAYER
等等。我使用Ashley的signals
接口创建了一个简单的事件队列存储,系统可以在每次滴答声时轮询这些事件。详情如下:
public class EventQueue implements Listener<GameEvent> {
private PriorityQueue<GameEvent> eventQueue;
public EventQueue() {
eventQueue = new PriorityQueue<GameEvent>();
}
public GameEvent[] getEvents() {
GameEvent[] events = eventQueue.toArray(new GameEvent[0]);
eventQueue.clear();
return events;
}
public GameEvent poll() {
return eventQueue.poll();
}
@Override
public void receive(Signal<GameEvent> signal, GameEvent event) {
eventQueue.add(event);
}
}
希望这是有意义的,也请随意阅读我的项目代码以了解更多示例用法。我正在使用libgdx,您建议ECS框架与libgdx一起使用什么?Ashley或artemis odb。不知道其他ECS,更进一步说,您甚至不能存储特殊类的事件实例,以便将参数传递给事件吗?
public class LaserSystem extends IteratingSystem implements Disposable, ContactListener {
...
private Signal<GameEvent> gameEventSignal;
private EventQueue eventQueue;
public LaserSystem(Signal<GameEvent> gameEventSignal) {
super(Family.all(LaserComponent.class).get(), Constants.SYSTEM_PRIORITIES.LASER);
this.gameEventSignal = gameEventSignal;
eventQueue = new EventQueue();
gameEventSignal.add(eventQueue);
}
...
@Override
public void beginContact(Contact contact) {
....
LaserComponent laserComponent = laserMapper.get(laser);
laserComponent.updateLaser = true;
if (other.getComponent(PlayerComponent.class) != null) {
gameEventSignal.dispatch(GameEvent.LASER_COLLISION);
}
}
}