Hi,
Ive gotten this far, but its not very elegant, nor compact...plus I think I made a mistake in my logic somewhere because it doesnt work 100% like Im envisioning.
Basically what Im doing is I have 3 guide booklets that are gui's. The zorders are initialized as:
QuickGuide_VC.ZOrder = 10;
QuickGuide_PC.ZOrder = 9;
QuickGuide_SS.ZOrder = 8;
I dont want the ZOrders to ever be anything different than 8, 9 or 10. The highest is always 10, the lowest, always 8.
When you click on any of the gui's, that gui's zorder will become 10, the others, depending on their order amongst themselves, will get their zorder knocked down so that its logical.
Here is what I have, where could my error be (Ive attempted debugging without luck so far) and more important, how to make this shorter/more elegant?
if (mouse.IsButtonDown(eMouseLeft) && gQuickGuidesGUI.Visible)
{
if (overGUI == gQuickGuidePC)
{
iPCz = gQuickGuidePC.ZOrder;
if (iPCz != 10)
{
gQuickGuidePC.ZOrder = 10;
iVCz = gQuickGuideVC.ZOrder;
iSSz = gQuickGuideSS.ZOrder;
if (iVCz == 10) gQuickGuideVC.ZOrder = 9;
else if (iVCz == 9) gQuickGuideVC.ZOrder = 8;
else if (iSSz == 10) gQuickGuideSS.ZOrder = 9;
else if (iSSz == 9) gQuickGuideSS.ZOrder = 8;
}
}
else if (overGUI == gQuickGuideVC)
{
iVCz = gQuickGuideVC.ZOrder;
if (iVCz != 10)
{
gQuickGuideVC.ZOrder = 10;
iPCz = gQuickGuidePC.ZOrder;
iSSz = gQuickGuideSS.ZOrder;
if (iPCz == 10) gQuickGuidePC.ZOrder = 9;
else if (iPCz == 9) gQuickGuidePC.ZOrder = 8;
else if (iSSz == 10) gQuickGuideSS.ZOrder = 9;
else if (iSSz == 9) gQuickGuideSS.ZOrder = 8;
}
}
else if (overGUI == gQuickGuideSS)
{
iSSz = gQuickGuideSS.ZOrder;
if (iSSz != 10)
{
gQuickGuideSS.ZOrder = 10;
iVCz = gQuickGuideVC.ZOrder;
iPCz = gQuickGuidePC.ZOrder;
if (iVCz == 10) gQuickGuideVC.ZOrder = 9;
else if (iVCz == 9) gQuickGuideVC.ZOrder = 8;
else if (iPCz == 10) gQuickGuidePC.ZOrder = 9;
else if (iPCz == 9) gQuickGuidePC.ZOrder = 8;
}
}
}
It seems to me that it would be as simple in this case as doing something like:
function gQuickGuide_OnClick(GUI *theGui, MouseButton button)
{
// link the OnClick functions for gQuickGuideVC, gQuickGuidePC, and gQuickGuideSS to this function
if (theGui.ZOrder == 10) return; // there's no need to process any of this if we clicked on the highest GUI already
GUI *otherGUIs[2]; // we'll use this to make it a bit more generically simple :)
// here..we figure out which GUIs belong where
// theGui: VC PC SS
// otherGUIs[0]: PC VC VC
// otherGUIs[1]: SS SS PC
// NOTE: This isn't always an accurate depiction of the current z-orders, but it will always let us put each GUI into its own slot
if (theGui != gQuickGuideVC) otherGUIs[0] = gQuickGuideVC;
else otherGUIs[0] = gQuickGuidePC;
if (theGui != gQuickGuideSS) otherGUIs[1] = gQuickGuideSS;
else otherGUIs[1] = gQuickGuidePC;
theGui.ZOrder = 10; // this GUI's z-order is always set to 10
if (otherGUIs[0].ZOrder != 8) otherGUIs[0].ZOrder--; // these GUIs' z-orders may have been 8, 9, or 10..
if (otherGUIs[1].ZOrder != 8) otherGUIs[1].ZOrder--; // ..as long as they weren't already 8 then they need to be bumped down one
}
The reason I created the array was simply to avoid having to duplicate code, which I think you were asking about, right?
Instead of constantly checking for clicks in repeatedly_execute (which I'm guessing is where you had the code), just set the OnClick event (in the Events pane in the editor for each of the GUIs) to this function (copy and paste the function name). AGS is already checking for these clicks anyway (even if you don't have an OnClick function linked, it still fires on_event for eEventGUIMouseDown and eEventGUIMouseUp), so there's no need for you to be checking for it yourself. ;)
Wow, so much better...how do you guys do it? Ill be able to apply your solution to many other things now aswell, since you explained it too.
Works perfect sir!
Thanx :)
It took me a second to wrap my head around the array mapping (in simplest terms), which is why I made that table. As I noted, that table doesn't necessarily reflect the z-order of the GUIs, but it ensures that each of them gets used.
That along with the information you provided is, as you say, "how [I] do it". :=
You're welcome.
Say if I wanted to add a 4th booklet (or even 5th), is this how I would process the zorders? What is the "formula" you used exactly? I cant figure it out (you're smart).
GUI *otherGUIs[3];
if (theGui != gQuickGuideVC) otherGUIs[0] = gQuickGuideVC;
else otherGUIs[0] = gQuickGuidePC;
if (theGui != gQuickGuideSS) otherGUIs[1] = gQuickGuideSS;
else otherGUIs[1] = gQuickGuidePC;
if (theGui != gQuickGuideFM) otherGUIs[2] = gQuickGuideFM;
else otherGUIs[2] = gQuickGuidePC;
theGui.ZOrder = 10; // this GUI's z-order is always set to 10
if (otherGUIs[0].ZOrder != 7) otherGUIs[0].ZOrder--; // these GUIs' z-orders may have been 7,8, 9, or 10..
if (otherGUIs[1].ZOrder != 7) otherGUIs[1].ZOrder--; //...as long as they weren't already 7 then they need to be bumped down one
if (otherGUIs[2].ZOrder != 7) otherGUIs[2].ZOrder--;
Retrospectively that solution was somewhat specialized whereas a more generic solution would have been more flexible and you probably wouldn't have to be asking about it again now..
if (theGui.ZOrder == 10) return;
GUI *sortedGUIs[SORTED_GUI_COUNT];
// just add each of the GUIs to this array
sortedGUIs[0] = gQuickGuideVC;
sortedGUIs[1] = gQuickGuidePC;
sortedGUIs[2] = gQuickGuideSS;
sortedGUIs[3] = gQuickGuideFM;
int maxZOrder = 10; // highest Z order of any of the GUIs
int minZOrder = (maxZOrder - (SORTED_GUI_COUNT - 1)); // lowest Z order of any of the GUIs
int i = 0;
while (i < SORTED_GUI_COUNT)
{
if (sortedGUIs[i] == theGui) sortedGUIs[i].ZOrder = maxZOrder; // if this was the GUI that the user clicked on, bring it to the top
else if (sortedGUIs[i].ZOrder != minZOrder) sortedGUIs[i].ZOrder--; // if this was not already the lowest GUI, then it should be shifted down
i++;
}
Wow, well this is great, thank-you sir :)
Hey Monkey,
I've run into a little problem with testing today:
1) There are 4 guides (a,b,c,d).
2) The present Z order is like this (from farthest to closest to screen): d,c,b,a
When I click on c or d, alternating the clicks, after a few clicks, the zOrder of guide "a" will pop-up above guide "b" without clicking on it.
Is it something with the logic or perhaps somehow I need to test out if my clicks are going through some guides?
**Short vid on youtube: http://www.youtube.com/watch?v=YUYn4rtxBHI (http://www.youtube.com/watch?v=YUYn4rtxBHI)**
Ugh, I overlooked something when I wrote that last bit of code..if you have more than 3 GUIs then..it won't work right! 8)
if (theGui.ZOrder == 10) return;
GUI *sortedGUIs[SORTED_GUI_COUNT];
// just add each of the GUIs to this array
sortedGUIs[0] = gQuickGuideVC;
sortedGUIs[1] = gQuickGuidePC;
sortedGUIs[2] = gQuickGuideSS;
sortedGUIs[3] = gQuickGuideFM;
int maxZOrder = 10; // highest Z order of any of the GUIs
int curZOrder = theGui.ZOrder; // we need the current Z order..only the GUIs above this level need to be shifted down
int i = 0;
while (i < SORTED_GUI_COUNT)
{
if (sortedGUIs[i] == theGui) sortedGUIs[i].ZOrder = maxZOrder; // if this was the GUI that the user clicked on, bring it to the top
else if (sortedGUIs[i].ZOrder > curZOrder) sortedGUIs[i].ZOrder--; // if this GUI was above the clicked GUI previously, it needs to be shifted down
i++;
}
I still haven't tested this (at all!! :=), but it should..probably work now.