来自actor的libgdx触发事件调用另一个actor

时间:2017-12-04 09:12:12

标签: android libgdx event-handling

我使用Scene2D并且有两个演员。触摸MyActor1时,应触发应由MyActor2处理的事件。我已尝试了几种不同的变种,甚至来自MyActor1,但MyActor2仍未处理。完整的代码如下。

刚刚转发到屏幕的游戏类

public class MyGdxGame extends Game {
   @Override
   public void create() {
       setScreen(new MyGdxScreen());
   }
}

屏幕类(省略空方法)

public class MyGdxScreen implements Screen {

   private Stage stage;

   @Override
   public void show() {
       stage = new Stage(new ScreenViewport());
       stage.addActor(new MyActor1());
       stage.addActor(new MyActor2());
       Gdx.input.setInputProcessor(stage);
   }

   @Override
   public void render(float delta) {
       Gdx.gl.glClearColor(1, 1, 1, 1);
       Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

       stage.act(delta);
       stage.draw();
   }

   @Override
   public void dispose() {
       stage.dispose();
   }
}

第一个演员(触摸时触发自定义事件)

public class MyActor1 extends Actor {

   private Texture image;

   public MyActor1() {
       this.image = new Texture("badlogic.jpg");

       setPosition(0, 0);
       setBounds(0, 0, image.getWidth(), image.getHeight());
       setTouchable(Touchable.enabled);

       addListener(new InputListener() {
           @Override
           public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
               Gdx.app.log("touched", "First actor touched!");
               MyActor1.this.fire(new ActorTouchedListener.ActorTouchedEvent());
               MyActor1.this.getParent().fire(new ActorTouchedListener.ActorTouchedEvent());
               return true;
           }
       });
   }

   @Override
   public void draw(Batch batch, float parentAlpha) {
       batch.draw(image, 0, 0, image.getWidth(), image.getHeight());
   }
}

第二个Actor(应该处理由Actor1触发的事件)

public class MyActor2 extends Actor {

   public MyActor2() {
       addListener(new ActorTouchedListener());
   }
}

事件监听器

public class ActorTouchedListener implements EventListener {
   @Override
   public boolean handle(Event event) {
       if (event instanceof ActorTouchedEvent) {
           Gdx.app.log("fired", "Second actor got event!");
           return true;
       }
       return false;
   }

public static class ActorTouchedEvent extends Event {
     public ActorTouchedEvent() {
     }
   }
}

2 个答案:

答案 0 :(得分:0)

这两行什么都不做。

MyActor1.this.fire(new ActorTouchedListener.ActorTouchedEvent()); 
MyActor1.this.getParent().fire(new ActorTouchedListener.ActorTouchedEvent());

要从另一个Actor调用Actor,您应该创建它的实例。

public class MyActor1 extends Actor {

   private Texture image;
   private Actor actor2; // instance of MyActor2

   public MyActor1(actor2: Actor) { 
       this.image = new Texture("badlogic.jpg");
       this.actor2 = actor2;     

       setPosition(0, 0);
       setBounds(0, 0, image.getWidth(), image.getHeight());
       setTouchable(Touchable.enabled);

       addListener(new InputListener() {
           @Override
           public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
               Gdx.app.log("touched", "First actor touched!");
               actor2.fire(event);  // Here we fire event on MyActor2
               return true;
           }
       });
   }

   @Override
   public void draw(Batch batch, float parentAlpha) {
       batch.draw(image, 0, 0, image.getWidth(), image.getHeight());
   }
}

答案 1 :(得分:0)

组件间事件

LibGDX不提供嵌入式组件间事件系统,但您可以使用其他框架。例如LibGDX Autumn。您可以使用两种类型的事件:

  • text event - 通知组件有关更改某些州的信息
  • object event - 此机制将您的事件对象传递给观察者

这个框架有文档和examples,它有助于做你想做的事情

延迟演员更新

对于演员的更新目的,LibGDX有actions mechanism。在您的情况下,我建议将DelayAction附加到包含MyActor2

MyRedrawAction
DelayAction delayAction = new DelayAction();

// set wrapped action dellay (in sec.)
delayAction.setDuration(1F);
// set wrapped action. It will be invoked after 1 sec. of stage drawing
delayAction.setAction(new MyRedrawAction());

actor2.addAction(delayAction);

您可以touchDown()方法@icarumbas建议

执行此操作