How do I make an inventory with lots of "slots"?

@pspeed said: I'm just curious because I see this come up a lot... but what is it that you think you'd get that you aren't getting now? Just wondering if you know that you can already check out an SVN repository with GIT and get many of the GIT-related "benefits".

Will have to look into this. Thanks!

@t0neg0d Ah, finally I found the code that makes DragElement move. :stuck_out_tongue: When I didnā€™t yet know how it worked, I thought that maybe I could make it work like I wanted it to. But you are probably right. Will have to reconsiderā€¦ tomorrow.

Thanks for bearing with me so far!

1 Like

@t0neg0d and @ others who wanna make an inventory, I have decided what Iā€™m gonna do. :stuck_out_tongue:

Ok, new day. Now that I have all the information I thought I needed (such as how to move DragElement programatically), I have given this whole HUD thing another think. I have I have come to the conclusion: What was I thinking before? :stuck_out_tongue:

A system that works as you proposed, t0neg0d, with a slot for the mouse, and then just buttons for items/slots allows for much more separation between logic and representation. For example: The fact that, in my old way of doing things, items are DragElements is already too much logic for the HUD (heads-up displayā€”itā€™s about graphics!) system. The HUD should know nothing about the logic of the things it represents graphically. Not to mention the fact that having the DragElementā€™s drop slot be the canonical representation of where an item is, is even worse and completely backwards.

Iā€™m gonna have two namespaces (in Clojure, but you can think Java classes). One named HUD that only does graphical representation and forwards mouse events to the logic part, but translates the events from Elements/screen positions to the logical IDs of the items clicked. The other one named ItemsLogic or something that has a logical state (does not import/use any JME or tonegodgui stuff!) of the inventory, and manipulates that state given the events.

Each frame, the HUD gets the logical state as an argument, and just draws/represents what it gets, while knowing as little as possible about what it draws.

I think I know everything I need now, since like one type of Element should suffice for all slots/icons. Maybe one more for containers.

By the way, this is the greatest video/presentation about programming EVER: http://www.infoq.com/presentations/Simple-Made-Easy

Thank you again t0neg0d for all the help, and thanks for tonegodgui! :slight_smile:

@tuffe said: @t0neg0d and @ others that wanna make an inventory, I have decided what I'm gonna do. :P

Ok, new day. Now that I have all the information I thought I needed (such as how to move DragElement programatically), I have given this whole HUD thing another think. I have I have come to the conclusion: What was I thinking before? :stuck_out_tongue:

A system that works as you proposed, t0neg0d, with a slot for the mouse, and then just buttons for items/slots allows for much more separation between logic and representation. For example: The fact that, in my old way of doing things, items are DragElements is already too much logic for the HUD (heads-up displayā€”itā€™s about graphics!) system. The HUD should know nothing about the logic of the things it represents graphically. Not to mention the fact that having the DragElementā€™s drop slot be the canonical representation of where an item is, is even worse and completely backwards.

Iā€™m gonna have two namespaces (in Clojure, but you can think Java classes). One named HUD that only does graphical representation and forwards mouse events to the logic part, but translates the events from Elements/screen positions to IDs of the items clicked. The other one named ItemsLogic or something that has a logical state (does not import/use any JME or tonegodgui stuff!) of the inventory, and manipulates that state given the events.

Each frame, the HUD gets the logical state as an argument, and just draws/represents what it gets, while knowing as little as possible about what it draws.

I think I know everything I need now, since like one type of Element should suffice for all slots/icons. Maybe one more for containers.

Brilliant!

This is the approach I took and it worked out beautifully.

I (as well as most others) would agree that separating your logic from display is critical, as visuals are always subject to change completely independently of logic which is also likely to change.

@t0neg0d Quick answer! :stuck_out_tongue: I made some edits afterwards. Make sure you check out that video, itā€™s pure brilliance!

1 Like

@t0neg0d

Hi!

Seems I did not quite know everything I needed. :stuck_out_tongue:

Since I just want to translate mouse events into something that the logic part of my system can consume, something like [Logical ID of element, which button, pressed (true/false)], using the 4 different methods in tonegodguiā€™s MouseButtonListener interface is unnecessary. If I did, they would all contain very similar code. And they just handle the left and right mouse buttons. What if I want to be able to use the middle mouse button too? Also, I think it would be nicer if I didnā€™t add code for this in the Elements themselves. So, I thought Iā€™d just use regular JME input handling, with an ActionListener.

But hereā€™s the problem: I want to be able to get the Element given the coordinates. That seems to be what getEventElement, getTargetElement or getContactElement in Screen does. But they are all private. Couldnā€™t they be public? Also, what is the difference between the 3?

Btw, did you watch the video? :stuck_out_tongue:

@tuffe said: @t0neg0d

Hi!

Seems I did not quite know everything I needed. :stuck_out_tongue:

Since I just want to translate mouse events into something that the logic part of my system can consume, something like [Logical ID of element, which button, pressed (true/false)], using the 4 different methods in tonegodguiā€™s MouseButtonListener interface is unnecessary. If I did, they would all contain very similar code. And they just handle the left and right mouse buttons. What if I want to be able to use the middle mouse button too? Also, I think it would be nicer if I didnā€™t add code for this in the Elements themselves. So, I thought Iā€™d just use regular JME input handling, with an ActionListener.

But hereā€™s the problem: I want to be able to get the Element given the coordinates. That seems to be what getEventElement, getTargetElement or getContactElement in Screen does. But they are all private. Couldnā€™t they be public? Also, what is the difference between the 3?

Btw, did you watch the video? :stuck_out_tongue:

I didā€¦ I loved it!

For the mouse wheel events. Extend ButtonAdapter and implement MouseWheelListener. This will give you wheel up, down press and release methods.

