【问题标题】:scene2d: how to fire(event) and handle at scene/root?场景2d:如何在场景/根处触发(事件)和处理?
【发布时间】:2014-05-07 03:59:48
【问题描述】:

我正在尝试将 touchDown 和 touchUp 事件从演员对象升级到我的 applicationListener 类。为此,我调用了 fire(event);在我的 Actor 的 InputListener 中

this.addListener(new InputListener(){
        public boolean touchDown(InputEvent event, float x, float y, int pointer, int buttons){
            Gdx.app.log("Example", "touch started at (" + x + ", " + y + ")");
            fire(event);
            return true;
        }
        public void touchUp(InputEvent event, float x, float y, int pointer, int buttons){
            Gdx.app.log("Example", "touch ended at (" + x + ", " + y + ")");
        }
});

为了在我的 ApplicationListener 类(包含演员的舞台)中处理事件,我在舞台上添加了一个 InputListener

        Gdx.input.setInputProcessor(stage);
        stage.addListener(new InputListener(){
            public boolean touchDown(InputEvent event, float x, float y, int pointer, int buttons){
                Gdx.app.log("FIRE!!!", "I CAUGHT A FIRED EVENT!");
                event.stop();
                return true;
            }
            public void touchUp(InputEvent event, float x, float y, int pointer, int buttons){
                Gdx.app.log("FIRE!!!", "the fired event even touchupped.");
                }
        });

但是,当我触摸我的演员时,我会收到 StackOverflowError 以及来自多个 InputListener 的大量异常(我假设事件没有正确停止并传播到我场景中的所有演员)。我在这里错过了什么?

此外,在触发事件后,我无法再将 event.getTarget()(它是一个 Actor)投射到我的 Actor-Subclass 中,如果我在 ActorSubclass 本身中执行此操作就可以了。这意味着以下代码在 ApplicationListener 中使用时会产生错误,但在 MyActor 类中有效:

MyActor actor = (MyActor)event.getTarget();

由于目标实际上是一个 MyActor 对象,我如何才能不仅以 Actor 的身份访问它,而且以 MyActor 的身份访问它?

【问题讨论】:

    标签: java android libgdx scene2d


    【解决方案1】:

    正如@chase 所说,您正在递归调用 fire(even) 方法,因为您只能设置 1 个 InputProcessor(您的 stage),因此始终使用相同的方法接收事件。
    你应该改用InputMultiplexer

    1. Stage 和您的ApplicationListener 作为InputProcessor 添加到InputMultiplexer
    2. 通过调用Gdx.input.setInputProcessor(multiplexer);InputMulitplexer 设置为InputProcessor

    然后InputMultiplexer 会将事件发送给第一个InputProcessor,如果它返回 false,它会将事件发送给下一个。
    因此,在您的 Stage 中,您只需要返回 false。
    但我不明白如果您不希望它处理输入,为什么要将 Stage 添加为 InputProcessor...
    无论如何,在scene2d 中,您不需要在舞台上添加InputProcessor,因为它已经有了一个。 Actor 也有 boolean touchDown(float x, float y, int pointer) 和其他有用的方法。
    一个有用的链接:Scene2D wiki article

    【讨论】:

    • 非常感谢 - 我不知道事件会在没有 fire(event) 方法的情况下自动传播给父母!我刚刚删除了它,一切都像我想要的那样工作。但是,你还能给我一个工作火(事件)实现的例子吗?我想我很快就会需要它,但仍然不太明白如何停止此方法的递归调用。只是在我的 inputProcessor 中返回 false 似乎并没有减少它。即使在调用 event.stop() 之后,事件似乎也会传播给其他参与者。
    • 返回值仅用于InputMultiplexer 了解事件是否已被处理或是否应交给下一个处理器。例如,您有一个由WASD 控制的Player1 和一个由ArrowKeys 控制的Player2。如果按下了WASD,则播放器 1 的 keyPressed 方法返回 true。如果它返回 false,则将 keyevent 传递给Player2
    【解决方案2】:

    此时你不是只是通过每次处理事件时重新触发事件来进行递归调用吗?

    为什么不直接从你的监听器返回 false?

    【讨论】:

      猜你喜欢
      • 2023-02-02
      • 1970-01-01
      • 2012-02-28
      • 1970-01-01
      • 2015-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-27
      相关资源
      最近更新 更多