Stacking issues
Blitz3D Forums/Blitz3D Beginners Area/Stacking issues
| ||
First I want to thank Soja, Perturbatio and Wolron for their help. It got me pretty far down the road. Now I have a nagging issue with image "counter" stacking. I have counters moving all over the board and sometimes they stack up in one "32x32pixelsquare" 5 deep. As I mouse click each counter I cannot figure out how to control the stacking order so I can choose which counter to pick. here is the following brief example of a larger problem: Any takers out there. I have been struggling with this one for days and now I've had it! |
| ||
You could add a field that holds the height. When a counter is added to a square you do a check to count how many others are already on it and then add 1 and store it as the height. Then when you click on a square the first one to be picked will be the one with the highest height (LIFO = last in first out). Hope that helps. |
| ||
you could have a 3 dimensional array (x,y,z) for the board and simply add the counter into the first available slot in the z-dimension and when you move a counter, it will be the one in the highest index of the z dimension. |
| ||
Sunteam, I like your idea. You said "do a check to count how many others are already on it and then add 1 and store it as the heights" The thing is I am using a type: counter and a type: square. Infact was already on your track but could not pass the final heights in type:sq to all the type:counters in that square. Using the example below can you give me a code example of what you mean? Note: As you can see I use "act" variables for the "inst" instances to process (2) types, one type within the other. It has to be this way for the game! I loop through the whole thing four times to put four counters into the sq. Also I need to close the actives to process the other data! |
| ||
Errrm ok, that code doesn't make much sense to me as I can't see how that works. For example you have a While without a condition, this immediately throws an error at me?! Also you have height fields in both. So my questions at the moment would be: 1. how does the mouse interaction work? (is it click->drag->drop or click->click to drop?) 2. why are you using the mouse x/y coords with an 'equal to' check of the counter position? Are all the counters 1x1 in dimension? A couple of other things to note, you don't have any 'End Type' statements, this throws errors up! Also you don't have a 'Next' for your embedded 'For' statement?! Having said all this, let's see if I can show you an example of the method I was describing. I would work on the basis of using functions to handle these as Types can be accessed anywhere in the program and it makes for neater programming :) I'll presume that counters are placed on the squares to a maximum height of 4 counters on a square, and that the last counter placed on the square is always the first selected when the mouse if clicked on it. Also as your not moving the squares around (I presume only the counters move), I will remove the square type as it is not required, i.e. it is represented but not necessary to track. Type counter Field sqx ;x square location Field sqy ;y square location Field cheight ; height on square End Type ; FUNCTION: MoveCounter ; ; Pass the FROM square x and y and the TO square x and y ; ; Returns true if successful or false if the square is full (4 counters) ; Function MoveCounter(fromsqx,fromsqy,tosqx,tosqy) ;cf1-cf4 temp var holds pointers to any found counters on the from square Local cf1.counter,cf2.counter,cf3.counter,cf4.counter ;ct1-ct4 temp var holds pointers to any found counters on the to square Local ct1.counter,ct2.counter,ct3.counter,ct4.counter ;ctm is the pointer to the counter that is moving Local ctm.counter ;c.counter is a temp var used for the loops only Local c.counter ;loop through counters to find those on the from square and work out the counter that is moving For c.counter=Each counter ;if the current counter in the loop is on our from square... If c\sqx=fromsqx And c\sqy=fromsqy Then ;determine the height and place it in the relevant cf? var Select c\cheight Case 1 cf1=c Case 2 cf2=c Case 3 cf3=c Case 4 cf4=c End Select EndIf Next ;work out the topmost counter on the from square and place a pointer in ctm.counter If cf4<>Null Then ctm=cf4 ElseIf cf3<>Null Then ctm=cf3 ElseIf cf2<>Null Then ctm=cf2 ElseIf cf1<>Null Then ctm=cf1 EndIf ;loop through counters to find those on the to square For c.counter=Each counter ;if the current counter in the loop is on our to square... If c\sqx=tosqx And c\sqy=tosqy Then ;determine the height and place it in the relevant ct? var Select c\cheight Case 1 ct1=c Case 2 ct2=c Case 3 ct3=c Case 4 ct4=c End Select EndIf Next ;work out the topmost counter on the to square and update the counter that is moving to be the topmost ;NB: if there are already 4 counters on the square then the counter to move can't be moved! If ct1=Null Then ctm\sqx=tosqx ctm\sqy=tosqy ctm\cheight=1 ElseIf ct2=Null Then ctm\sqx=tosqx ctm\sqy=tosqy ctm\cheight=2 ElseIf ct3=Null Then ctm\sqx=tosqx ctm\sqy=tosqy ctm\cheight=3 ElseIf ct4=Null Then ctm\sqx=tosqx ctm\sqy=tosqy ctm\cheight=4 Else ;already 4 on square so return false Return False EndIf ;if we get to here then the counter was successfully moved so we return true Return True End Function *phew that took a while :) I haven't tested it as I obviously don't have anything to test it with but I think the logic should work ok :) Let me know if you have any questions or can better explain how your game is intending to use this code/data. |
| ||
Thanks so much for the hard worked reply. I will look it over carefully, then get back to you. By the way the code I showed you was a chopped shortcut hack job of the real code (That actually works quite well) so alot of stuff was left out. Again thanks for all the effort!!!! |
| ||
No problem, I did kinda guess the code was incomplete, the problem is that it was sooo incomplete it was very difficult to understand how it was being implemented. A little more next time please :) |
| ||
Ok I ran into the same problem. I cant pass data back from cf# to ctm as in your example (If cf4<>Null Then ctm=cf4 etc..) The ctm (actBG in my case) is null. I know you want me to close the loop after ( Select c\cheight Case 1 cf1=c etc...) but my shortened code sample below shows that it can't be done without hosing the program. Note: program works fully as it is now but without stack ordering! I translated your code to mine and found what i was trying to do in the instance of the type, you where doing with multible variables of the type, KOOL! Now if I can only get it to work. I hope you can help me on this, thanks for everything so far!!!!! |
| ||
Right, this is not making a lot of sense to me. Why: I don't understand why your now holding source and destination x,y's in the type, it's not necessary??! ..and you certainly don't need activex,y in there?? do you? Please bear in mind that every instance of a type takes up the same space which is defined by the fields, so if you have 10 fields and you have 100 types in the list, each of those 100 types will have those 10 fields, whether you use em or not. The reason I used vars is because they were not needed in the type, in fact they were only needed once per iteration of the checking loop they were used in, so using vars makes all the sense! stackorder = height?? You whole mousehit loop isn't making much sense to me, actbg will always be null because even if you get to a situation where you can set actbg=instbg, because it is in a loop, on the next iteration it will set actbg to null again?? why? The ONLY time it won't be null is if the last bg in the type list happens to match your criteria for setting actbg=instbg. I am trying to understand but it's always difficult reading someone else's code, so it's not a dig just one of those learny curve things :D |
| ||
Please read the comments in my code. ActBG will not always be Null because as a "variable of a type" if you dont declare the var Null its still holds the instance you have in it. If when processing a condition and var finds the match in one of the instances then var takes on that instance not the last instance in the type. The use of the different XY's is for the conditions in my functions like my Final Undo, Draws, Moves etc and for checking the process altogether with Writeout files. The write out files will show me with the different xys how my functions handles or didnt handle the activeXY data. The Mouse loop is as I said in the notes. It passes through once to pick up the counter then passes through again to put it down. The first pass has its conditions and the second pass has its. This program is a variation on Soja "template" which was an advanced version of Perturbatio's counter controller program. I am extremely pleased with its heartyness so far. I do not want to rewrite this program so any solution that does I wont consider. I dont have the time or desire to rewrite this from scratch, atleast not now. I did find one thing. While trying to do everything at once, I forgot the basic tracking of "from" squares. I also found its resolution of the problem by using a modified version of my Final Undo because it performs flawlessly. It performs after ActBG is turned off and that was my problem in the first place, that I could not control the instances after I turned of the actBG. I hope that clarified the issue. I may also be able to solve the stacking issue with the instbg\Stackorder. I have to track a Defender stack and an Agressor stack and all in the same square so thereby being in the same instance, I don't want to track it in the Counters Type at least not yet, It again will mean major rework. and redoing all my .data streams. For now I am still resolving the "from" square issue I won't get to the stack issue for a while. When I finish my "from" square solution I may have the answer and if not I will look into your "multiple var of a type" solution. If you can still make any sense of this then I will appreciate any other input otherwise, Thanks for all your help. |
| ||
I think my brain is now dribbling... nope didn't understand much of that so all I can do is wish you luck with it all :) |