What's the best approach for displaying a grid based inventory?

Hi,

I’m wondering if anybody could suggest their best approach to display a grid base inventory.

Before you post, let me refine the question. I’m specifically wondering if there’s a better way than making 50 different item pictures one by one and having an array of the Picture class instanciated and placed in the GUI node. Is there a way to crop pictures? At least I figure making only one big texture for all the items together would be a beginning. If not, how would one go about achieving this without using 1 million pictures?

inb4 Ben, why don’t you make a dozen billboard geometries that share the same material and feed them a huge texture then attach them to the camera node… wonder if there’s a better approach, of course.

The goal would be something similar to this but we could still see the game happening in the background:

Thx! :smiley:

[java]

//Somewhere in your init of your appstate
LayoutHelper.reset();
Element lastEl = whateverElement; // << to use as a starting offset or null

int index = 0;
for (int y = 0; y < 4; y++) {
LayoutHelper.resetX();
if (lastEl != null)
LayoutHelper.advanceY(lastEl, true);
for (int x = 0; x < 4; x++) {
ButtonAdapter e = createInventorySlot(index, LayoutHelper.position());
someWindowOrSomething.addChild(e);
lastEl = e;
LayoutHelper.advanceX(lastEl, true);
index++;
}
}

// Only need to define this once
private ButtonAdapter createInventorySlot(int index, Vector2f position) {
ButtonAdapter slot = new ButtonAdapter(
screen,
“InvSlot” + index,
position,
LayoutHelper.dimensions(iconSize,iconSize),
screen.getStyle(“CheckBox”).getVector4f(“resizeBorders”),
screen.getStyle(“CheckBox”).getString(“defaultImg”)
) {
@Override
public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
// Your inventory handling code or a call to it with (this) as a param
}
};
slot.clearAltImages();
slot.setEffectZOrder(false);
slot.setScaleEW(false);
slot.setScaleNS(false);
slot.setDocking(Element.Docking.SW);
slot.setButtonIcon(iconSize, iconSize, iconDefault);
slot.getButtonIcon().setTextureAtlasImage(objIcons, iconDefault); // << use the icon to display they held item
slot.setIsDragDropDropElement(true);
return slot;
}
[/java]

1 Like

It would likely be helpful to store the ButtonAdapters in a list you can iterate through… one that doesn’t rely on Element.getElementsAsMap

[java]
List<ButtonAdapter> slots = new ArrayList();

// Add slots.add(e); to the loop above
[/java]

Oh… as for the icons. I set up icon texture for like types.

weapon_1hs_01.png
weapon_2hs_01.png
armor_plate_helms_01.png
armor_chain_boots_01.png

Set up some type of enum and a texture manager:

[java]
Texture tex = textureManager().getIconSet(IconSet.CHAIN_BOOTS_01);
[/java]

And also add your atlas info as retrievables from the textureManager:

[java]
String atlasCoords = textureManager.getRegion(Regions.CB_005);
[/java]

Then all you have to do is store:

[java]
IconSet iconSet = IconsSet.CHAIN_BOOTS_01;
Regions texRegion = Regions.CB_005;
[/java]

with the item… retrieve the associated data and alter the element to display it.

Maybe you should mention that this is using your TonegodGUI…?

I would (for a low level approach)

Create an textureatlas containing all symbols/icons(images (+ null image)

Then create a quadgrid directly as a mesh manually
Then change for each quad contained the texture coordinates to match one symbol of the atlas.
-> Pass in the texture coordinate x the item you target
-> Pass in y a inidcator wich edge of the quad I am, so the vertex shader has more information(see below)

Eg atlas is 5x5
-> I want item 13 -> texcoord.x of vertextbuffer = 13

Shader then:
2 = 13/5;
row 2 (aka 3 starting at 0)
13%5= 3
-> column 3

calculated uv coordinates passed to the frag shader.
U =
1/53 left vertex
1/5
3+1 right vertex
V =
1/52 upper
1/5
3 lower.

Pro: constant cost, the rendering does only change speed with amount of items, but not with used amount. Great if you use Diablo style fixed size inventories. Or the common MMO varant aka X pages of y*z items. As you can just resuse the same grid for every page then.
The only dynamic part would be the x coordinate of the texturecoordinate vertexbuffer, everything else would not change.

Contra: Requires custom shader to work.

1 Like
@normen said: Maybe you should mention that this is using your TonegodGUI..?

He uses the gui library… but yes! For other people, that may have been a good idea =) Sorry!

@t0neg0d said: He uses the gui library... but yes! For other people, that may have been a good idea =) Sorry!
Moved the topic to the correct forum then.

Wow, thank you Chris for taking the time to put this extensive code preview. So basically, if I installed TonegodGUI I’d be able to do all of this. I +1’ed for the effort. I’m not closed to the idea but at the moment, I’m preferably looking for a vanilla way, if there is one. What I fear the most is the number of textures shown on screen (which you seem to solve in your approach using texture atlas regions). The game still goes on at the back, so ideally it would all work with only 1 texture atlas or something similar, I don’t want to see in the stats: TEXTURES (S) 137 you know :stuck_out_tongue:

Are texture regions or something similar available in the vanilla JME3 environment? And are they doing texture switches? Maybe a shader would be more suited to account for that issue?

Thx for all inputs.

… he uses your lib eh? xD

@Empire Phoenix said: I would (for a low level approach)

