Cycle through active GUI objects with mousewheel (SOLVED)

Started by alkis21, Thu 14/06/2007 19:19:39

Previous topic - Next topic

alkis21

Here's the problem: My game features a "Thoughts" GUI, which is basically a Panel of buttons displayed as post-its. When the player uses the GUI, he can select a "Thought" with the Use icon, which causes a special post-it inventory item to turn the same color and a global variable named "thought" to change value.

As turning the GUI on and off repeatedly can become tedious after a while, I thought of using the mouse wheel to cycle through "thoughts" when the player's active inventory item is the post-it. This was simple to enough to achieve with the following script inside on_mouse_click:

Code: ags
  else if (button==eMouseWheelSouth) {
     if ((player.activeinv==1) && (mouse.Mode==4)) {    
        if (th==1) {
           if (Thou1.Visible==true) {
              thought="yourself";
              SetInvItemPic(1,145);
              }
           }
        else if (th==2) {
           if (Thou2.Visible==true) {
              thought="DITR";
              SetInvItemPic(1, 270);
              }
           }
        else if (th==3) {
           if (Thou3.Visible==true) {
              thought="Mr. Hungerton";
              SetInvItemPic(1, 145);
              }
           }   
           .
           .
           .
           .}


As you can see, GUI buttons Thou1, Thou2 etc. are not always visible, and I need to check whether each one of them is every time. The obvious problem is that if, for instance, Thou1 and Thou4 are visible and Thou2 and Thou3 aren't, there is a delay of two mouse wheel clicks before Thou4 is selected.

I've tried several workarounds, such as checking whether the next button is visible, and then the next, and then the next, until I got something like that:

Code: ags
        else if (th==5) {
           if (Thou6.Visible==true) {
              thought="Sydelle";
              SetInvItemPic(1, 145);
              }
           else if ((Thou6.Visible==false) && (Thou7.Visible==true)) {
              thought="Nadine";
              SetInvItemPic(1, 145);
              }
           else if ((Thou6.Visible==false) && (Thou7.Visible==false) && (Thou8.Visible==true)) { 
              thought="Henry";
              SetInvItemPic(1, 145);
              }
           else if ((Thou6.Visible==false) && (Thou7.Visible==false) && (Thou8.Visible==false) && (Thou10.Visible==true)) {  
              thought="Curtis' favor";
              SetInvItemPic(1, 312);
              }
           else th=0;
           }


but soon enough the different scenarios become too many and the code too messy.

Can anyone think of a more simple solution to avoid dead clicks?

Khris

#1
Code: ags
function GetNextVisible(int current, int dir) {
  current +=dir;
  if (current==Thoughts.ControlCount) current=0;
  if (current==-1) current=Thoughts.ControlCount-1;

  if (gThoughts.Controls[current].Visible) return current;
  return GetNextVisible(current, dir);
}

// th: 0 to x
// ths[0]="yourself"; ths[1]="DITR"; ths[2]="Mr Hungerton"; ...
// thp[0]=145; thp[1]=270; thp[2]=145; ...

// Mousewheel south
th=GetNextVisible(th, 1);

// Mousewheel north
th=GetNextVisible(th, -1);

// then
thought=ths[th];
inventory[1].Graphic=thp[th];


This uses a recursive function to find the next visible button.
thought and Inventory Graphic are set using arrays.

alkis21

It took me a while to figure it out and get it right but it worked flawlessly! Thank you so much, Khris.

Khris

Glad it works :)
Note that there has to be at least one button visible at all times, otherwise AGS will get stuck in the recursive loop and probably crash.

SMF spam blocked by CleanTalk