• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Bring objects to "front" on click

O

orSQUADstra

Guest
So what I want to do is to have an object, and there would be multiple of that placed in the room. They all have "w" for width, and "h" for height variables, and they draw a rectangle from x and y to x+w and y+h. They also contain some text.

What I was wondering is, how could I make a sequence (or whatever you call it)? Like how your OS has windows, this would be pretty much the same, if I click on one and the others don't cover them, it would be in front.

I've been trying to do this for hours now with absolutely no luck :(

Any help is appreciated!
 

jo-thijs

Member
So what I want to do is to have an object, and there would be multiple of that placed in the room. They all have "w" for width, and "h" for height variables, and they draw a rectangle from x and y to x+w and y+h. They also contain some text.

What I was wondering is, how could I make a sequence (or whatever you call it)? Like how your OS has windows, this would be pretty much the same, if I click on one and the others don't cover them, it would be in front.

I've been trying to do this for hours now with absolutely no luck :(

Any help is appreciated!
There are a couple of approaches to this.

I would suggest to make those objects invisible and use a controller object.
This controller object would keep track of a ds_list of all these objects, sorted on which is on top.
You could then make the controller object draw those objects by looping over the ds_list and using a combination of the with-structure and event_perform function.
In the global mouse left pressed event you could loop over the ds_list until you find an object that touches the mouse.
You'd then move that object in front of the list.

This system is one that will be very prone to change, so you'd better make a lot of scripts to get an abstraction.
You could use scripts such as scr_sos_init(obj) (script selectable object system initialization) which registers one of the square objects to the controller object,
scr_sos_contains(obj,x,y) which checks if the point (x,y) lies within the given square object,
scr_sos_promote(obj) which promotes the given object to be on top,
scr_sos_ontop(obj) which returns whether the given object is on top of the list,
scr_sos_isactive(obj), ...
 
O

orSQUADstra

Guest
There are a couple of approaches to this.

I would suggest to make those objects invisible and use a controller object.
This controller object would keep track of a ds_list of all these objects, sorted on which is on top.
You could then make the controller object draw those objects by looping over the ds_list and using a combination of the with-structure and event_perform function.
In the global mouse left pressed event you could loop over the ds_list until you find an object that touches the mouse.
You'd then move that object in front of the list.

This system is one that will be very prone to change, so you'd better make a lot of scripts to get an abstraction.
You could use scripts such as scr_sos_init(obj) (script selectable object system initialization) which registers one of the square objects to the controller object,
scr_sos_contains(obj,x,y) which checks if the point (x,y) lies within the given square object,
scr_sos_promote(obj) which promotes the given object to be on top,
scr_sos_ontop(obj) which returns whether the given object is on top of the list,
scr_sos_isactive(obj), ...
Well, I was trying to approach this problem with 2D arrays.

So far only been trying to do with simply if you click one of the boxes, it comes to top.

The current code looks like this:
I have first set up the global variable global.sequence[0,0] = 0 in a separate object

Then, whenever a new box is created, it is meant to be on top as it's created.

So it looks like this:
Create event:
Code:
ownsequence = 0

w = 128
h = 96

for (i=instance_number(objBox); i>0; i-=1)
{
    global.sequence[i,0]=global.sequence[i-1,0]
}

global.sequence[ownsequence,0] = id

if instance_number(objBox)>1
{
    for (i=1; i<instance_number(objBox); i+=1)
    {
        global.sequence[i,0].ownsequence += 1
    }
}
And Step event:
Code:
depth = -500 +ownsequence

if mouse_in_region(x,y-26,x+w,y+h)
and mouse_check_button_pressed(mb_left)
and !(ownsequence = 0)
{   
    ownsequence = 0

    if instance_number(objBox)>1
    {
        for (i=instance_number(objBox)-1; i>0; i-=1)
        {
            global.sequence[i,0]=global.sequence[i-1,0]
        }
    
        global.sequence[ownsequence,0] = id
    
    
        for (i=1; i<instance_number(objBox); i+=1)
        {
            global.sequence[i,0].ownsequence += 1
        }
    }
}
Note: mouse_in_region is a script that returns true if the mouse coordinates are inside the x1, y1, x2, y2 zone.