Create an textureatlas containing all symbols/icons(images (+ null image)

Then create a quadgrid directly as a mesh manually
Then change for each quad contained the texture coordinates to match one symbol of the atlas.
-> Pass in the texture coordinate x the item you target
-> Pass in y a inidcator wich edge of the quad I am, so the vertex shader has more information(see below)

Eg atlas is 5x5
-> I want item 13 -> texcoord.x of vertextbuffer = 13

Shader then:
2 = 13/5;
row 2 (aka 3 starting at 0)
13%5= 3
-> column 3

calculated uv coordinates passed to the frag shader.
U =
1/53 left vertex
1/5
3+1 right vertex
V =
1/52 upper
1/5
3 lower.

Pro: constant cost, the rendering does only change speed with amount of items, but not with used amount. Great if you use Diablo style fixed size inventories. Or the common MMO varant aka X pages of y*z items. As you can just resuse the same grid for every page then.
The only dynamic part would be the x coordinate of the texturecoordinate vertexbuffer, everything else would not change.

Contra: Requires custom shader to work.

Yep. That’s roughly what I had in mind yesterday evening. In other words, it requires a shader to crop the image regions right?

Either a shader, or do on cpu, shader is faster, but more work. Depends on your inventory sizes I would say if it is worth it.

@normen said: ... he uses your lib eh? xD

Oh hell… I saw the user icon and thought it was someone else… sorry!

@.Ben. said: Wow, thank you Chris for taking the time to put this extensive code preview. So basically, if I installed TonegodGUI I'd be able to do all of this. I +1'ed for the effort. I'm not closed to the idea but at the moment, I'm preferably looking for a vanilla way, if there is one. What I fear the most is the number of textures shown on screen (which you seem to solve in your approach using texture atlas regions). The game still goes on at the back, so ideally it would all work with only 1 texture atlas or something similar, I don't want to see in the stats: TEXTURES (S) 137 you know :P

Are texture regions or something similar available in the vanilla JME3 environment? And are they doing texture switches? Maybe a shader would be more suited to account for that issue?

Thx for all inputs.

Sorry you! I honestly thought you were another user I saw the avatar… and the letter B and made an assumption. Sooooo sorry. I hope you didn’t take my response the wrong way.

@normen said: ... he uses your lib eh? xD

Would you be so kind as to move his topic back to the correct forum… soooory for the misunderstanding!

You should be ashamed of yourself for trying to help someone hahahah!! JK >.< :stuck_out_tongue: Wow, absolutely not… Why are you so sorry about it? I don’t see any problem in suggesting your own brand, I’m happy you actually took the time to explain your avenue. I might try it in the future, for this one it’s already done: I made what I wrote in the OP via a shader in less than 20 minutes. Thanks Empire Phoenix. It’s not exactly what you described because I had already a shader almost ready for this, so I reused it, but it’s quite close to what you described still, so I +1’ed you as well. Thx everybody! :smiley:

1 Like

To give some insights about grid base inventory, which I wrote a few also. Also note that I’d like to abstract out the UI interaction and the “so call” gameplay interactions as my experience to code properly and don’t make my head explode later :)).

Let say you have MxN Grid to display the inventory. If all of those Slot can be a button, which offer drag and drop operations between each other, obviously you go through 2 simple for loop to create them as in Tonegod example.

If an item can be more than 1x1 big, the problem change quite a lot. But i see it’s not what you intend to do…

About representation, let all the icons in one texture atlast is a wise choice as they usually show at once. You may later encount the same problem if you going to add a Shop to exchange with your own inventory.

A little bit more into graphic side… The inventory, and other HUD should be outstanding with the background. You may find it’s nessesary to add background color and highlight to your UI to make it attractive and more visible :))

@tonegod
One question aside concern about Element “having Texture Atlas clipped texture” or “having Texture as separated texture” in Tonegod GUI.

The situation is I want all my button icons are in the atlast but my background is a separate texture. I may display the background in desktop application but not in Android device for example.

I did read the code, but may be the old one…
What Element do is it ask for the texture atlast of the screen, or more specific is the atlast status of the Screen to decide its imagePath should be resolve as TextureCoord or a real path. This is almost the normal behavior … but… What if some element use atlast and some is not??

As I said may be I’ve read the old code but i also know for sure this little problem can be fixed easily if you have some time :))

1 Like
@atomix said: To give some insights about grid base inventory, which I wrote a few also. Also note that I'd like to abstract out the UI interaction and the "so call" gameplay interactions as my experience to code properly and don't make my head explode later :)).

Let say you have MxN Grid to display the inventory. If all of those Slot can be a button, which offer drag and drop operations between each other, obviously you go through 2 simple for loop to create them as in Tonegod example.

If an item can be more than 1x1 big, the problem change quite a lot. But i see it’s not what you intend to do…

About representation, let all the icons in one texture atlast is a wise choice as they usually show at once. You may later encount the same problem if you going to add a Shop to exchange with your own inventory.

A little bit more into graphic side… The inventory, and other HUD should be outstanding with the background. You may find it’s nessesary to add background color and highlight to your UI to make it attractive and more visible :))

@tonegod
One question aside concern about Element “having Texture Atlas clipped texture” or “having Texture as separated texture” in Tonegod GUI.

The situation is I want all my button icons are in the atlast but my background is a separate texture. I may display the background in desktop application but not in Android device for example.

I did read the code, but may be the old one…
What Element do is it ask for the texture atlast of the screen, or more specific is the atlast status of the Screen to decide its imagePath should be resolve as TextureCoord or a real path. This is almost the normal behavior … but… What if some element use atlast and some is not??

As I said may be I’ve read the old code but i also know for sure this little problem can be fixed easily if you have some time :))

The button and icon are separate and can use two separate atlases.

And +1 for abstracting out the the Game Logic from UI… I did this for all game elements as well. They were actually Serializable to make saving and network transport simple.