• 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!

Checking if an object is fully inside another object

I have a room where its all covered with invisible blocks, along 64x64 grids.
If the player object presses a certain key, a block object on top of which it currently is should activate. However the player sometimes overlaps two of these at a time. I cant make the collision mask of the blocks much smaller either. How can i make the player character only activate a block object that it is fully inside of, not so that it activates all blocks the player object even partially collides with?
 
A

Annoyed Grunt

Guest
you can use
Code:
rectangle_in_rectangle(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
to determine if two rectangles are fully intersecting each other.
 
Use something like collision_point() to determine which block the player is above, then use rectangle_in_rectangle() function to work out if the player is fully inside that block.
 
how will i mark the player object's coordinates in rectangle_in_rectangle? Does it matter if the player object is not rectangular, should i use some other function?
The player objects sprite's size is 42 x 42, in case it matters. Should I mark that as the 'destination rectangle to check against' ?
Or does it go smth like:

rectangle_in_rectangle(sx1, sy1, sx2, sy2, playerobj.dx1, playerobj.dy1, playerobj.dx2, playerobj.dy2);

Never used this function before, so sorry for all the questions
 

Bentley

Member
I have a room where its all covered with invisible blocks, along 64x64 grids.
If the player object presses a certain key, a block object on top of which it currently is should activate. However the player sometimes overlaps two of these at a time. I cant make the collision mask of the blocks much smaller either. How can i make the player character only activate a block object that it is fully inside of, not so that it activates all blocks the player object even partially collides with?
To check if the player is completely inside a block:
Code:
var block, x1, y1, x2, y2, x3, y3, x4, y4;

block = instance_place(x, y, o_block);
if (instance_exists(block))
{
    x1 = bbox_left;
    y1 = bbox_top;
    x2 = bbox_right;
    y2 = bbox_bottom;
    x3 = block.bbox_left;
    y3 = block.bbox_top;
    x4 = block.bbox_right;
    y4 = block.bbox_bottom;
    if (rectangle_in_rectangle(x1, y1, x2, y2, x3, y3, x4, y4) == 1) // Only true if you're completely inside a block
    {
        // Do something
    }
}
Edit: ignore what I wrote below if you just want to check if the player is entirely inside. Also, @IndianaBones post about using collision_point is a better approach than mine.

Assuming you want something to happen when you're overlapping, change the check to be > 0.
The problem will be when you are overlapping two rectangles. The instance_place could return the ID of the lesser of the two rectangles you're overlapping.

Off the top of my head, a collision list and then store the nearest rectangle. Surely there's a better way but that's probably how I would do it.
 
Last edited:
Off the top of my head, a collision list and then store the nearest rectangle. But there's probably a more efficient that someone smart than me can tell you about.
That's a good solution, should work in all cases.

I suggest, if the sprite x and y offset for your player is centered, replacing instance_place() with collision_point() and using the players x and y position should do the trick.

If the player's x and y are outside of a block, then the rest of the player sprite is definitely not going to be within the block entirely.

You can always test it to confirm what method works best.
 
To check if the player is completely inside a block:
Code:
var block, x1, y1, x2, y2, x3, y3, x4, y4;

block = instance_place(x, y, o_block);
if (instance_exists(block))
{
    x1 = bbox_left;
    y1 = bbox_top;
    x2 = bbox_right;
    y2 = bbox_bottom;
    x3 = block.bbox_left;
    y3 = block.bbox_top;
    x4 = block.bbox_right;
    y4 = block.bbox_bottom;
    if (rectangle_in_rectangle(x1, y1, x2, y2, x3, y3, x4, y4) == 1) // Only true if you're completely inside a block
    {
        // Do something
    }
}
The problem will be when:
1. You are overlapping one rectangle
2. You are overlapping two rectangles
Assuming you want something to happen when you're overlapping, change the check to be > 0.

The problem about colliding with 2 rectangles remains. The instance_place could return the ID of the lesser of the two rectangles you're overlapping.

Off the top of my head, a collision list and then store the nearest rectangle. Surely there's a better way but that's probably how I would do it.
this actually works! no overlapping issues anymore, the player object can only activate a block now when completely inside one, and nothing happens when player overlaps more than 1 blocks.
Thanks to all of you guys who posted here!
especially @Bentley !
 
Top