I’m trying to make a hot bar like in minecraft and I’m having trouble making my block meshes line up with my image. I’ve tried lots of things and I’m stuck. I’ve created a demo app and I’ll include the code and a screenshot. It should be a quick fix but I’m banging my head against the wall at this point.
The code below involves 3 classes and my custom styles at the end. HUDDemo is the main app. It attaches a HUDAppState which extends the BaseHudState which is just a slightly modified version of HudState in the lemur project.
Any help is appreciated.
import com.chappelle.jcraft.CubesSettings;
import com.chappelle.jcraft.blocks.*;
import com.chappelle.jcraft.jme3.HUDAppState;
import com.chappelle.jcraft.world.chunk.ChunkMaterial;
import com.jme3.app.*;
import com.simsilica.lemur.GuiGlobals;
import com.simsilica.lemur.style.BaseStyles;
public class HUDDemo extends SimpleApplication
{
@Override
public void simpleInitApp()
{
//Initialize Lemur GUI
GuiGlobals.initialize(this);
BaseStyles.loadGlassStyle();
BaseStyles.loadStyleResources("com/chappelle/jcraft/jme3/ui/styles/jcraft-styles.groovy");
GuiGlobals.getInstance().getStyles().setDefaultStyle("glass");
stateManager.detach(stateManager.getState(StatsAppState.class));
Block block = Blocks.bedrock;//HACK: Need to statically reference Blocks class to initialize blocks
new CubesSettings(assetManager, new ChunkMaterial(assetManager, "Textures/FaithfulBlocks.png"));//HACK: load up CubesSettings
stateManager.attach(new HUDAppState());
}
public static void main(String[] args)
{
HUDDemo app = new HUDDemo();
app.showSettings = false;
app.start();
}
}
package com.chappelle.jcraft.jme3;
import com.chappelle.jcraft.blocks.*;
import com.chappelle.jcraft.world.chunk.ChunkMaterial;
import com.jme3.app.Application;
import com.jme3.math.*;
import com.jme3.scene.*;
import com.simsilica.lemur.*;
import com.simsilica.lemur.component.BorderLayout.Position;
import com.simsilica.lemur.component.SpringGridLayout;
import com.simsilica.lemur.core.GuiControl;
import com.simsilica.lemur.style.ElementId;
public class HUDAppState extends BaseHudState
{
private Container hotbarContainer;
public HUDAppState(){}
@Override
protected void initialize(Application app)
{
super.initialize(app);
hotbarContainer = new Container(new ElementId("hud.hotbar"));
hotbarContainer.setLayout(new SpringGridLayout(Axis.X, Axis.Y));
hotbarContainer.setPreferredSize(new Vector3f(500, 50, 0));
hotbarContainer.setInsets(new Insets3f(0, 80, 0, 80));
ChunkMaterial material = new ChunkMaterial(app.getAssetManager(), "Textures/FaithfulBlocks.png");
for(int i = 0; i < 10; i++)
{
Block block = Block.blocksList[i+1];
if(block == Blocks.door || block == Blocks.torch || block == Blocks.ladder)//these blocks don't work yet
{
block = Blocks.cactus;
}
Node node = new Node("huditem" + i);
Geometry blockItemGeometry = new Geometry("", MeshGenerator.generateIndividualMesh(block));
blockItemGeometry.rotate(new Quaternion().fromAngleAxis(toRadians(25), Vector3f.UNIT_X));
blockItemGeometry.rotate(new Quaternion().fromAngleAxis(toRadians(-45), Vector3f.UNIT_Y));
blockItemGeometry.setMaterial(material);
node.scale(20.0f);
node.attachChild(blockItemGeometry);
GuiControl control = new GuiControl(Panel.LAYER_INSETS, Panel.LAYER_BORDER, Panel.LAYER_BACKGROUND);
control.setPreferredSize(new Vector3f(50.0f, 10.0f, 10.0f));
node.addControl(control);
hotbarContainer.addChild(node);
}
getSouth().addChild(hotbarContainer, Position.Center);
}
private float toRadians(float degrees)
{
return (degrees / 180) * FastMath.PI;
}
}
package com.chappelle.jcraft.jme3;
import com.jme3.app.Application;
import com.jme3.app.state.BaseAppState;
import com.jme3.math.Vector3f;
import com.jme3.renderer.*;
import com.jme3.renderer.queue.RenderQueue.Bucket;
import com.jme3.scene.Node;
import com.simsilica.lemur.*;
import com.simsilica.lemur.component.*;
import com.simsilica.lemur.component.BorderLayout.Position;
import com.simsilica.lemur.event.MouseAppState;
import com.simsilica.lemur.input.InputMapper;
import com.simsilica.lemur.style.ElementId;
public abstract class BaseHudState extends BaseAppState
{
public static final ElementId ID_HUD = new ElementId("hud");
public static final ElementId ID_NORTH = ID_HUD.child("north");
public static final ElementId ID_SOUTH = ID_HUD.child("south");
public static final ElementId ID_EAST = ID_HUD.child("east");
public static final ElementId ID_WEST = ID_HUD.child("west");
private ViewPort view;
private Node main;
private Container container;
private Container east;
private Container west;
private Container north;
private Container south;
public BaseHudState()
{
}
public Node getRoot()
{
return main;
}
public void toggleHud()
{
setEnabled(!isEnabled());
}
public Container getEast()
{
if(east == null)
{
east = new Container(ID_EAST);
east.setLayout(new SpringGridLayout(Axis.Y, Axis.X, FillMode.None, FillMode.Even));
east.setInsets(new Insets3f(5, 5, 5, 5));
container.addChild(east, Position.East);
}
return east;
}
public Container getWest()
{
if(west == null)
{
west = new Container(ID_WEST);
west.setLayout(new SpringGridLayout(Axis.Y, Axis.X, FillMode.None, FillMode.Even));
west.setInsets(new Insets3f(5, 5, 5, 5));
container.addChild(west, Position.West);
}
return west;
}
public Container getNorth()
{
if(north == null)
{
north = new Container(ID_NORTH);
north.setLayout(new BorderLayout());
container.addChild(north, Position.North);
}
return north;
}
public Container getSouth()
{
if(south == null)
{
south = new Container(ID_SOUTH);
south.setLayout(new BorderLayout());
container.addChild(south, Position.South);
}
return south;
}
@Override
protected void initialize(Application app)
{
InputMapper inputMapper = GuiGlobals.getInstance().getInputMapper();
// inputMapper.addDelegate( MainFunctions.F_HUD, this, "toggleHud" );
Camera cam = app.getCamera().clone();
cam.setParallelProjection(true);
main = new Node("HUD");
main.setQueueBucket(Bucket.Gui);
view = app.getRenderManager().createPostView("Hud ViewPort", cam);
view.setEnabled(isEnabled());
view.setClearFlags(false, true, true);
view.attachScene(main);
// Make sure our viewport is setup properly
GuiGlobals.getInstance().setupGuiComparators(view);
// Make sure this viewport gets mouse events
getState(MouseAppState.class).addCollisionRoot(main, view);
// Setup a basic container for standard layout... for anything
// that cares to use it.
container = new Container(new BorderLayout(), ID_HUD);
container.setPreferredSize(new Vector3f(cam.getWidth(), cam.getHeight(), 0));
container.setLocalTranslation(0, cam.getHeight(), 0);
main.attachChild(container);
// Have to add an empty geometry to the HUD because JME has
// a bug in the online versions and I'd rather not go directly to
// source.
// Label temp = new Label("");
// getNorth().addChild(temp);
main.updateLogicalState(1);
main.updateGeometricState();
}
@Override
protected void cleanup(Application app)
{
InputMapper inputMapper = GuiGlobals.getInstance().getInputMapper();
// inputMapper.removeDelegate( MainFunctions.F_HUD, this, "toggleHud" );
app.getRenderManager().removePostView(view);
}
@Override
protected void onEnable()
{
view.setEnabled(true);
}
@Override
protected void onDisable()
{
view.setEnabled(false);
main.updateGeometricState();
}
@Override
public void update(float tpf)
{
main.updateLogicalState(tpf);
}
@Override
public void render(RenderManager rm)
{
main.updateGeometricState();
}
}
import com.simsilica.lemur.*
import com.simsilica.lemur.component.*
import com.jme3.material.RenderState.BlendMode
def gradient = TbtQuadBackgroundComponent.create(
texture( name:"/com/simsilica/lemur/icons/bordered-gradient.png",
generateMips:false ),
1, 1, 1, 126, 126,
1f, false )
def border = TbtQuadBackgroundComponent.create(
texture( name:"/com/simsilica/lemur/icons/border.png",
generateMips:false ),
1, 2, 2, 6, 6,
1f, false )
def hotbar = new QuadBackgroundComponent(texture( name:"/Textures/gui/hotbar.png"), 25f, 25f)
def transparent = new QuadBackgroundComponent(color(0, 0, 0, 0))
selector( "container", "glass" )
{
background = gradient.clone()
background.setColor(color(0.25, 0.5, 0.5, 0.5))
}
selector( "hud", "glass" )
{
background = transparent
}
selector( "hud", "south", "glass" )
{
background = border.clone()
}
selector("hud", "hotbar", "glass")
{
background = hotbar.clone()
}