I do it in a small package and it works

. So I was happy but only for a short time. When I try on my own project I still have the same bug : when I clicked on button, nothing happens. After some debug test I find why.
In my game I used TWL for the menu GUI. But in game I used MouseOverArea components and it look like when using StateBasedGame + TWL + MouseOverArea the input are cut by MouseOverArea even if the object is just instantiate and not used in a state that it's not used too.
All the code (one interface and three classes (one StateBasedGame and two BasicGameState)), (need an image for MouseOverArea and a TWL Theme) :
To see the problem just comment/uncomment the MouseOverArea line in MyBasicGameState2 (method init)
Code:
public interface ITWLGameState {
public Widget getRootWidget();
}
Code:
public class MyStateBasedGame extends StateBasedGame {
private static final String THEME_PATH = "resources/themes/guiTheme.xml";
private LWJGLRenderer lwjglRenderer;
private ThemeManager theme;
private GUI gui;
private TWLInputAdapter twlWrapper;
//Main
public static void main(String[] args) {
try {
AppGameContainer container = new AppGameContainer(new MyStateBasedGame());
container.setDisplayMode(800, 600, false);
container.setTargetFrameRate(100);
container.start();
} catch (SlickException e) {
e.printStackTrace();
}
}
public MyStateBasedGame() {
super("State Based Game with TWL");
}
@Override
public void initStatesList(GameContainer container) throws SlickException {
addState(new MyBasicGameState1());
addState(new MyBasicGameState2());
// save Slick's GL state while loading the theme
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
try {
lwjglRenderer = new LWJGLRenderer();
lwjglRenderer.setUseSWMouseCursors(true);
theme = ThemeManager.createThemeManager(Thread.currentThread().getContextClassLoader().getResource(THEME_PATH), lwjglRenderer);
gui = new GUI(lwjglRenderer);
twlWrapper = new TWLInputAdapter(gui, container.getInput());
container.getInput().addPrimaryListener(twlWrapper);
gui.setSize();
gui.applyTheme(theme);
} catch (LWJGLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// restore Slick's GL state
GL11.glPopAttrib();
}
}
// TWL
public void updateTWL() {
twlWrapper.update();
}
public void renderTWL() {
twlWrapper.render();
}
public void setRootPane(int id) {
gui.setRootPane(((ITWLGameState) getState(id)).getRootWidget());
}
public class TWLInputAdapter extends InputAdapter {
private final Input input;
private final GUI gui;
private int mouseDown;
private boolean ignoreMouse;
private boolean lastPressConsumed;
public TWLInputAdapter(GUI gui, Input input) {
if (gui == null) {
throw new NullPointerException("gui");
}
if (input == null) {
throw new NullPointerException("input");
}
this.gui = gui;
this.input = input;
}
@Override
public void mouseWheelMoved(int change) {
if (!ignoreMouse) {
if (gui.handleMouseWheel(change)) {
consume();
}
}
}
@Override
public void mousePressed(int button, int x, int y) {
if (mouseDown == 0) {
// only the first button down counts
lastPressConsumed = false;
}
mouseDown |= 1 << button;
if (!ignoreMouse) {
if (gui.handleMouse(x, y, button, true)) {
consume();
lastPressConsumed = true;
}
}
}
@Override
public void mouseReleased(int button, int x, int y) {
mouseDown &= ~(1 << button);
if (!ignoreMouse) {
if (gui.handleMouse(x, y, button, false)) {
consume();
}
} else if (mouseDown == 0) {
ignoreMouse = false;
}
}
@Override
public void mouseMoved(int oldX, int oldY, int newX, int newY) {
if (mouseDown != 0 && !lastPressConsumed) {
ignoreMouse = true;
gui.clearMouseState();
} else if (!ignoreMouse) {
if (gui.handleMouse(newX, newY, -1, false)) {
consume();
}
}
}
@Override
public void mouseDragged(int oldx, int oldy, int newX, int newY) {
mouseMoved(oldx, oldy, newX, newY);
}
@Override
public void keyPressed(int key, char c) {
if (gui.handleKey(key, c, true)) {
consume();
}
}
@Override
public void keyReleased(int key, char c) {
if (gui.handleKey(key, c, false)) {
consume();
}
}
@Override
public void mouseClicked(int button, int x, int y, int clickCount) {
if (!ignoreMouse && lastPressConsumed) {
consume();
}
}
private void consume() {
input.consumeEvent();
}
@Override
public void inputStarted() {
gui.updateTime();
}
@Override
public void inputEnded() {
gui.handleKeyRepeat();
}
/**
* Call this method from {@code BasicGame.update}
*
* @see BasicGame#update(org.newdawn.slick.GameContainer, int)
*/
public void update() {
gui.setSize();
gui.handleTooltips();
gui.updateTimers();
gui.invokeRunables();
gui.validateLayout();
gui.setCursor();
}
/**
* Call this method from {@code BasicGame.render}
*
* @see BasicGame#render(org.newdawn.slick.GameContainer,
* org.newdawn.slick.Graphics)
*/
public void render() {
gui.draw();
}
}
}
Code:
public class MyBasicGameState1 extends BasicGameState implements ITWLGameState {
public static final int ID = 1;
private MyStateBasedGame myGame;
private Widget rootWidget;
@Override
public int getID() {
return ID;
}
// Set root pane when enter
@Override
public void enter(GameContainer container, StateBasedGame game) throws SlickException {
super.enter(container, game);
myGame.setRootPane(getID());
}
@Override
public void init(GameContainer container, StateBasedGame sbGame) throws SlickException {
rootWidget = new Widget();
myGame = (MyStateBasedGame) sbGame;
// Add a button to test
Button button = new Button("The button of the First state");
button.addCallback(new Runnable() {
@Override
public void run() {
System.out.println("move to state 1 to state 2");
myGame.enterState(MyBasicGameState2.ID, new FadeOutTransition(), new FadeInTransition());
}
});
button.setSize(200, 20);
button.setPosition(200, 200);
rootWidget.add(button);
}
@Override
public void render(GameContainer container, StateBasedGame sbGame, Graphics g) throws SlickException {
((MyStateBasedGame) sbGame).renderTWL();
}
@Override
public void update(GameContainer container, StateBasedGame sbGame, int delta) throws SlickException {
((MyStateBasedGame) sbGame).updateTWL();
}
@Override
public Widget getRootWidget() {
return rootWidget;
}
}
Code:
public class MyBasicGameState2 extends BasicGameState implements ITWLGameState {
public static final int ID = 2;
private MyStateBasedGame myGame;
private Widget rootWidget;
@Override
public int getID() {
return ID;
}
// Set root pane when enter
@Override
public void enter(GameContainer container, StateBasedGame game) throws SlickException {
super.enter(container, game);
myGame.setRootPane(getID());
}
@Override
public void init(GameContainer container, StateBasedGame sbGame) throws SlickException {
rootWidget = new Widget();
myGame = (MyStateBasedGame) sbGame;
// Add a button to test
Button button = new Button("The button of the Second state");
button.setSize(200, 20);
button.addCallback(new Runnable() {
@Override
public void run() {
System.out.println("move to state 2 to state 1");
myGame.enterState(MyBasicGameState1.ID, new FadeOutTransition(), new FadeInTransition());
}
});
// Change the postion compare to the first state
button.setPosition(200, 400);
rootWidget.add(button);
//THIS LINE WILL CUT EVENT !!!
MouseOverArea test = new MouseOverArea(container, new Image("resources/images/fow.png"), 200, 200);
}
@Override
public void render(GameContainer container, StateBasedGame sbGame, Graphics g) throws SlickException {
((MyStateBasedGame) sbGame).renderTWL();
}
@Override
public void update(GameContainer container, StateBasedGame sbGame, int delta) throws SlickException {
((MyStateBasedGame) sbGame).updateTWL();
}
@Override
public Widget getRootWidget() {
return rootWidget;
}
}
I need to used both TWL and MouseOverArea in my project so any help is welcome