If there are only 2, it works perfectly.
If there are more than two, as far as I'm clicking them in the order they were created, they work perfectly. If I click them in an order that isn't how they were created, for some reason the one I click won't have the ownsequence as 0 but as the one that was clicked previously.

I've been trying to tweak that code, but no luck.
 

jo-thijs

Member
Well, I was trying to approach this problem with 2D arrays.

So far only been trying to do with simply if you click one of the boxes, it comes to top.

The current code looks like this:
I have first set up the global variable global.sequence[0,0] = 0 in a separate object

Then, whenever a new box is created, it is meant to be on top as it's created.

So it looks like this:
Create event:
Code:
ownsequence = 0

w = 128
h = 96

for (i=instance_number(objBox); i>0; i-=1)
{
    global.sequence[i,0]=global.sequence[i-1,0]
}

global.sequence[ownsequence,0] = id

if instance_number(objBox)>1
{
    for (i=1; i<instance_number(objBox); i+=1)
    {
        global.sequence[i,0].ownsequence += 1
    }
}
And Step event:
Code:
depth = -500 +ownsequence

if mouse_in_region(x,y-26,x+w,y+h)
and mouse_check_button_pressed(mb_left)
and !(ownsequence = 0)
{ 
    ownsequence = 0

    if instance_number(objBox)>1
    {
        for (i=instance_number(objBox)-1; i>0; i-=1)
        {
            global.sequence[i,0]=global.sequence[i-1,0]
        }
  
        global.sequence[ownsequence,0] = id
  
  
        for (i=1; i<instance_number(objBox); i+=1)
        {
            global.sequence[i,0].ownsequence += 1
        }
    }
}
Note: mouse_in_region is a script that returns true if the mouse coordinates are inside the x1, y1, x2, y2 zone.

If there are only 2, it works perfectly.
If there are more than two, as far as I'm clicking them in the order they were created, they work perfectly. If I click them in an order that isn't how they were created, for some reason the one I click won't have the ownsequence as 0 but as the one that was clicked previously.

I've been trying to tweak that code, but no luck.
This part doesn't seem right:
Code:
if instance_number(objBox)>1
{
    for (i=1; i<instance_number(objBox); i+=1)
    {
        global.sequence[i,0].ownsequence += 1
    }
}
Wouldn't it be easier to change the create event to:
Code:
ownsequence = -1;

w = 128;
h = 96;

with objBox
{
    global.sequence[++ownsequence,0] = id;
}
and change the step event to:
Code:
depth = ownsequence - 500;

if mouse_in_region(x, y - 26, x + w, y + h)
&& mouse_check_button_pressed(mb_left)
&& ownsequence != 0
{
    with objBox
    {
        if ownsequence < other.ownsequence
        {
            global.sequence[++ownsequence,0] = id;
        }
    }
    ownsequence = 0;
    global.sequence[ownsequence,0] = id;
}
EDIT: that would still cause trouble though, as multiple instances will try to get on top at once.
You should go with my controller object suggestion.
 
O

orSQUADstra

Guest
This part doesn't seem right:
Code:
if instance_number(objBox)>1
{
    for (i=1; i<instance_number(objBox); i+=1)
    {
        global.sequence[i,0].ownsequence += 1
    }
}
Wouldn't it be easier to change the create event to:
Code:
ownsequence = -1;

w = 128;
h = 96;

with objBox
{
    global.sequence[++ownsequence,0] = id;
}
and change the step event to:
Code:
depth = ownsequence - 500;

if mouse_in_region(x, y - 26, x + w, y + h)
&& mouse_check_button_pressed(mb_left)
&& ownsequence != 0
{
    with objBox
    {
        if ownsequence < other.ownsequence
        {
            global.sequence[++ownsequence,0] = id;
        }
    }
    ownsequence = 0;
    global.sequence[ownsequence,0] = id;
}
EDIT: that would still cause trouble though, as multiple instances will try to get on top at once.
You should go with my controller object suggestion.
Tried with those, but when I try to run it:
Error in code at line 67:
global.sequence[++ownsequence,0] = id;
^
at position 22: Negative array index
 
O

orSQUADstra

Guest
For all I now legacy could have refered to GM:S 1.4.

Then change this:
Code:
global.sequence[++ownsequence,0] = id;
to this:
Code:
ownsequence += 1;
global.sequence[ownsequence,0] = id;
Ah, alright, it works now.

Thank you! ^^
 
Top