Layered Picking with Mouse issues.

Blitz3D Forums/Blitz3D Beginners Area/Layered Picking with Mouse issues.

Omnicode(Posted 2013) [#1]
Hello, I have an issue I hope could be solved. I have successfully coded a full-purpose inventory system using types, Basically the type represents an array of all slots. each slot displays data based on its image value etc. creating the illusion of an item being there to the user though its just simple munipulation of the slot_image, which is stored in a global AnimatedImage of the inventory. However, my issue is when trying to access a specific slot upon mousehit(1) based on its x,y (rectsoverlap function): it is either delayed by half of a second then registers or requires multi-clicking (spamming) to actually register. I realize it may just be an issue of how im accessing the slots, but id like to know how to access a specific type without switching it from the top of the "stack", the bottom or just moving it from its position in que of each type-list. So if anyone can offer any advice id gladly listen. my fps is not a factor, the inventory system runs fluently, it works fine with the Mousedown(1) but it updates too fast to effectively place objects one-by-one. Contact me here or by email. Thanks.


Omnicode(Posted 2013) [#2]
Here's the function that runs the main inventory.


I've already tinkered around trying to fix the issue with it so if there's any be-nine factors don't judge.

Also, disregard any spell stuff. Here's how the inventory is laid out.
-Bag
-Slots in bags
-Slot handling

-Access Bag called "inventory"
Items all have a dignified string assigning them certain properties.
"_25500" : MISC. can go in any slot besides equipment.
"_25501.." : is Sword,PickAxe,Axe,Shovel

Examples:
"Mystical Logs018_25500"
"Wooden Sword019_25501"
"name of item$|Imageid#|type$"

Just further clarification.


Kryzon(Posted 2013) [#3]
I suggest you rewrite it; That's certainly what I'd do if I had this amount of code and didn't know where the bug might be.

And also, separate the rendering part from the logic part. It doesn't matter if you're going to have to run through an all-items loop twice (one for logic, one for rendering). It makes the code that much clear, and demands from you a more organized way of dealing with data. There's no price in that.

Function Run_Slots()
;Only logic\update code.
End Function

Function Render_Slots()
;Only render\drawing code.
End Function

EDIT: I also think all these assignment blocks such as...

Sel\Name$=S\Status$
Sel\S_item=S\img_id
Sel\id=S\id
Sel\Amount=S\Amount
Sel\Stored_4=S\Durability#
Sel\Durability#=S\Durability#
Sel\Status$="Full"
S\Status$="Empty"
Task$="Moving"

...should be converted to a single function call. That is, something like SetSelect(Sel.slot, S.slot).
You know from which object you're retrieving data and to which you're outputting it, so you can spare all these lines with a single one for the sake of clearness\privacy:

SetSelect( Sel, S )
Task$ = "Moving"


MCP(Posted 2013) [#4]
I think it's highly likely your repeated use of MouseHit(),MouseX(),MouseY() within your function's For...Next loop that's giving you problems. These functions should only be Read from ONCE per frame (especially MouseHit) which is why response is laggy and you're having to spam your mouse buttons. See blitz docs... MouseHit. It is Blitz's Flip() command that is actually responsible for updating mouse and keyboard events via Windows PeekMessage function so the above is most likely the cause.

Suggested fix:

Create some global variables and read any mouse states and other required input ONCE inside your program's main loop.

Either reference the global variables directly from your Run_SLots function or pass them over as function parameters.


Omnicode(Posted 2013) [#5]
Thank you both, I read both of your responses and I hope to combine. That bit of info about flip being the point in which mousehit actually updates is a complete break through for me.
Here's just a pic to give some imagery.



Btw. Mis-communication on my part when I said layered I meant this as a metaphor for the issue. Basically what I had meant was it seemed like (from what I could tell as I beta test my game constantly) the first slot could be selected and registered faster, the last slot was almost impossible so on and so forth so i built this idea in my head that was rather false, sorry. I do believe the claim of the multitude of mouse checks is the primary issue and should indeed be handled by yet another set of globals. I just wanted to optimize everything before I release anything so the claim of compiling into a function for variable calls is genius thank you for that bit. I hope to repost my fixed version quite soon. Also, if you wish to keep updated with progress, I have a worklog that I will use to chart its dev.
Thanks for your time.

Also, I'm not really a beginner to blitz3d. Just needed some input. As none of my friends are code suave.


Kryzon(Posted 2013) [#6]
It is Blitz's Flip() command that is actually responsible for updating mouse and keyboard events via Windows PeekMessage function so the above is most likely the cause.

I agree that storing the keyboard\mouse state once per frame is the best approach, but are you sure about this Flip thing?
The MouseHit() sample code doesn't make use of Flip, and still reports the amount of clicks with success.


MCP(Posted 2013) [#7]
I assume you mean this example from the blitz3d docs...
; MouseHit Example

; Set up the timer
current=MilliSecs()
Print "Press left mouse button a bunch of times for five seconds..."

; Wait 5 seconds
While MilliSecs() < current+5000
Wend

; Print the results
Print "Pressed left button " + MouseHit(1) + " times."

The reason the above example works without Flip() is because it compiles to a stock console application where internal events and outputs are handled differently.
When using Graphics3D() as intended for games blitz3d actually compiles a Windows application and sets up a Direct3d interface. Output is directed to the backbuffer and Flip() is required to swap the backbuffer with the frontbuffer as you'd expect. Windows messaging is also handled by the Flip command via the PeekMessage loop described in my original post to keep Windows happy and update the Blitz event system.


Kryzon(Posted 2013) [#8]
Try the following (it uses Graphics3D):
Graphics3D 800,600,0,2 ;Windowed or fullscreen give the same result.

current=MilliSecs()
Print "Press left mouse button a bunch of times for five seconds..."

; Wait 5 seconds
While MilliSecs() < current+5000
Wend

; Print the results
Print "Pressed left button " + MouseHit(1) + " times."
WaitKey()
End 
It still reports the hits for me, even though it makes no use of Flip. It must poll the keyboard\mouse by use of an internal timer or something else - maybe Yasha knows.


MCP(Posted 2013) [#9]
The only thing I can think of there is that mouse events are being fed through Blitz's winproc() procedure and mousehit is actually being updated through that so yes by the time your code does query mousehit it will contain the correct number of hits. A tool similar to Winspy++ should answer that.
As a side note blitz3d could also insert default message processing in the absence of flip() or that maybe something that the system handles in the absence of getmessage,peek message in an app. That's something I'll have to look into. I still stand by my original claim though as I've done a lot of 'low level' work extending blitz3d in the past.


Omnicode(Posted 2013) [#10]
Hello again, Im proud to announce I successfully fixed the issue :D

What I basically did was completely replace the use of my mousehits within any function and instead ran them all on a Global function named: Mouse_Checks() used to check for mousehits(1-2) and downs(1-2): works faster than ever! Thank you guys for your help, it inspired me to continue on and crack such a mind-blogging issue i've had since the creation of the inventory system. :D

Ill edit in a video if i can to show the speed and optimization shortly!
Old Method:
https://www.youtube.com/watch?v=ncrR5cFdddY

New Method:
https://www.youtube.com/watch?v=p8VQL0qwXHE


MCP(Posted 2013) [#11]
Congrats. That's a big improvement :)


Omnicode(Posted 2013) [#12]
Thanks :D


RemiD(Posted 2013) [#13]
Hello Omnicode,

I just wanted to say that i like how your project is progressing, i hope you will manage to finish it or at least to finish a demo.

I like the renders with these simple graphics, it reminds me of Daggerfall and Morrowind. :)

I wish you the best for the next steps.


Omnicode(Posted 2013) [#14]
Thanks! it means more than you know.
I do as well, if you wish to follow my progress just check out my work-logs. Ill be sure to post a new update after every 2-3days. Right now im currently re-working all Ai within my game as it was rather retro and dull.


Omnicode(Posted 2013) [#15]
This prior coding of the inventory has become obsolete, I've since replaced the inventory system with a far faster, and efficient system that can provide more with less.
Features: Stack-Splitting, Dragging, Use-To-Use Item recipes, Tools, Handles multiple bags for in-game banking or something like that.

Last Inventory was 430 Lines.
New Inventory is 260 Lines.