(Solved) Clicking on overlapped buttons

Started by Privateer Puddin', Sun 11/10/2020 10:14:04

Previous topic - Next topic

Privateer Puddin'

 Hi,

I have a GUI of 9 buttons that may overlap. Their size is based on sprites representing a list box item/ saved game name:



but of course, in terms of buttons, that'd look like something like this:



I have this code from Feria for checking on an individual button (provided it's on top in zorder) whether you're clicking text or a transparent part

Code: ags
bool MouseOverPixelPerfect(this Button*)
{
  // Calculate mouse coordinates relative to button sprite canvas 
  int x = mouse.x - this.X - this.OwningGUI.X;
  int y = mouse.y - this.Y - this.OwningGUI.Y;
  // Get the color on button sprite canvas at mouse cursor pixel
  DynamicSprite* buttonMask = DynamicSprite.CreateFromExistingSprite(this.NormalGraphic, false);
  DrawingSurface* maskSurface = buttonMask.GetDrawingSurface();
  int pixelColor = maskSurface.GetPixel(x,y);
  maskSurface.Release();
  buttonMask.Delete();
 
  if (pixelColor == COLOR_TRANSPARENT) // if this doesn't work then try your harcoded number, 63519
  {
      
      Display("Transparent");
      return false;
  }
    Display("Not transparent");
    return true;
}


but then I'm not sure how to go about checking when it's transparent to go to the next button and do a check there. I tried bringing the next button ID to front and repeating that check, but wasn't working.

Code: ags
if(pixelColor == COLOR_TRANSPARENT) // if this doesn't work then try your harcoded number, 63519
  {
      
      Display("Transparent on the first layer..");
      gGui1.Controls[this.ID+1].AsButton.BringToFront();   // bring the next Button to the front...
      DynamicSprite* buttonMask2 = DynamicSprite.CreateFromExistingSprite(gGui1.Controls[this.ID+1].AsButton.NormalGraphic, false);
      Display("%d",gGui1.Controls[this.ID+1].AsButton.NormalGraphic);
      DrawingSurface* maskSurface2 = buttonMask2.GetDrawingSurface();
      int pixelColor2 = maskSurface2.GetPixel(x,y);
      maskSurface2.Release();
      buttonMask2.Delete();
      Display("%d",pixelColor2);
        if(pixelColor2 == COLOR_TRANSPARENT) // if this doesn't work then try your harcoded number, 63519
        {
            Display("I am transparent on the second layer");
            

        } else {
      
            //Text found, do whatever
          
        }
   
  }


Thanks!

Snarky

#1
The easiest thing is probably to draw separate hotspots for each line on the background, and use GetHotspotAt() to determine which button was pressed.

Or you could do it all as one big button, and then use a bit of math to calculate which line the player clicked on. (The task is to determine the coordinate vector of the position they clicked with respect to the basis defined by the horizontal and vertical lines of the paper.)

It looks like the basis is that the "vertical" vector is a 45-degree diagonal: (1,1) and the "horizontal" vector is (3, -1). Back-of-an-envelope calculation gives me that if your mouse position is (x,y) relative to the "top left" corner of the first entry, the coordinate in terms of the "vertical" vector is (x+3*y)/4, and in terms of the "horizontal" vector (x-y)/4. So if the height of each line is 10 (just eyeballing), (mouse.x-x_0 + 3(*mouse.y-y_0))/40 â€" where (x_0,y_0) are the "top left" corner of the first entry â€" should give you the current line, while you can use the "horizontal" vector value to determine whether you're within the bounds.

Privateer Puddin'

Ah, I hadn't seen your edit! That gives me something to shoot for - Thanks

Privateer Puddin'

Thanks Snarky! I need to fine tune my stuff a bit, but it's working well


Snarky


Matti

Very cool indeed  ;-D

I really like that screen btw.

SMF spam blocked by CleanTalk