Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: Knox on Wed 02/03/2011 19:23:32

Title: Gui you click on amongst 2 others gets ZOrder placed above the others
Post by: Knox on Wed 02/03/2011 19:23:32
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;      
     }      
   }
 }
Title: Re: The 1 Gui you click on amongst 2 others gets its ZOrder placed above the others
Post by: monkey0506 on Wed 02/03/2011 20:01:40
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. ;)
Title: Re: Gui you click on amongst 2 others gets ZOrder placed above the others **SOLVED**
Post by: Knox on Wed 02/03/2011 21:02:54
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 :)
Title: Re: Gui you click on amongst 2 others gets ZOrder placed above the others **SOLVED**
Post by: monkey0506 on Wed 02/03/2011 22:12:41
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.
Title: Re: Gui you click on amongst 2 others gets ZOrder placed above the others
Post by: Knox on Thu 07/04/2011 16:09:08
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--;
Title: Re: Gui you click on amongst 2 others gets ZOrder placed above the others
Post by: monkey0506 on Thu 07/04/2011 18:03:19
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++;
 }
Title: Re: Gui you click on amongst 2 others gets ZOrder placed above the others **SOLVED**
Post by: Knox on Fri 08/04/2011 01:36:49
Wow, well this is great, thank-you sir :)
Title: Re: Gui you click on amongst 2 others gets ZOrder placed above the others **SOLVED**
Post by: Knox on Sat 16/04/2011 17:29:42
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)**
Title: Re: Gui you click on amongst 2 others gets ZOrder placed above the others
Post by: monkey0506 on Sat 16/04/2011 20:56:58
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.