I’m using scene2d for my on-screen controls. I have 3 buttons and each one has it’s own listener which sets the entities current action on touchUp
and touchDown
events. However when I hold one button and then press another, the button which is held no longer triggers the touchDown event until I release it and press it again. This leads me to believe that scene2d widgets or maybe InputListener
doesn’t by default support multi touch. Am I right, and can I enable it somehow, or do I have to ditch scene2d?
Here’s my current code(it might contain syntax errors since I’ve converted this from Kotlin to make it easier to understand for those who don’t use Kotlin).
public class UiInputSystem extends EntitySystem {
private ComponentMapper<InputComponent> inputComponentComponentMapper;
private ComponentMapper<ActionComponent> actionComponentComponentMapper;
private UiSystem uiSystem;
private final Array<Entity> entities = new Array<Entity>(1);
UiInputSystem() {
super(Aspect.all(InputComponent,class, ActionComponent.class));
}
@Override
protected void initialize() {
uiSystem.buttons.get(Input.UI_BUTTON_LEFT.name).addListener(new InputListener() {
@Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
for(entity : entities) { process(entity, null); }
}
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button){
for(entity : entities) { process(entity, Input.UI_BUTTON_LEFT); }
return true;
}
})
uiSystem.buttons.get(Input.UI_BUTTON_RIGHT.name).addListener(new InputListener() {
@Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
for(entity : entities) { process(entity, null); }
}
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button){
for(entity : entities) { process(entity, Input.UI_BUTTON_RIGHT); }
return true;
}
})
uiSystem.buttons.get(Input.UI_BUTTON_JUMP.name).addListener(new InputListener() {
@Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
for(entity : entities) { process(entity, null); }
}
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button){
for(entity : entities) { process(entity, Input.UI_BUTTON_JUMP); }
return true;
}
})
}
private void process(Entity entity, Input input) {
InputComponent inputComponent = inputComponentComponentMapper.get(entity);
ActionComponent actionComponent = actionComponentComponentMapper.get(entity);
actionComponent.currentAction = inputComponent.inputActions.get(input) != null ? inputComponent.inputActions.get(input) : Action.DEFAULT;
}
@Override
public void inserted(Entity e) {
entities.add(e);
}
@Override
public void removed(Entity e) {
entities.removeValue(e, true);
}
@Override
protected void processSystem() {}
}
uiSystem.buttons
is a map of buttons which are initialized and added to the stage in the uiSystem
. In the uiSystem
the buttons only have a position, name and image associated to them.
UPDATE: I noticed that if I set the return value of touchDown
on the jump button listener to return false then pressing jump doesn’t override/stop triggering the left/right buttons but then my character won’t stop jumping until i release the held left/right button.