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);
        }
    }
}