• Hey! Guest! The 40th (!!!) GMC Jam will take place between February 25th, 12:00 UTC to March 1st 12:00 UTC. Why not join in this very special anniversary jam! Click here to find out more!

Help: Stacking different size objects on top of each other with priority inside the stack

MercyGRID

Member
Hello all! First post, but I've been toying around for a bit and getting used to the ropes of GML. I'm still pretty new, but I learn quick!

I'm trying to accomplish stacking multiple objects on top of one another in the game window, while at the same time giving priority to some objects to be further in the stack.

There are 3 types of objects: Let's call them A, B, and C. The priority should be all of A stack at the bottom, followed by B, followed by C. The problem is B is 2 times larger than A or C.

If all the objects were the same size, it would be simple: Move the object down until it hits the same priority object type, the one higher in priority, or the "floor". Then any other object you collide with moves up at the same time. But in this case, if Object A is moving down the stack toward its priority and collides with Object B (which is 2x bigger) Object B will be moving twice as much as it needs to, and I then end up with overlapping Objects that don't function the way I'm looking for.

I'm probably describing this terribly, but...

Current -- Target
A ---------- C
B ---------- C
C ---------- B
A ---------- A
C ---------- A

Keeping in mind B is 2x the size.

How can I get this kind of movement and collision problem working? Should I be looking to use a 3D Array and store data inside it to determine movement locations, or is there a simpler way?
 

SoapSud39

Member
If you have some information for your objects (or instances thereof), you can make a ds_list or ds_grid to store it (maybe ds_grid for this case), then use ds_list_sort() or ds_grid_sort() to order the items in the list (descending or ascending). I don't know how you're using the instances, but you can loop through the data structure and then set things like position or draw position to get the desired effect.

Just remember that for every data structure you create (e.g. ds_list_create()) you need to destroy it at some point, such as in the clean-up event, or it might lead to a memory leak.

sample:
GML:
//obj_object create event
position = irandom(10);

//controller object create event
object_grid = ds_grid_create(2, 10);
for (var i = 0; i < 10; i++) {
    var inst = instance_create_layer(x, y, "layer", obj_object);
    object_grid[# 0, i] = inst;                //put instance id into first column
    object_grid[# 1, i] = inst.position;    //put position variable into second column
    //ds_grid_sort wants a column, so I think this should be right (maybe??)
}
ds_grid_sort(object_grid, 1, true); //sort grid in order of instance position
    //later on you can return the instance id based on position variable, then set that instance's other variables, etc., etc.
   
//don't forget to use ds_grid_destroy in clean-up
 

TheouAegis

Member
Can you use the bbox variables? I like the idea of an array or ds_list holding the order of everything, especially if you want the order to change gradually. You could handle all the ordering inside the array or list, and then loop through the array or list fetching each id, starting with the one on the bottom. Place it at the coordinates in the room at the bottom, then fetch its bbox_top value. Get the id of the next instance and set its y to that saved bbox_top value. Then update the saved bbox_top value to be that of the most recent instance. Repeat until you've gone through the entire array or list.

Code:
for(var n=0,lim=ds_list_size(STACK), i=0; i<lim; i++;) {
    if STACK[|i].size < STACK[|i+1].size {
        n = STACK[|i];
        STACK[|i] = STACK[|i+1];
        STACK[|i+1] = n;
        i++;
    }
}
var top = 0;
for(i=lim-1; i>-1; i--;) {
    if !top {
        STACK[|i].y = yFloor;
        top = STACK[|i].bbox_top;
    }
    else {
        STACK[|i].y = top;
        top = STACK[|i].bbox_top;
    }
}
 
Last edited:

MercyGRID

Member
I hadn't thought about the bounding box sides... that might work. I'll have to give that a go tonight.

As for using ds_list, I don't think that's going to work for me easily the way I have the code right now, but if this first one doesn't work I'll definitely give it a go! I'll update once I know how it goes.

Edit: After a bit of thought, the array is definitely how it's going to have to work. I'm in the process now of seeing if I can wrap my noodle-brain around it. :)
 
Last edited:

MercyGRID

Member
So using an array allowed me to get things seemingly working, but trying to move pieces to their new locations in the stack order was...troublesome. After scrubbing the movement code and starting again with an array, I was able to remove the bug that did it and I'm all good on this problem! Now onto the next step in my 1st project that I intend to finish and share with the world! <3

Thanks everyone for the aid!
 
Top