Cursor under objects?

Started by Ezekiel000, Thu 16/08/2012 13:08:06

Previous topic - Next topic

Ezekiel000

Is it possible for the mouse cursor to go under an object?
I have labels that are visible when the mouse hovers over an exit but at the moment if the cursor goes over the label object when it is visible then the label disappears.
I would like to have the cursor go underneath the label.

Khris

First of all, you're using room objects to display these labels? That's a bad route. A GUI is much better suited to do this.
Objects are meant to represent stuff in a room that's apart from the background but still part of the game world. They should never be used as part of the UI.
(One simple reason is that you have to recreate the object in every new room while you'll only need one GUI total.)

To answer your question: the mouse cursor is always on top of everything else, no exception.
To solve this problem, provided you're using a GUI for the labels, use another GUI with a lower zOrder to represent the mouse position/cursor.

We can help you with coding that, but first you should ditch using objects for UI labels.
Are you using one object per room that contains all the labels and turn it on/off?

Ezekiel000

No each label is a different object as they are in different positions in relation to the exit hotspot/object and different text depending on where the exit goes too.
If I used a gui for the label and a gui for the cursor, how would that affect the normal mouse functions? (changing mode, graphic etc)

Khris

The mouse GUI would have to mimic the mouse cursor behavior exactly. Only the appearance requires code though because if you set the GUI to not clickable, all clicking will work as usual.
Here's code that'll take care of most of that:
Code: ags
// inside GlobalScript.asc

DynamicSprite*mouse_cursor;

function repeatedly_execute_always() {
  int slot = mouse.GetModeGraphic(mouse.Mode);
  if (!mouse_cursor) mouse_cursor = DynamicSprite.Create(100, 100);  // this should accommodate all sprite sizes
  DrawingSurface*ds = mouse_cursor.GetDrawingSurface();
  ds.Clear();
  ds.DrawImage(0, 0, slot);
  ds.Release();
  gMouse.BackgroundGraphic = mouse_cursor.Graphic;
  gMouse.SetPosition(mouse.x - 5, mouse.y - 5);
}

In addition you have to call mouse.Visible = false; in game_start() to hide the actual mouse.

The only bad thing about this workaround is that there's no way I know of of reading the hotspot coordinates of a mouse mode. So instead of using 5, 5 in the last line, one has to set up an array and store all the HotspotX/Y data of the cursors in there so that the GUI is positioned correctly. It's even worse if one uses all kinds of different hotspots for the inventory items.

Ezekiel000

Thank you for that, I'll try to implement it later.
I'm using 2.72 is there anything in this code that wouldn't work in that.

Snarky

The quickest fix, as Khris points out (but maybe you missed it) is to just set the label object/GUI to not clickable. The mouse cursor will still be on top of the label, but you'll be able to click on whatever is behind it. Maybe that's good enough for what you need.

Khris

I think the main concern is the mouse cursor obscuring the label.
Btw, there's also another way of doing this: one can reposition the label depending on the mouse's position so it's always next to it.

I can't help you with moving this code to 2.72 right now, and I'd really recommend switching to 3.2.1 anyway.

Ezekiel000

#7
Really it is two problems one the cursor on top of the label and the label disappearing when under the cursor.
I hadn't even considered using a gui for the labels up to now but I'll go through the help file to find the functions I need.
First I'll try to get the labels to always appear when they should with a gui then I'll worry about trying to fake the cursor under the label.

I would move to 3.2.1 but it doesn't work in linux (under wine) none of the 3 series do.

Edit:
I tried to replace my label objects with a gui but when the gui is visible clicking on the exit has no effect, it doesn't change room.
If I set up everything except making the gui visible the exits work.

Code: AGS
function exit_label(int text_sprite, int object_exit, int x_pos, int y_pos)
{
  if (gLabel.Visible == false)
  {
    if (Object.GetAtScreenXY(mouse.x, mouse.y) == object[object_exit])
    {
      gLabel.Clickable = false;
      gLabel.Height = Game.SpriteHeight[text_sprite];
      gLabel.Width = Game.SpriteWidth[text_sprite];
      gLabel.BackgroundGraphic = text_sprite;
      gLabel.SetPosition(x_pos, y_pos-12);
      gLabel.Visible = true;
      Object *o = Object.GetAtScreenXY(mouse.x, mouse.y);
      if (mouse.Mode != eModeWalk && o.GetProperty("WALK_A") == 1)
      {
        old_mouse_mode = mouse.Mode;
        mouse.Mode = eModeWalk;
      }
    }
  }
  if (gLabel.Visible == true && gLabel.BackgroundGraphic == text_sprite)
  {
    if (Object.GetAtScreenXY(mouse.x, mouse.y) != object[object_exit])
    {
      gLabel.Visible = false;
      if (mouse.Mode == eModeWalk) mouse.Mode = old_mouse_mode;
    }
  }
}


And this in the room script:
Code: AGS
function room_d()
{
  // script for Room: Repeatedly execute
  exit_label(99, 1, 256, 123);
}


Edit: The problem I had was that the label gui was set to popup modal, I switched it to normal and it works fine.

SMF spam blocked by CleanTalk