Here is the code, if you wish to inspect it, excuse the messiness.
public class MenuBaseAppState extends BaseAppState {
private final Node rootNode;
private final Node guiNode;
private final AppSettings settings;
private AssetManager am;
private Camera cam;
private final int w;
private final int h;//0,h is the uppper left corner.
private Application app;
private static final Logger LOGGER = Logger.getLogger(MenuBaseAppState.class.getName());
private Picture start, set, qt;
private final DefaultMouseListener startdml = new DefaultMouseListener() {
@Override
public void mouseEntered( MouseMotionEvent event, Spatial target, Spatial capture ) {
Picture p = (Picture) target;
p.setImage(am, LemurSettings.STARTO, true);//these are just references to paths stored as strings
}
@Override
public void mouseExited( MouseMotionEvent event, Spatial target, Spatial capture ) {
Picture p = (Picture) target;
p.setImage(am, LemurSettings.START, true);
}
@Override
protected void click(MouseButtonEvent event, Spatial target, Spatial capture) {
app.getStateManager().attach(new GameBaseAppState(rootNode,guiNode,settings));
}
}, setdml =
new DefaultMouseListener() {
@Override
public void mouseEntered( MouseMotionEvent event, Spatial target, Spatial capture ) {
Picture p = (Picture) target;
p.setImage(am, LemurSettings.SETTINGSO, true);
}
@Override
public void mouseExited( MouseMotionEvent event, Spatial target, Spatial capture ) {
Picture p = (Picture) target;
p.setImage(am, LemurSettings.SETTINGS, true);
}
@Override
protected void click(MouseButtonEvent event, Spatial target, Spatial capture) {
}
}, qtdml =
new DefaultMouseListener() {
@Override
public void mouseEntered( MouseMotionEvent event, Spatial target, Spatial capture ) {
Picture p = (Picture) target;
p.setImage(am, LemurSettings.QUITO, true);
}
@Override
public void mouseExited( MouseMotionEvent event, Spatial target, Spatial capture ) {
Picture p = (Picture) target;
p.setImage(am, LemurSettings.QUIT, true);
}
@Override
protected void click(MouseButtonEvent event, Spatial target, Spatial capture) {
app.stop();
System.exit(0);
}
};
public MenuBaseAppState (Node rootNode, Node guiNode, AppSettings settings) {
this.rootNode = rootNode;
this.guiNode = guiNode;
this.settings = settings;
w = settings.getWidth();
h = settings.getHeight();
}
@Override
protected void initialize(Application app) {
//It is technically safe to do all initialization and cleanup in the
//onEnable()/onDisable() methods. Choosing to use initialize() and
//cleanup() for this is a matter of performance specifics for the
//implementor.
//TODO: initialize your AppState, e.g. attach spatials to rootNode
Logger.getLogger("").setLevel(Level.SEVERE);
this.app = app;//for access by other components
this.am = app.getAssetManager();
this.cam = app.getCamera();
initMenuGui();
}
@Override
protected void cleanup(Application app) {
//TODO: clean up what you initialized in the initialize method,
//e.g. remove all spatials from rootNode
//System.out.println("Detaching Menu App State");
MouseEventControl.removeListenersFromSpatial(start, startdml);
MouseEventControl.removeListenersFromSpatial(set, setdml);
MouseEventControl.removeListenersFromSpatial(qt, qtdml);
guiNode.detachAllChildren();
}
//onEnable()/onDisable() can be used for managing things that should
//only exist while the state is enabled. Prime examples would be scene
//graph attachment or input listener attachment.
@Override
protected void onEnable() {
//Called when the state is fully enabled, ie: is attached and
//isEnabled() is true or when the setEnabled() status changes after the
//state is attached.
app.getStateManager().detach(this);
}
@Override
protected void onDisable() {
//Called when the state was previously enabled but is now disabled
//either because setEnabled(false) was called or the state is being
//cleaned up.
}
@Override
public void update(float tpf) {
//.
}
private void initMenuGui() {// Note: Lemur GUI elements grow down from the upper left corner.
Label title = new Label(Settings.TITLE + " by " + LemurSettings.AUTHOR);
guiNode.attachChild(title);
title.setLocalTranslation(6, title.getFontSize()*1.5f, 0);
Picture logo = new Picture("logo");
logo.setImage(am, LemurSettings.TITLE_LOGO, true);
float wp = w/1920f, hp = h/1080f;//resolution scaling params, so far only works on 16:9
float lw = LemurSettings.LOGO_WIDTH*wp, lh = LemurSettings.LOGO_HEIGHT*hp;
//positions center and down from the top
logo.setPosition((w/2)-(lw/2),((float) h-(lh))*0.9765f);
logo.setHeight(lh);
logo.setWidth(lw);
guiNode.attachChild(logo);
start = new Picture("start");
start.setImage(am, LemurSettings.START, true);
float wps = w/1920f, hps = h/1080f;//resolution scaling params, so far only works on 16:9
final float lws = LemurSettings.LOGO_WIDTH*wps*.5f, lhs = LemurSettings.LOGO_HEIGHT*hps*.5f;
//positions center and down from the top
start.setPosition((w/2)-(lws/2),((float) h-(lhs))*0.55f);
start.setHeight(lhs);
start.setWidth(lws);
MouseEventControl.addListenersToSpatial(start,startdml);
guiNode.attachChild(start);
set = new Picture("set");
set.setImage(am, LemurSettings.SETTINGS, true);
float wpt = w/1920f, hpt = h/1080f;//resolution scaling params, so far only works on 16:9
final float lwt = LemurSettings.LOGO_WIDTH*wpt*.5f, lht = LemurSettings.LOGO_HEIGHT*hpt*.5f;
//positions center and down from the top
set.setPosition((w/2)-(lwt/2),((float) (h-(lhs))*0.40f));
set.setHeight(lht);
set.setWidth(lwt);
MouseEventControl.addListenersToSpatial(set,setdml);
guiNode.attachChild(set);
qt = new Picture("qt");
qt.setImage(am, LemurSettings.QUIT, true);
float wpq = w/1920f, hpq = h/1080f;//resolution scaling params, so far only works on 16:9
final float lwq = LemurSettings.LOGO_WIDTH*wpq*.5f, lhq = LemurSettings.LOGO_HEIGHT*hpq*.5f;
//positions center and down from the top
qt.setPosition((w/2)-(lwq/2),((float) (h-(lhs))*0.25f));
qt.setHeight(lhq);
qt.setWidth(lwq);
MouseEventControl.addListenersToSpatial(qt,qtdml);
guiNode.attachChild(qt);
}