I’m trying to make a skin/model choosing dialog for the player.
A sketch of what I’m thinking:
What I’m getting:
Not everything (Ex owned/cost) is implemented, you probably get the general idea.
My Entire MainMenu class (ABSOLUTE MESS)
package com.indigoa.game.crushed.state;
import com.indigoa.game.crushed.GameLogic;
import com.indigoa.game.crushed.Main;
import static com.indigoa.game.crushed.Main.gl;
import com.indigoa.game.crushed.UsernameGenerator;
import com.indigoa.game.crushed.Variables;
import com.indigoa.game.crushed.skin.PlayerSkin;
import com.jme3.app.Application;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.font.BitmapText;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.input.event.MouseMotionEvent;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.material.RenderState;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Quad;
import com.simsilica.lemur.Button;
import com.simsilica.lemur.Command;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.GuiGlobals;
import com.simsilica.lemur.Label;
import com.simsilica.lemur.Panel;
import com.simsilica.lemur.TextField;
import com.simsilica.lemur.component.IconComponent;
import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.core.GuiControl;
import com.simsilica.lemur.event.MouseListener;
import com.simsilica.lemur.style.Attributes;
import com.simsilica.lemur.style.BaseStyles;
import java.awt.event.MouseEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.event.MouseInputListener;
/**
*
* @author mccra
*/
public class MainMenu extends AbstractAppState {
Geometry title, darken;
Spatial coinMDL;
Container lemur, smenu, name, sm;
Button play, coins;
float ttpScale = 1;
boolean ttpDir = false, triggered = false, settingsOpen = false;
TextField nameBlank;
@Override
public void initialize(AppStateManager stateManager, Application app) {
super.initialize(stateManager, app);
Main main = (Main) app;
title = new Geometry("title", new Quad(Main.settings_.getWidth() / 2, (Main.settings_.getWidth() / 2) / 7));
Material mat = new Material(Main.assets, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setTexture("ColorMap", Main.assets.loadTexture("Textures/Title.png"));
mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
title.setMaterial(mat);
title.setLocalTranslation((Main.settings_.getWidth() / 4), (Main.settings_.getHeight() / 2) + (Main.settings_.getHeight() / 5), 0);
Main.guiNode_.attachChild(title);
darken = new Geometry("darken", new Quad(Main.settings_.getWidth(), Main.settings_.getHeight()));
mat = new Material(Main.assets, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f));
mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
darken.setMaterial(mat);
darken.setLocalTranslation(0, 0, -1);
Main.guiNode_.attachChild(darken);
gl.player.killed = 0;
gl.destroy();
gl.genCrushers(10);
gl.genNPCs(20);
gl.setupPlayer();
gl.attatchChildrenToNode(Main.rootNode_);
//gl.update();
GuiGlobals.initialize(Main.instance);
//GuiGlobals.getInstance().setCursorEventsEnabled(true, true);
QuadBackgroundComponent bg;
Attributes a;
a = GuiGlobals.getInstance().getStyles().getSelector(TextField.ELEMENT_ID, GuiGlobals.getInstance().getStyles().getDefaultStyle());
bg = new QuadBackgroundComponent(new ColorRGBA(0, 0, 0, 0.5f));
a.set("background", bg);
play = new Button("");
IconComponent icon = new IconComponent("Textures/start.png");
icon.setIconSize(new Vector2f(Main.settings_.getWidth() / 6, Main.settings_.getWidth() / 6));
play.setIcon(icon);
play.setLocalTranslation(Main.settings_.getWidth() / 3 + Main.settings_.getWidth() / 12, Main.settings_.getHeight() / 3, 0);
play.addClickCommands((Button source) -> {
if (triggered) return;
triggered = true;
Running.killAll = false;
Main.stateManager_.attach(new Running());
Main.stateManager_.detach(MainMenu.this);
});
Main.guiNode_.attachChild(play);
//GuiGlobals.getInstance().getStyles().setDefaultStyle("glass");
lemur = new Container();
Main.guiNode_.attachChild(lemur);
lemur.setLocalTranslation(0, Main.settings_.getHeight(), 0);
Button settings = lemur.addChild(new Button(""));
icon = new IconComponent("Textures/gear.png");
icon.setIconSize(new Vector2f(Main.settings_.getWidth() / 15, Main.settings_.getWidth() / 15));
settings.setIcon(icon);
if (Variables.instance.hasAds()) {
Button ads = lemur.addChild(new Button(""));
icon = new IconComponent("Textures/noads.png");
icon.setIconSize(new Vector2f(Main.settings_.getWidth() / 15, Main.settings_.getWidth() / 15));
ads.setIcon(icon);
ads.addClickCommands((Button source) -> {
Variables.instance.buyNoAds();
});
}
//GuiGlobals.getInstance().getStyles().setDefaultStyle("glass");
smenu = new Container();
//Main.guiNode_.attachChild(smenu);
smenu.setLocalTranslation(0, Main.settings_.getHeight() - Main.settings_.getWidth() / 15, 0);
Button lgm = smenu.addChild(new Button((Variables.instance.fastmode() ? "High" : "Low") + " Graphics Mode"));
lgm.setFontSize(Main.settings_.getWidth() / 32);
lgm.addClickCommands((Button source) -> {
if (Variables.instance.fastmode()) {
Variables.instance.setFastmode(false);
Main.instance.reload();
} else {
Variables.instance.setFastmode(true);
Main.instance.reload();
}
lgm.setText((Variables.instance.fastmode() ? "High" : "Low") + " Graphics Mode");
});
settings.addClickCommands((Button source) -> {
System.out.println("settingsOpen: " + settingsOpen);
if (settingsOpen) {
settingsOpen = false;
Main.guiNode_.detachChild(smenu);
} else {
settingsOpen = true;
Main.guiNode_.attachChild(smenu);
}
});
Button reload = smenu.addChild(new Button("Quick Reload"));
reload.setFontSize(Main.settings_.getWidth() / 32);
reload.addClickCommands((Button source) -> {
Main.instance.reload();
});
coins = new Button(String.valueOf(Variables.instance.getCoins()));
coins.setFontSize(Main.settings_.getWidth() / 32);
coinMDL = Main.assets.loadModel("Models/coin_tri.j3o");
coinMDL.addLight(new DirectionalLight(new Vector3f(-0.6f, -0.6f, -0.6f)));
DirectionalLight light = new DirectionalLight(new Vector3f(0.1f, -1f, -0.2f));
//light = new AmbientLight();
coinMDL.addLight(light);
coinMDL.addLight(new DirectionalLight(new Vector3f(0.1f, -1f, -0.45f)));
coinMDL.addLight(new DirectionalLight(new Vector3f(0.5f, -0.5f, 0.45f)));
coinMDL.setLocalScale(Main.settings_.getWidth() / 30);
coinMDL.setLocalTranslation(Main.settings_.getWidth() / 30, (Main.settings_.getHeight() / 3) * 2, 0);
// mat = new Material(Main.assets, "Common/MatDefs/Misc/Unshaded.j3md");
// mat.setColor("Color", new ColorRGBA(0.8f, 0.5f, 0, 1));
// coinMDL.setMaterial(mat);
coinMDL.rotate(0, 70 * FastMath.DEG_TO_RAD, 0);
coins.setLocalTranslation(Main.settings_.getWidth() / 30 * 2, (Main.settings_.getHeight() / 3) * 2 + Main.settings_.getWidth() / 30, 0);
coins.addClickCommands((Button source) -> {
Variables.instance.buyCoins();
});
Main.guiNode_.attachChild(coins);
Main.guiNode_.attachChild(coinMDL);
name = new Container();
Main.guiNode_.attachChild(name);
Label l = new Label(" Username ");
l.setFontSize(Main.settings_.getWidth() / 24);
name.addChild(l);
nameBlank = name.addChild(new TextField(Variables.instance.getUsername()));
nameBlank.setFontSize(Main.settings_.getWidth() / 24);
nameBlank.setSingleLine(true);
nameBlank.addMouseListener(new MouseListener() {
@Override
public void mouseButtonEvent(MouseButtonEvent event, Spatial target, Spatial capture) {
System.out.println(event + " " + event.getButtonIndex() + " " + event.isReleased());
if (event.getButtonIndex() == MouseInput.BUTTON_LEFT && event.isReleased())Variables.instance.openKeyboard(nameBlank, () -> {Variables.instance.setUsername(nameBlank.getText());});
}
@Override
public void mouseEntered(MouseMotionEvent event, Spatial target, Spatial capture) {}
@Override
public void mouseExited(MouseMotionEvent event, Spatial target, Spatial capture) {}
@Override
public void mouseMoved(MouseMotionEvent event, Spatial target, Spatial capture) {}
});
name.setLocalTranslation(0, Main.settings_.getHeight() / 2, 0);
Button skins = name.addChild(new Button("Skins"));
skins.setFontSize(Main.settings_.getWidth() / 24);
skins.addClickCommands((Button source) -> {
skinMenu();
});
sm = new Container();
sm.setSize(new Vector3f(Main.settings_.getWidth(), Main.settings_.getHeight(), 0));
sm.setLocalTranslation(0, Main.settings_.getHeight(), ttpScale);
Running.killAll = true;
}
public void skinMenu() {
sm.clearChildren();
//Back button/coins
Button back = sm.addChild(new Button("Back"), 0, 0);
back.addClickCommands((Button source) -> {
closeSkinMenu();
});
//Button back = p.addChild(new Button("Back"), 0, 0);
coins.setLocalTranslation(Main.settings_.getWidth() / 30 * 2, (Main.settings_.getHeight() / 3) * 2 + Main.settings_.getWidth() / 6 + Main.settings_.getWidth() / 30, 0);
coinMDL.setLocalTranslation(Main.settings_.getWidth() / 30, (Main.settings_.getHeight() / 3) * 2 + Main.settings_.getWidth() / 6, 0);
//Current skin
Node n = Main.gl.player.skin.getGUISkin();
n.setLocalScale(Main.settings_.getHeight() / 3);
//n.setLocalTranslation(Main.settings_.getWidth() / 2, Main.settings_.getHeight() / 3, 0);
n.getControl(GuiControl.class).setSize(new Vector3f(Main.settings_.getHeight() / 3, Main.settings_.getHeight() / 3, 0));
sm.addChild(n, 1);
//Options
Container skins = new Container();
for (String s : PlayerSkin.skins.keySet()) {
PlayerSkin skin = PlayerSkin.getSkin(s);
n = skin.getGUISkin();
n.setLocalScale(Main.settings_.getHeight() / 8);
n.getControl(GuiControl.class).setSize(new Vector3f(Main.settings_.getHeight() / 8, Main.settings_.getHeight() / 8, 0));
skins.addChild(n);
}
sm.addChild(skins);
//Detatch/attatch objects
Main.guiNode_.detachChild(title);
Main.guiNode_.detachChild(play);
//Main.guiNode_.detachChild(darken);
Main.guiNode_.detachChild(lemur);
Main.guiNode_.detachChild(smenu);
Main.guiNode_.detachChild(name);
//Main.guiNode_.detachChild(coins);
//Main.guiNode_.detachChild(coinMDL);
Main.guiNode_.attachChild(sm);
}
public void closeSkinMenu() {
Main.guiNode_.attachChild(title);
Main.guiNode_.attachChild(play);
//Main.guiNode_.attachChild(darken);
Main.guiNode_.attachChild(lemur);
Main.guiNode_.attachChild(smenu);
Main.guiNode_.attachChild(name);
coins.setLocalTranslation(Main.settings_.getWidth() / 30 * 2, (Main.settings_.getHeight() / 3) * 2 + Main.settings_.getWidth() / 30, 0);
//Main.guiNode_.attachChild(coins);
coinMDL.setLocalTranslation(Main.settings_.getWidth() / 30, (Main.settings_.getHeight() / 3) * 2, 0);
//Main.guiNode_.attachChild(coinMDL);
Main.guiNode_.detachChild(sm);
}
@Override
public void update(float tpf) {
coinMDL.rotate(0, 0.02f, 0);
while (Main.stateManager_.getState(Running.class) != null) {
Main.stateManager_.detach(Main.stateManager_.getState(Running.class));
}
while (Main.stateManager_.getState(Restart.class) != null) {
Main.stateManager_.detach(Main.stateManager_.getState(Restart.class));
}
while (Main.stateManager_.getState(YouWin.class) != null) {
Main.stateManager_.detach(Main.stateManager_.getState(YouWin.class));
}
while (Main.stateManager_.getState(MainMenu.class) != null && Main.stateManager_.getState(MainMenu.class) != this) {
Main.stateManager_.detach(Main.stateManager_.getState(MainMenu.class));
}
}
@Override
public void cleanup() {
super.cleanup();
Main.guiNode_.detachChild(title);
Main.guiNode_.detachChild(play);
Main.guiNode_.detachChild(darken);
Main.guiNode_.detachChild(lemur);
Main.guiNode_.detachChild(smenu);
Main.guiNode_.detachChild(name);
Main.guiNode_.detachChild(coins);
Main.guiNode_.detachChild(coinMDL);
}
}
This the method I think I need to worry about:
public void skinMenu() {
sm.clearChildren();
//Back button/coins
Button back = sm.addChild(new Button("Back"), 0, 0);
back.addClickCommands((Button source) -> {
closeSkinMenu();
});
//Button back = p.addChild(new Button("Back"), 0, 0);
coins.setLocalTranslation(Main.settings_.getWidth() / 30 * 2, (Main.settings_.getHeight() / 3) * 2 + Main.settings_.getWidth() / 6 + Main.settings_.getWidth() / 30, 0);
coinMDL.setLocalTranslation(Main.settings_.getWidth() / 30, (Main.settings_.getHeight() / 3) * 2 + Main.settings_.getWidth() / 6, 0);
//Current skin
Node n = Main.gl.player.skin.getGUISkin();
n.setLocalScale(Main.settings_.getHeight() / 3);
//n.setLocalTranslation(Main.settings_.getWidth() / 2, Main.settings_.getHeight() / 3, 0);
n.getControl(GuiControl.class).setSize(new Vector3f(Main.settings_.getHeight() / 3, Main.settings_.getHeight() / 3, 0));
sm.addChild(n, 1);
//Options
Container skins = new Container();
for (String s : PlayerSkin.skins.keySet()) {
PlayerSkin skin = PlayerSkin.getSkin(s);
n = skin.getGUISkin();
n.setLocalScale(Main.settings_.getHeight() / 8);
n.getControl(GuiControl.class).setSize(new Vector3f(Main.settings_.getHeight() / 8, Main.settings_.getHeight() / 8, 0));
skins.addChild(n);
}
sm.addChild(skins);
//Detatch/attatch objects
Main.guiNode_.detachChild(title);
Main.guiNode_.detachChild(play);
//Main.guiNode_.detachChild(darken);
Main.guiNode_.detachChild(lemur);
Main.guiNode_.detachChild(smenu);
Main.guiNode_.detachChild(name);
//Main.guiNode_.detachChild(coins);
//Main.guiNode_.detachChild(coinMDL);
Main.guiNode_.attachChild(sm);
}
I was thinking that
n.getControl(GuiControl.class).setSize(new Vector3f(Main.settings_.getHeight() / 3, Main.settings_.getHeight() / 3, 0));
Would set the size for the layout. What I want to do Is set the size that the layout thinks my node is, that way additional UI elements will account for the size of the first, and not display on top of each other.
Here is the PlayerSkin.getGUISkin() method:
public Node getGUISkin() {
Node n = new Node();
n.addControl(new GuiControl("skin_inventory"));
Node in = new Node();
in.attachChild(getBody()); //Abstract, different for each skin
in.attachChild(getSpear()); //Abstract, different for each skin
in.setLocalTranslation(0.8f, -0.8f, 0);
in.rotate(0, 200 * FastMath.DEG_TO_RAD, -15 * FastMath.DEG_TO_RAD);
n.attachChild(in);
return n;
}
Any help would be appreciated, thaks