Not sure I understand not using the button listeners. What do you mean by similar code? They should all contain the exact same code if the inventory system is designed properly.

I guess they could all contain the exact same code. But I donā€™t wanna have 4 places (or 6 with the mouse wheel) with the the same code in them. I just wanna have to put the code in 1 place. Putting the same code in more than 1 place is complex (as defined in the video)! :wink:

Oh, forgot to put @t0neg0d in my last post. I guess you use the email notices or something, because you always answer quickly (except for sometimes on fast replies, which you seem to miss sometimes :p).

@t0neg0d

I have thought about this some more, and I have come to think that using getEventElement or something in Screen is bad for my problem.

What I would like though, is the following: A new kind of listener, called MouseRawListener, or MouseEventListener, or something, that has one method onMouseEvent, that would trigger on ALL mouse events (except maybe move). Then I would not have to implement all 6 onMouseLeft/Right/MiddlePressed/Released. Anyone who wants to dispatch based on what kind of button is being used can use that listener instead of the others.

@tuffe said: @t0neg0d

I have thought about this some more, and I have come to think that using getEventElement or something in Screen is bad for my problem.

What I would like though, is the following: A new kind of listener, called MouseRawListener, or MouseEventListener, or something, that has one method onMouseEvent, that would trigger on ALL mouse events (except maybe move). Then I would not have to implement all 6 onMouseLeft/Right/MiddlePressed/Released. Anyone who wants to dispatch based on what kind of button is being used can use that listener instead of the others.

You mean for buttons past left, right & wheel?

You can do this already by implementing RawInputListener and adding the listener to the input manager before creating the screen.

@tuffe said: I guess they could all contain the exact same code. But I don't wanna have 4 places (or 6 with the mouse wheel) with the the same code in them. I just wanna have to put the code in 1 place. Putting the same code in more than 1 place is complex (as defined in the video)! ;)

This really depends on how you define 1 place.

A single java class is one place + code folds! This = better than a single method with a million conditional statements.

@t0neg0d said: This really depends on how you define 1 place.

A single java class is one place + code folds! This = better than a single method with a million conditional statements.

A place is one instance of the code. If I have onLeftPressed and onRightPressed with the same code in them, thatā€™s two places. And I would definitely not have a million conditionals if I just had one onMouseEvent. I wouldnā€™t even need one in my case. And of course, Iā€™m not saying you should remove the old functionality with onLeftPressed et al. Just let the user choose. :stuck_out_tongue:

@t0neg0d said: You can do this already by implementing RawInputListener and adding the listener to the input manager before creating the screen.

Sorry, I was not clear in my earlier post. What I mean is that I want my Elements to implement the new MouseEventListener, and onMouseEvent would just be called without me doing anything else. That would not work now (Iā€™m fairly sure, but might be wrong). For that to work, Screen would have to call onMouseEvent from its onMouseButtonEvent method, in the same way it currently calls onLeftPressed et al.

@t0neg0d

I donā€™t really understand what all the code in Screenā€™s onMouseButtonEvent does, but couldnā€™t one just do this:

[java]
public void onMouseButtonEvent(MouseButtonEvent evt) {
Element picked = getContactElement(evt.getX(), evt.getY()); //NEW LINE
if (picked != null && picked instanceof MouseEventListener) //NEW LINE
((MouseEventListener) picked).onMouseEvent(evt); //NEW LINE

	if (evt.isPressed()) {
		mousePressed = true;
		eventElement = getEventElement(evt.getX(), evt.getY());

[/java]

Or is there other stuff that needs to be taken care of? There shouldnā€™t be, right? Because everything IS taken care of later.

Btw, what is the difference between getTargetElement, getEventElement, and getContactElement?

@t0neg0d Why does Element need a minimum of height 10? :stuck_out_tongue:

@tuffe said: @t0neg0d

I donā€™t really understand what all the code in Screenā€™s onMouseButtonEvent does, but couldnā€™t one just do this:

[java]
public void onMouseButtonEvent(MouseButtonEvent evt) {
Element picked = getContactElement(evt.getX(), evt.getY()); //NEW LINE
if (picked != null && picked instanceof MouseEventListener) //NEW LINE
((MouseEventListener) picked).onMouseEvent(evt); //NEW LINE

	if (evt.isPressed()) {
		mousePressed = true;
		eventElement = getEventElement(evt.getX(), evt.getY());

[/java]

Or is there other stuff that needs to be taken care of? There shouldnā€™t be, right? Because everything IS taken care of later.

Btw, what is the difference between getTargetElement, getEventElement, and getContactElement?

Each of the three do something different.

One is specific to tracking multitouch events with Android
One is for events that happen that is not related to mouse button interaction (i.e. keyboard, tab navigation, mouse focus/lose focus, etc)
One is for normal mouse eventsā€¦ I believe

There is more to this, Iā€™m just not caffeinated enough to remember atm.

@tuffe said: @t0neg0d Why does Element need a minimum of height 10? :P

Not sure what this means? Are yo talking about minDimensions? If so, itā€™s just an arbitrary value.

@t0neg0d said: Not sure what this means? Are yo talking about minDimensions? If so, it's just an arbitrary value.

Yes. I made an invisible container with height 0 (or so I thought), but the min. height of 10 messed up my layout, because it wasnā€™t 0.

@tuffe said: Yes. I made an invisible container with height 0 (or so I thought), but the min. height of 10 messed up my layout, because it wasn't 0.

Can you point specifically at where this is set so I can fix this?

I thought there was a way of setting the minDimensions already. Also, I thought these were only taken into account when resizing, so if you set a height of 0 via codeā€¦ it should be a height of 0.

Anywaysā€¦ just drop me a line number where you think the problem is happening and Iā€™ll run a test here to see if I can repro the issue to get it resolved.