I can't seem to find an answer to my problem here, though I do find related problems. First of all, I'm using libGDX v0.9.8 and scene2d.
So, what I intend to do is a scene where a bunch of Actors appear here and there dynamically and can be clicked so they dissapear. Simple concept.
I'll try to simplify my code to put it here.
These appearing actors I'm talking about are a pool of my Enemy class:
public class Enemy extends Image implements Poolable {
//...
public Enemy(Stage stage) {
super();
this.stage = stage;
//...
}
//more stuff...
}
My stage is something like this:
public class Level1 implements Screen {
private InputMultiplexer inputMultiplexer;
private Stage stage;
private final int MAX_ENEMIES = 20;
private long tickLastEnemyCreated = 0;
private Group enemyGroup;
private Pool<Enemy> enemyPool;
public Level1() {
this.stage = new Stage(ExampleMain.S_WIDTH, ExampleMain.S_HEIGHT, true) {
@Override
public boolean touchDown (int x, int y, int pointer, int button) {
System.out.println("Stage touchDown");
return super.touchDown(x, y, pointer, button);
}
};
stage.getCamera().position.set(stage.getWidth()/2, stage.getHeight()/2, 0);
enemyGroup = new Group();
enemyPool = new Pool<Enemy>(MAX_ENEMIES) {
@Override
protected Enemy newObject() {
Enemy e = new Enemy(stage);
e.addListener(new ClickListener() {
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
System.out.println("touched enemy");
//wipe enemy out if clicked
Enemy enemy = (Enemy)event.getListenerActor();
enemyGroup.removeActor(enemy);
enemyPool.free(enemy);
return true;
}
};
enemyGroup.addActor(e);
return e;
}
@Override
public Enemy obtain() {
Enemy e = super.obtain();
enemyGroup.addActor(e);
return e;
}
};
//set stage as input. multiplexer will be set as imput processor in resize function.
this.inputMultiplexer = new InputMultiplexer();
this.inputMultiplexer.addProcessor(this.stage);
}
@Override
public void resize(int width, int height) {
stage.setViewport(ExampleMain.S_WIDTH, ExampleMain.S_HEIGHT, true);
stage.getCamera().position.set(stage.getWidth()/2, stage.getHeight()/2, 0);
this.stage.clear();
//add enemy group to stage
this.stage.addActor(this.enemyGroup);
//set input
Gdx.input.setInputProcessor(this.inputMultiplexer);
}
@Override
public void render(float delta) {
//obtain enemy
if ((TimeUtils.nanoTime() - this.tickLastEnemyCreated)/1000000000 > 2f) {
this.enemyPool.obtain();
this.tickLastEnemyCreated = TimeUtils.nanoTime();
}
//update all enemies in group
SnapshotArray<Actor> enemyArray = this.enemyGroup.getChildren();
Actor[] enemies = enemyArray.begin();
for (int i = 0; i < enemyArray.size; i++) {
Enemy e = (Enemy)enemies[i];
e.refresh(delta); //emeny refresh method
if (!e.active) { //some condition to destroy it whenever, if never clicked
enemyGroup.removeActor(e);
enemyPool.free(e);
}
}
enemyArray.end();
//stage update
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act(delta);
stage.draw();
}
}
Problem: When I click anywhere on the screen, I get the "Stage touchDown" text in the console. When I click an enemy, I also get the "Stage touchDown" text in the console and nothing else happens. In this last case, I expect both "Stage touchDown" and "touched enemy" texts, as well as seeing the enemy dissappear. It seems as if the input processor can't proccess a dynamically created Image/Actor or whatever. But I guess it does and I'm doing something wrong.
Maybe you guys can give me a hint on what I might be missing.
Thanks!
UPDATE: I have just observed that if I "turn off" an overlaying parallax layer I have, it does work properly. This means that what I'm really clicking is that layer. So, my new question is: Is there a way to leave that layer in front and let underlaying Actors recieve events normally?
Thanks again.