Detect hover over topmost instance

padth4i

Member
I have an object where if the player hovers their cursor over some text on the object, a border appears around the text. This is the code I have for the same:
GML:
if (point_in_rectangle(mouse_x, mouse_y, x + 18, y + 50, x + 278, y + 60 + string_height_ext(options[0][0], sepVal, wrapLength) + 10)) {
    draw_rectangle(x + 18, y + 50, x + 278, y + 60 + string_height_ext(options[0][0], sepVal, wrapLength) + 10, true);
}
Multiple instances of the object could be present in the room, all of which can be clicked and dragged. If one of the instances is dragged over the other, and the player hovers over the text, then the borders of all instances under that point get shown like in the below image where I hover over "Option 2b":

1.JPG

Ideally, I only want the border over the topmost instance if multiple are present at the same point. What can I do about this forum? Thanks in advance!
 

samspade

Member
How are you determining which object is on top for draw order? You can probably use whatever you're doing there as a check for drawing the rectangle. While not as important, I would also move the check to the step event.

GML:
///step event

if (point_in_rectangle(mouse_x, mouse_y, x + 18, y + 50, x + 278, y + 60 + string_height_ext(options[0][0], sepVal, wrapLength) + 10)) &&
   (//however you checking draw order)
{
   selected = true;
}

///draw event
if (selected) {
    draw_rectangle(x + 18, y + 50, x + 278, y + 60 + string_height_ext(options[0][0], sepVal, wrapLength) + 10, true);
}
 

padth4i

Member
I use instance_create_depth(spawnX, spawnY, spawnHeight, objPaper) to spawn the instances. The value of spawnHeight is decreased by 1 with each instance creation.

Thanks for the heads up with the Step event
 

samspade

Member
I use instance_create_depth(spawnX, spawnY, spawnHeight, objPaper) to spawn the instances. The value of spawnHeight is decreased by 1 with each instance creation.

Thanks for the heads up with the Step event
You should just be able to check depth. For example something like this might work (I haven't used depth since GMS 1.4 so I might be wrong with my use here, but the basic idea should work:


GML:
topmost = true;                        //assume it is topmost
with (objPaper) {                    //loop through all objects
    if (id == other.id) continue;     //skip self
    if (depth < other.depth) {        //compare depth
        other.topmost = false;        //if not topmost, set this
        break;                        //end loop, you only need to find one instance of falseness
    }
}
 

padth4i

Member
Thanks for the help. Your fix works partway, as in now only the topmost instance can be interacted with:

2.JPG

Which fixes the overlap issue, but brings another problem. Now you can interact with only the topmost instance unless you click another one, changing its depth. I would like for the options on other instances to be hoverable as well, but only one at a time, without any overlaps. Any suggestions?
 

samspade

Member
You can probably do it by adding more checks. For example, you could only do the topmost check if there is a collision/point in rectangle with more than one paper object.
 

TheouAegis

Member
What is your current code? Did you incorporate your first code into that with Loop? Cuz you don't want just the topmost selection, you want the top most selection that matches the criteria of having it's bounding box Encompass the mouse.
 

padth4i

Member
What is your current code? Did you incorporate your first code into that with Loop? Cuz you don't want just the topmost selection, you want the top most selection that matches the criteria of having it's bounding box Encompass the mouse.
I've added a second check to @samspade's code to see if the mouse is within the bbox.

GML:
topmost = true;                        //assume it is topmost
with (objTranscript) {                    //loop through all objects
    if (id == other.id) continue;     //skip self
    if (depth < other.depth && position_meeting(mouse_x, mouse_y, id)) {        //compare depth
        other.topmost = false;        //if not topmost, set this
        break;                        //end loop, you only need to find one instance of falseness
    }
}
Works perfectly now. Thanks for the help!
 
Top