在libGDX中点击一个Actor

10
我在我的游戏中有一个叠加层,由一个显示屏的图像和一组“按钮”组成。

截图:

Screenshot showing UI components

我的Screen只有一个Stage。该Stage具有一组Group对象,我将其视为层。第一组具有背景,中间的组具有游戏元素,而最前面的组具有屏幕叠加层。

叠加层由一个Image(屏幕本身)和四个TextButton(每个角落一个)组成。

如果不考虑叠加层中的图像位于所有内容之前,则会很好地工作。即使图像是透明的,它仍然在触摸事件到达游戏层之前拦截它们。

所以我的问题是:如何使叠加层中的图像忽略所有触摸事件,以便游戏层将其获取并可以实际进行游戏?

我尝试了一个想法,但我不确定这是否是正确的方法:我尝试将图像创建为自定义Actor,始终将其高度/宽度设置为0,但仍然(通过重载draw()方法)在整个屏幕上绘制图像。这非常有效,除了事实是该图像以某种原因在较低层中绘制。

截图:https://dl.dropboxusercontent.com/u/1545094/Screen2.png

在此截图中,我打开了一个指示消息框,将其添加到游戏层之一(组6)。请注意,叠加层中的所有按钮(即组7)都在消息框前面,但屏幕框架(自定义Actor)以某种方式在消息框后面绘制。为什么会这样呢?

注意:如果我采用完全相同的情况,并将我的自定义演员更改为常规Image,则所有内容都将正确绘制,但是,如上所述,我将无法单击较低层中的任何内容。

以下是我的自定义Actor,如果有人能看懂的话:

public class ClickThroughImage extends Actor {

    BaseDrawable d;

    public NonexistingImage(BaseDrawable d){
        this.d = d;
        setSize(0, 0);
    }

    @Override
    public void draw(SpriteBatch batch, float parentAlpha) {
        d.draw(batch, 0, 0, 1024, 768); //Yes, I tried swapping these two lines. 
        super.draw(batch, parentAlpha); //It had no effect.
    }
}
3个回答

24

除了其他方法之外,你还可以调用:

setTouchable(Touchable.disabled);

被记录为:

演员或其子元素将不会接收到任何触摸输入事件。

该方法在Actor类中。


1
这应该是被接受的答案。其他答案可能会很有信息量,但这个更好地、更简单地解决了提问者的问题。 - Fran Marzoa

6

使用InputMultiplexer。 InputMultiplexer类允许您在多个输入处理器之间共享用户输入。 创建扩展InputProcessor的自己的类,并将其与Stage一起放入InputMultiplexer中。 这样,您可以以自定义方式响应用户输入,并仍然能够使用您的舞台。

    InputMultiplexer multiplexer = new InputMultiplexer();
    Array<InputProcessor> processors = new Array<InputProcessor>();
    MyInputProcessor myInputProcessor = new MyInputProcessor(); 
    processors.add(myInputProcessor);
    processors.add(stage);
    this.multiplex.setProcessors(processors);

    //...
    //and in your show method in your Screen class
    Gdx.input.setInputProcessor(this.multiplex);

此外,请确保从Actor.hit返回null。这应该导致演员不响应任何用户交互。
这是我在我的游戏中解决这个问题的方法。

3
谢谢!实际上,从我的“Image”的Actor.hit返回null解决了问题,不需要使用InputMultiplexer。 - Erlend D.
啊,太好了。如果你有任何其他问题,请随时联系我。我在LIBGDX方面有一年多的经验。这个框架非常庞大,一些更技术性的问题在文档或教程中没有得到充分解决,这是我的个人看法。 - William Morrison
1
谢谢,如果我遇到其他令我困惑的问题,我可能会向您寻求帮助。;) - Erlend D.
1
将Actor.hit的返回值设置为null仍然有效。只是提供信息而已。感谢您持久的回答! - Nibb

1

是的,Pool 是正确的。

只需将 touchable 设置为 disabled。

引擎是否将所有演员设置为可触摸存在疑问,因为在我的大多数游戏中,大多数演员都是不可触摸的,并且用户可以/应该与其中的少数元素进行交互。因此,我总是创建一个名为“nonTouchableActor”的基类,从中派生出所有不应对点击/轻敲作出反应的演员,并在构造函数中设置touchable(disabled)。这样你就不必再考虑它了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接